关于嵌入式学习随笔->8《UART串行通信原理》

1、什么是串口

      串口是MCU(Microcontroller Unit;微控制单元)重要的外部接口,同时也是软件开发重要的调试手段,现如今基本上所有的MCU都会带有串口。以STM32F767为例,它的串口资源相当丰富,功能也十分强大,STM32F767IGT6最多可以提供8路串口,支持8/16倍过采样、支持自动波特率检测、支持Modbus通信、支持同步单线通信和半双工单线通信、支持LIN、支持调制解调器操作、智能卡协议和IrDA SIR ENDEC规范、具有DMA等。

处理器与外部设备通信的两种方式:

--》并行通信

   -传输原理:数据各个位同时传输。
    -优点:速度快
    -缺点:占用引脚资源多

--》串行通信

   -传输原理:数据按位顺序传输。
    -优点:占用引脚资源少
    -缺点:速度相对较慢

2、串行通信

按照数据传送方向,分为:

--》单工:数据传输只支持数据在一个方向上传输
--》半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;
--》全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。

image

串行通信的通信方式:

--》同步通信:带时钟同步信号传输(SPI,IIC通信 )
--》异步通信:不带时钟同步信号(UART串口通信(通用异步收发器),单总线通信)

常见的串行通信接口:

通信标准 引脚说明 通信方式 通信方向
UART

TXD:发送端

RXD:接收端

GND:公共地

异步通信 全双工
单总线 DQ:发送/接收端 异步通信 半双工
SPI

SCK:同步时钟

MISO:主机输入,从机输出

MOSI:主机输出,从机输入

同步通信 全双工
IIC

SCL:同步时钟

SDA:数据输入/输出端

同步通信 半双工

3、异步串口通信UART

--》物理层(电气层:接口决定):通信接口(RS232,RS485,RS422,TTL)

-RXD:数据输入引脚。接收数据。
-TXD:数据发送引脚。发送数据。

image

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位)
      -->波特率设置

image

STM32串口通信过程:

image
--》通信协议(协议层:程序决定)

通信协议往往由用户自己根据需要来编写。

  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 }
通信协议
posted @ 2019-02-27 23:53  Yimiu  阅读(988)  评论(0编辑  收藏  举报