你真的懂串口通信嗎?

一、什麼是串口通訊?

串行通訊是指僅用一根接收線和一根發送線就能將數據以位進行傳輸的一種通訊方式。儘管串行通訊的比按字節傳輸的並行通信慢,但是串口可以在僅僅使用兩根線的情況下就能實現數據的傳輸。

典型的串口通信使用 3 根線完成,分別是地線、發送、接收。由於串口通信是異步的,所以端口能夠在一根線上發送數據同時在另一根線上接收數據。串口通信最重要的參數是波特率、數據位、停止位和奇偶的校驗。對於兩個需要進行串口通信的端口,這些參數必須匹配,這也是能夠實現串口通訊的前提。

圖 1:串行通訊示數據傳輸意圖

二、串口通訊的通訊協議?

最初數據是模擬信號輸出簡單過程量,後來儀表接口出現了 RS232 接口,這種接口可以實現點對點的通信方式,但這種方式不能實現聯網功能,這就促生了 RS485。

我們知道串口通信的數據傳輸都是 0 和 1,在單總線、I2C、UART 中都是通過一根線的高低電平來判斷邏輯 1 或者邏輯 0,但這種信號線的 GND 再與其他設備形成共地模式的通信,這種共地模式傳輸容易產生干擾,並且抗干擾性能也比較弱。所以差分通信、支持多機通信、抗干擾強的 RS485 就被廣泛的使用了。

RS485 通信最大特點就是傳輸速度可以達到 10Mb/s 以上,傳輸距離可以達到 3000 米左右。大家需要注意的是雖然 485 最大速度和最大傳輸距離都很大,但是傳輸的速度是會隨距離的增加而變慢的,所以兩者是不可以兼得的。

三、串口通訊的物理層

串口通訊的物理層有很多標準,例如上面提到的,我們主要講解 RS-232 標準,RS-232 標準主要規定了信號的用途、通訊接口以及信號的電平標準。

在上面的通訊方式中,兩個通訊設備的 "DB9 接口" 之間通過串口信號線建立起連接,串口信號線中使用 "RS-232 標準" 傳輸數據信號。由於 RS-232 電平標準的信號不能直接被控制器直接識別,所以這些信號會經過一個 "電平轉換芯片" 轉換成控制器能識別的 "TTL 校準" 的電平信號,才能實現通訊。

下圖爲 DB9 標準串口通訊接口:

DB9 引腳說明:

上表中的是計算機端的 DB9 公頭標準接法,由於兩個通訊設備之間的收發信號 (RXD 與 TXD) 應交叉相連,所以調製調解器端的 DB9 母頭的收發信號接法一般與公頭的相反,兩個設備之間連接時,只要使用 "直通型" 的串口線連接起來即可。

串口線中的 RTS、CTS、DSR、DTR 及 DCD 信號,使用邏輯 1 表示信號有效,邏輯 0 表示信號無效。例如,當計算機端控制 DTR 信號線表示爲邏輯 1 時,它是爲了告知遠端的調製調解器,本機已準備好接收數據,0 則表示還沒準備就緒。

四、波特率

波特率是指數據信號對載波的調製速率,它用單位時間內載波調製狀態改變的次數來表示;

比如波特率爲 9600bps;代表的就是每秒中傳輸 9600bit,也就是相當於每一秒中劃分成了 9600 等份。

因此,那麼每 1bit 的時間就是 1/9600 秒 = 104.1666...us。約 0.1ms。既然是 9600 等份,即每 1bit 緊接着下一個比特,不存在額外的間隔。兩臺設備要想實現串口通訊,這收發端設置的波特率必須相同,否則是沒辦法實現通訊的。

收發波特率一致可以實現通訊:

收發波特率不一致,導致 RX 端不能正常接收:

五、串口通訊的數據結構

起始位: 起始位必須是持續一個比特時間的邏輯 0 電平,標誌傳輸一個字符的開始,接收方可用起始位使自己的接收時鐘與發送方的數據同步。

數據位: 數據位緊跟在起始位之後,是通信中的真正有效信息。數據位的位數可以由通信雙方共同約定。傳輸數據時先傳送字符的低位,後傳送字符的高位。

奇偶校驗位: 奇偶校驗位僅佔一位,用於進行奇校驗或偶校驗,奇偶檢驗位不是必須有的。如果是奇校驗,需要保證傳輸的數據總共有奇數個邏輯高位;如果是偶校驗,需要保證傳輸的數據總共有偶數個邏輯高位。

停止位: 停止位可以是是 1 位、1.5 位或 2 位,可以由軟件設定。它一定是邏輯 1 電平,標誌着傳輸一個字符的結束。

空閒位: 空閒位是指從一個字符的停止位結束到下一個字符的起始位開始,表示線路處於空閒狀態,必須由高電平來填充。

六、單雙工通訊

單工: 數據傳輸只支持數據在一個方向上傳輸;

半雙工: 允許數據在兩個方向上傳輸,但某一時刻只允許數據在一個方向上傳輸,實際上是一種切換方向的單工通信,不需要獨立的接收端和發送端,兩者可合併爲一個端口;

全雙工: 允許數據同時在兩個方向上傳輸,因此全雙工通信是兩個單工方式的結合,需要獨立的接收端和發送端。

七、STM32 中的串口通訊

STM32 串口通信接口有兩種,分別是:UART(通用異步收發器)、USART(通用同步異步收發器),對於大容量 STM32F10x 系列芯片,分別由 3 個 USART 和兩個 UART。

TXD:數據發送引腳;RXD:數據輸入引腳

對於兩芯片的間的連接,兩個芯片 GND 共地,同時 TXD 和 RXD 交叉連接,這樣兩個芯片間可進行 TTL 電平通信。

但如果對於芯片和 PC 機相連,除了共地條件外,不能使用如上的直接交叉連接,雖然兩者都有 TXD 和 RXD 引腳,但通常 PC 機使用的是 RS232 接口(9 針),通常是 TXC 和 RXD 經過電平轉換得到,故如果要使芯片與 PC 機的 RS232 接口直接通信,需要將芯片的輸入輸出端口也電平轉換爲 RS232 類型,再交叉連接,二者的電平標準不同:

單片機的點評標準 (TTL 電平):+5V 表示 1,0V 表示 0;

RS232 電平標準:+15/+13V 表示 0,-15/-13 表示 1。

因此單片機與 PC 機進行串口通信應該遵循:在單片機串口與上位機給出的 RS232 口之間,通過電平轉換電路實現 TTL 電平與 RS232 電平間的轉換.

如果使用 USB 轉串口也可以實現串口通訊,USB 轉串口電路圖如下所示

STM32 串口通訊代碼

STM32 中串口通訊已經給大家建好了相應的庫函數,大家在使用和配置串口的時候直接進行調用庫函數和配置就行了,請大家參照一下代碼:

1、初始化結構體代碼

`typedef struct {
 uint32_t USART_BaudRate; // 波特率
 uint16_t USART_WordLength; // 字長
 uint16_t USART_StopBits; // 停止位
 uint16_t USART_Parity; // 校驗位
 uint16_t USART_Mode; // USART 模式
 uint16_t USART_HardwareFlowControl; // 硬件流控制
 } USART_InitTypeDef;

`

2、NVIC 配置中斷優先級

`NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中斷控制器組選擇 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART爲中斷源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 搶斷優先級*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子優先級 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中斷 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

`

3、USART 配置函數

`void DEBUG_USART_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;
 
 /* 第一步:初始化GPIO */
  // 打開串口GPIO的時鐘
 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
  // 將USART Tx的GPIO配置爲推輓複用模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  // 將USART Rx的GPIO配置爲浮空輸入模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); 
 
 /* 第二步:配置串口的初始化結構體 */
  // 打開串口外設的時鐘
 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
 // 配置串口的工作參數
 // 配置波特率
 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
 // 配置 針數據字長
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 // 配置停止位
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 // 配置校驗位
 USART_InitStructure.USART_Parity = USART_Parity_No ;
 // 配置硬件流控制
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 // 配置工作模式,收發一起
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 // 完成串口的初始化配置
 USART_Init(DEBUG_USARTx, &USART_InitStructure);

/--------------------------------------------------------/
 // 串口中斷優先級配置
 NVIC_Configuration();
 
 // 使能串口接收中斷
 USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
/--------------------------------------------------------/
 
 /* 第三步:使能串口 */ 
  // 使能串口
 USART_Cmd(DEBUG_USARTx, ENABLE); 
}`

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/XelvP6QE5X9oK-zi0_Tgkw