1. 程式人生 > >關於嵌入式學習隨筆->8《UART串行通信原理》

關於嵌入式學習隨筆->8《UART串行通信原理》

停止 hide and 單元 iso 物理 數據 智能卡 eva

1、什麽是串口

串口是MCU(Microcontroller Unit;微控制單元)重要的外部接口,同時也是軟件開發重要的調試手段,現如今基本上所有的MCU都會帶有串口。以STM32F767為例,它的串口資源相當豐富,功能也十分強大,STM32F767IGT6最多可以提供8路串口,支持8/16倍過采樣、支持自動波特率檢測、支持Modbus通信、支持同步單線通信和半雙工單線通信、支持LIN、支持調制解調器操作、智能卡協議和IrDA SIR ENDEC規範、具有DMA等。

處理器與外部設備通信的兩種方式:

--》並行通信

-傳輸原理:數據各個位同時傳輸。
-優點:速度快
-缺點:占用引腳資源多

--》串行通信

-傳輸原理:數據按位順序傳輸。
-優點:占用引腳資源少
-缺點:速度相對較慢

2、串行通信

按照數據傳送方向,分為:

--》單工:數據傳輸只支持數據在一個方向上傳輸
--》半雙工:允許數據在兩個方向上傳輸,但是,在某一時刻,只允許數據在一個方向上傳輸,它實際上是一種切換方向的單工通信;
--》全雙工:允許數據同時在兩個方向上傳輸,因此,全雙工通信是兩個單工通信方式的結合,它要求發送設備和接收設備都有獨立的接收和發送能力。

技術分享圖片

串行通信的通信方式:

--》同步通信:帶時鐘同步信號傳輸(SPI,IIC通信 )
--》異步通信:不帶時鐘同步信號(UART串口通信(通用異步收發器),單總線通信)

常見的串行通信接口:

通信標準 引腳說明 通信方式 通信方向
UART

TXD:發送端

RXD:接收端

GND:公共地

異步通信 全雙工
單總線 DQ:發送/接收端 異步通信 半雙工
SPI

SCK:同步時鐘

MISO:主機輸入,從機輸出

MOSI:主機輸出,從機輸入

同步通信 全雙工
IIC

SCL:同步時鐘

SDA:數據輸入/輸出端

同步通信 半雙工

3、異步串口通信UART

--》物理層(電氣層:接口決定):通信接口(RS232,RS485,RS422,TTL)

-RXD:數據輸入引腳。接收數據。
-TXD:數據發送引腳。發送數據。

技術分享圖片

TTL串口 & RS232 & RS485 & RS422通信接口:

接口類型 邏輯1典型值 邏輯0典型值 說明 優缺點
TTL +5/3.3V 0V 一般的MCU串口引腳都支持TTL

優點:接口簡單

缺點:距離在1.5米以內

RS232 -3V~-15V 3V~15V 三線,全雙工

優點:距離在1.5~30米

缺點:最高傳輸速率20kb/s

RS485 -3V~-15V 3V~15V 兩線,利用壓差傳輸

優點:距離可達1219米,

最大傳輸速率10Mb/s(12米內)

RS422 -3V~-15V 3V~15V

不用共地,兩線,

平衡驅動差分接收,兩組電源獨立

優點:隔離抗幹擾性能強,

距離可達1219米,最大傳輸速率10Mb/s


--》 數據格式(數據層:芯片決定)

STM32串口異步通信數據格式:

-->起始位:1個邏輯0數據位開始
-->數據位(8位或者9位)
-->奇偶校驗位(第9位)
-->停止位(1,1.5,2位)
-->波特率設置

技術分享圖片

STM32串口通信過程:

技術分享圖片
--》通信協議(協議層:程序決定)

通信協議往往由用戶自己根據需要來編寫。

技術分享圖片

  1 void bbsapp_data_cheak(void)
  2 {
  3   			switch(rxState)
  4 			{
  5 				  case waitForStart:
  6 							if(aRxBuffer2[0]  == 0x66)				           	/*起始符正確*/
  7 							{
  8 								USART2_RX_STA=1;
  9 								USART2_RX_BUF[0] = aRxBuffer2[0];
 10 								rxState = waitForData;
 11 							} else							                         /*起始符錯誤*/
 12 							{
 13 								rxState = waitForStart;
 14 							}
 15 					    break;
 16 				  case waitForData:
 17 							USART2_RX_BUF[USART2_RX_STA] = aRxBuffer2[0];
 18 							USART2_RX_STA++;
 19 							if (USART2_RX_STA == 6)				               /*數據接收完成,校驗*/
 20 							{
 21 								rxState = waitForChksum;
 22 							}
 23 							break;
 24 				case waitForChksum:
 25 							USART2_RX_BUF[6] = aRxBuffer2[0];
 26 							if (wifi_cheak(USART2_RX_BUF))	              /*校驗正確,判斷結束符*/
 27 							{
 28 								rxState = waitForEnd;
 29 							} else
 30 							{
 31 								rxState = waitForStart;		                 /*校驗錯誤*/
 32 							}
 33 							break;
 34 				case waitForEnd:
 35 							if (aRxBuffer2[0] == 0x99)				          	/*結束符正確*/
 36 							{
 37 								USART2_RX_BUF[7] = aRxBuffer2[0];
 38 								printf("USART3_RX_BUF is %d  %d  %d  %d  %d  %d  %d  %d  \r\n",USART2_RX_BUF[0],USART2_RX_BUF[1],USART2_RX_BUF[2],USART2_RX_BUF[3],USART2_RX_BUF[4],USART2_RX_BUF[5],USART2_RX_BUF[6],USART2_RX_BUF[7]);
 39                 wifiDataHandle();
 40 								app_ok=1;
 41 //                LCD_ShowNum(0,0,app_flap,10,8);
 42 							} else
 43 							{
 44 								rxState = waitForStart;		                  /*結束符錯誤*/
 45 
 46 							}
 47 							rxState = waitForStart;
 48 							break;
 49 				default:
 50 							break;
 51 			}
 52 
 53 }
串口接收數據解析技術分享圖片
  1 void wifiDataHandle(void)
  2 {
  3 	  app_flap      =   USART2_RX_BUF[1];  //副翼      橫向
  4 	  app_elevator  =   USART2_RX_BUF[2];  //升降舵    前後
  5     app_pwm       =   USART2_RX_BUF[3];  //油門
  6 	  app_rudder    =   USART2_RX_BUF[4];  //方向舵
  7 	  if((USART2_RX_BUF[5]&0x01)==0){ keyFlight=0; }else {keyFlight=1;}   //一鍵起飛  先置1,1秒後置0
  8 		if((USART2_RX_BUF[5]&0x02)==0){ keyLand=0; }else {keyLand=1;}       //一鍵降落   先置1,1秒後置0
  9 		if((USART2_RX_BUF[5]&0x04)==0){ emerStop=0; }else {emerStop=1;}     //緊急停機   每次取反
 10 		if((USART2_RX_BUF[5]&0x08)==0){ flipOne=0; }else {flipOne=1;}       //固定翻轉   
 11     if((USART2_RX_BUF[5]&0x10)==0){ flightMode=0; }else {flightMode=1;} //1無頭  0有頭 		
 12 		if((USART2_RX_BUF[5]&0x20)==0){ flipFour=0; }else {flipFour=1;} 		//一鍵翻轉    點擊後置1,當方向鍵移動過一半時清0
 13 		if((USART2_RX_BUF[5]&0x40)==0){ ledControl=0; }else {ledControl=1;} //光控制
 14 		if((USART2_RX_BUF[5]&0x80)==0){ gyroCalib=0; }else {gyroCalib=1;}   //陀螺儀校準    先置1,1秒後置0
 15 
 16 		printf("app_flap app_elevator %d   %d ",app_flap,app_elevator);
 17 }
通信協議

關於嵌入式學習隨筆->8《UART串行通信原理》