【單片機入門】(三)應用層軟體開發的單片機學習之路-uart串口通訊和c#交互

【單片機入門】(三)應用層軟體開發的單片機學習之路-uart串口通訊和c#交互

uart串口通訊和c#串口進行通訊的一個案例,以及什麼是中斷,中斷的作用和實踐

最后更新 2022/10/25 下午9:58
陈显达
预计阅读 8 分钟
分类
分享
标签
.NET C# 硬體相關

本文由網友投稿。

作者:陳顯達

原文標題:【單片機入門】(三)應用層軟體開發的單片機學習之路-----uart 串口通訊和 c#交互

原文連結:https://www.cnblogs.com/1996-Chinese-Chen/p/16826558.html

引言

在第一章博客中,我們講了 arduino 對 esp32 的一個環境配置,以及了解到了常用的一個總線通訊協議,其中有 spi,iic,uart 等,今天我為大家帶來 uart 串口通訊和 c#串口進行通訊的一個案例,以及什麼是中斷,中斷的作用和實踐,話不多說,讓我們正式開始。

UART

在第一篇博客中,我們講了 uart 是需要一個接收一個發送的引腳,總共兩個,分別是 txd(發送引腳),rxd(接收引腳),不管是什麼類型的單片機串口引腳都是這兩個,可能有的是少了最後面的那個 d,但是都是一樣的東西,在 esp32 的開發板上,是有三對 uart 的引腳的,也就是說板子上有三個串口可以供我們使用,如下圖,serial0 對應的引腳為 1 和 3,serial1 對應的引腳為 9 和 10,serial2 對應的引腳為 16 和 17,但是在我們燒錄的時候,1 和 3 是不能使用的,因為我們通過 usb 將單片機連接到電腦上,使用的串口引腳就是 1 和 3,所以我們可使用串口只有兩個,而 arduino ide 上面,對應的 serial 也有四個靜態類,分別是 serial,serial1 和 serial2 以及 serial3。雖然他的數量和我們 esp32 的串口數量是一樣,但是只有第一個可以使用,後面兩個我們是無法使用的,因為後面兩個對應的引腳和我們 esp32 的引腳是不相同的,我們可以從下面第二個圖看到,serial1,serial2 的 pins 是和我們 esp32 的引腳是對不上的,所以我們在串口開發的時候是不使用這兩個,對於第一個 serial 我們是可以使用的。

我們如果需要使用 esp32 的串口開發,在 esp 的開發包里,官方給我們提供了一個 hardwareserial 的一個串口庫,裡面我們可以使用開發板上面的串口,同時將引腳指定為我們引腳圖上面的引腳。這個庫的位置為我們 arduino ide 目錄下的 hardware/espressif/esp32/cores/esp32 可以找到這個庫,這個文件夾下包含了一些 esp32 的官方庫;使用這個 hardwareserial.h 文件我們可以實現使用 esp32 開發板上面的串口進行開發,接下來我們在代碼中去了解他如何使用。

編碼

在下面的代碼中,我們開始了一個簡單的一個串口通訊,在代碼第一行,是和 c 語言一樣引入我們需要的庫文件,然後在第二行,定義了 hardwareserial 這個類的一個 myserial1 對象,裡面的構造函數的值是 1 代表著,我們將使用第一個串口,在下面的 setup 裡面,我們開始啟動了 myserial1 這個串口對象,啟動的波特率是 9600,數據長度是 8,校驗位是 none,停止位是 1,以及串口的 rx 的引腳是 16,tx 的引腳為 17。在下一行代碼,我們傳入了一個我們下方定義的 receiveevent 的一個方法,這個方法用來接收串口接收數據的一個回調,將我們這個方法指針傳入進去,在串口接收到數據之後,會進入到我們這個方法中。

最後一行代碼,我們是啟用了第 0 個串口,波特率是 9600。

可能上面的代碼有朋友就有疑惑了,明明 16 和 17 在引腳圖中定義的串口是 2,為什麼這裡定義的是 1 呢,實際上這個我們可以自己修改這個串口的定義和引腳,這個構造函數傳入的參數取值範圍為 0,1,2,對應的是我們開發板上的三個 uart 串口,在 begin 哪裡傳入的引腳和這個 0,1,2 是沒有任何關係的,但是這個傳入的引腳必須是開發板上三個 uart 串口之一,所以我們也可以定義為 myserial2.begin(9600,serial_8n1,10,9);這裡的 0,1,2 僅對應有三對串口,不指定對應的引腳,在 begin 方法我們指定對應的串口的引腳。

在下面的接收到串口消息的回調中,我們第一行代碼調用了 available 這個方法,這個方法返回的是一個 int 參數,當然了我們這塊也可以寫 available()>0,也是可以的,這個方法是從串口緩存中讀取我們接收到的數據長度,這個條件成立,說明我們是有接收到數據,然後在裡面我們開始去讀取數據。

在所有的 serial 都是及程式 arduino 的一個 stream 的一個基礎類,這個類提供了一些我們對數據處理的一個方法,所以在下面的代碼中,我們將讀取的數據轉為字符串,然後將代碼延遲暫停了一秒,隨後,我們使用我們的串口對象,將接收到的數據寫入緩衝區,緩衝區會把我們寫入的數據,在發送出去,即將 println 裡面傳入的參數發送到我們的串口發送方,誰發的數據,誰就會收到"i am receive!! "+str。

#include <HardwareSerial.h>
HardwareSerial MySerial1(1);
void setup() {
  // put your setup code here, to run once:
  MySerial1.begin(9600,SERIAL_8N1,16,17);
  MySerial1.onReceive(receiveEvent);
  Serial.begin(9600);
}

void loop() {

}
void receiveEvent()
{
  if(MySerial1.available())
  {
     String str= MySerial1.readString();
     delay(1000);
     MySerial1.println("i am receive!!"+str);
  }
  delay(1000);
}            

stream 包括了以下方法,其中繼承 stream 的分別為串口,iic 通訊的 wire,sd 卡的一個類,以及用於網絡連接的 ethernet 類,都可以使用這些方法用來對數據進行操作。

c#編碼

c#方面的代碼則簡單很多,界面一個開啟串口的按鈕,一個發送數據的按鈕和文本框,以及用來接收數據顯示的文本框。

在代碼中我們開啟了串口,指定了打開的是哪一個串口,一些屬性是需要和 esp32 那邊設置一樣的,在上面我們設置波特率為 9600,數據為是 8,停止位是 1,校驗位是 none,所以在 c#這邊我們也需要這樣設置,不過校驗位默認是 none 的,所以此處我們沒有設置,然後開啟串口,註冊了一個接收到數據的一個回調,然後定義一個 1024 的字節數組,從串口讀取數據,返回讀取的數據長度,然後在對剛才定義的 1024 字節數組進行截取,然後通過 utf-8 的格式轉為字符串,然後顯示到界面上的富文本框中,在發送按鈕事件中,我們從輸入框讀取數據轉為字節數組,然後將數據寫入到串口中去即可。

public partial class Form1 : Form
    {
        private SerialPort serialPort = new SerialPort("COM6");
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            serialPort.BaudRate = 9600;
            serialPort.StopBits = StopBits.One;
            serialPort.DataBits = 8;
            serialPort.Open();
            serialPort.DataReceived += (a, b) => {
                var serial = a as SerialPort;
                var data = new byte[1024];
                var res=serial.Read(data,0, data.Length);
                data = data[..res];
                string st = Encoding.UTF8
                .GetString(data);
                BeginInvoke(() => { richTextBox1.Text += st; });
            };
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var str = Encoding.UTF8.GetBytes(textBox1.Text);
            serialPort.Write(str, 0, str.Length);
        }
    }       

接線圖

在此處的實例,我們需要準備一個 usb 轉 ttl 的模塊,四根母對母的杜邦線,在程式燒錄之後,我們需要將使用杜邦線讓 usb 轉 ttl 模塊和單片機進行連接,vcc 或者 5v 接單片機的 5v 引腳,usb 轉 ttl 的 gnd 和單片機的 gnd 相接,然後 usb 轉 ttl 的 rxd 引腳和單片機 17 引腳相接,txd 引腳和單片機的 16 引腳相接,如下圖所示接線,5v 不可和 gnd 接反,否則可能會燒壞模塊,確認接線無誤後,將 usb 轉 ttl 模塊插入電腦中,然後代碼中運行 c#程式,電機開啟串口,隨後發送數據,可以接收到單片機的反饋。

結語

串口通訊是物聯網中,必不可少的一種通訊方式,通常情況下都是 rx 接 tx,tx 接 rx,除非是模塊廠商的規定,否則都是這樣接線,在後面的課程中,我會依次對 iic,以及 pwm,還有 spi,以及中斷單獨做一個講解,歡迎大家關注,學習和探討,我會將我所知道的都會分享,同時,後面也會有 stm32 系列的教程。如果有感興趣的朋友,可以加 qq 群一起來討論 822084696。

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2025/8/13

推薦一款高性能狀態機管理解決方案

在實際軟體開發中,尤其是工業軟體,每一款設備都有複雜的狀態以及狀態之間的切換的功能需求,在這種情況下,如何管理狀態以及狀態之間切換,和對應狀態下的功能控制,成為非常重要的一個問題。

继续阅读
同分类 / 同标签 2025/3/18

(7)從護士到c#開發者--面向對象編程基礎

作為一名從護理行業轉行的程式設計師,我將分享如何通過醫護工作經驗來理解面向對象編程的概念。本文將居間類、對象、屬性、方法等面向對象的核心概念,並結合醫療保健領域的實例來加深理解。

继续阅读