STM32的USART理解--1

本文介绍了USART在单片机中的作用,重点剖析了RS232和RS485协议在硬件层和软件层的应用,包括电平转换、波特率设置、数据帧格式等,并概述了编程接口和协议遵守的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

USART(Universal Synchronous Asynchronous Receiver and Transmitter)

通用同步异步收发器

首先简单的理解一下,这个所谓的通用同步异步收发器,我们一般把它理解为串口,它是单片机里面的一个外设,是一个设备,收发器。作为串口,它会引出两个引脚,一个是RX一个是TX。至于我们用这个RX和TX来遵循哪种协议来开发串口收发,如用232还是485,那是之后的事。

我们来看野火的这张图,以RS232协议为例。

图中的控制器A和控制器B就是单片机的收发器,两根蓝色的箭头,其实就是收发器的RX和TX线。也就是说我们在用单片机使用USART这个设备的时候,在配置好了以后,只是让收发器工作。并没有关心232协议还是485协议。怎么按照232协议和485协议工作,是另外的工作。

上文说到,USART只是提供了RX和TX线,在配置好了USART之后,只是让TX可以发送数据,RX可以收发数据。至于用的什么协议还没搞好。通常协议分为硬件层和软件层去理解。那么从这两层分别去理解RS232协议和RS485协议。搞清楚在USART是如何实现的不同协议的串口通信的。

RS232协议 

硬件层

仍然以野火的图为例来说,从控制器A出来的RX和TX线会接到电平转换芯片上,这里会有疑问,为什么要接转换芯片呢?这个就是RS232协议规定了!

怎么理解呢?为什么不直接让控制器A的RX和控制器B的TX连接,控制器A的TX和控制器B的RX连接?笔者的理解是,应该是可以连接的,但是是不是能保证十米通信距离呢?毕竟从单片机出来的信号是TTL电平信号,你十米左右信号到了还能保证信号准确吗?另外双方没有个互相认同的发送接受方式,怎么知道哪些数据有效哪些数据是没用的。说白了,别人RS232就是把这些想好了,硬件层,想好在十米的距离多少电压的信号能稳定传输,软件层,想好了什么信号是开始(起始位),什么信号是数据(数据位),什么信号是结束(终止位),什么信号确定信号是准确与错误的(校验位)。这么说应该算比较通俗的解释了协议的意思了吧。

好了,明白为什么要遵守协议了。那么继续讲在硬件层要遵守协议的什么“规矩”。

继续看图,接了一个电平转换芯片,就是将单片机出来的TX信号(TTL电平)转换位RS232需要的电平(暂且就称为RS232电平):

TTL与232电平标准
电平类型电平标准
TTL电平(单片机引出)

逻辑1:2.4V~5V

逻辑0:0V~0.5V

232电平(单片机经过电平转换芯片)

逻辑1:-3V~-15V

逻辑0:3V~15V

通过电平转换芯片之后,如图的两根红箭头,其实就是满足了协议后的RX和TX线了。

往后就是DB9接口,其实就是老式的串口接头,在台式机上很常见。如下图:

 从PC主机上出来的这种叫公头,开发板的叫母头,接上串口线,物理层就完成了。

但是显然,这种接口已经逐渐淘汰了,如笔者拍的这个照片,在公司找了几台PC才找到这个口。

以野火的开发板为例,已经改为miniUSB转串口了。也就是说从电平转换芯片出来的RX和TX线直接连在一个miniUSB的接头上。如果单片机要与PC通信,只需要一根USB线,USB头接PC机,miniUSB接单片机,物理层的接线就满足要求了。如下图所示:

 红色框出的就是单片机的miniUSB端,绿色框出的就是PC端的USB端,物理连接完成。

软件协议层

软件协议层规定的是在硬件线路层传输的电平,怎么规定的看下图:

 有四个需要注意的:

1.起始位:

        以一个bit时长的逻辑0电平为起始位

2.数据位

        数据位为5~8位长,一般为8位

3.校验位

        有多种校验方式:奇校验、偶校验、0校验和1校验,不展开讲

4.停止位

        以0.5、1、1.5、2个bit时长的逻辑1电平为停止位

以上就是发送数据帧的格式,也就是说在RS232协议下,你只有发这样格式的数据帧,才会被识别,才能接收到正确的数据,否则就会出现接收错误,要么是乱码,要么啥也没有。

        另外要补充一点就是,异步串口通信没有时钟同步,规定是用波特率来作为发送的时钟,也就是单位时间内发送的码元个数,比如常用的9600、115200,就是说一秒发送9600个码元,理解成9600个bit就行了。

        再补充一点,在起始位中有说到1bit时长的逻辑0电平,这里说的1bit时长,其实就是说的一个码元持续时间,也就是1/9600(1/115200)秒的时长。

其他协议简单理解

        串口协议除了RS232还有如RS422和RS485,其实这些所谓的协议,已经分成了硬件层和软件层,不同之处也就从这两个层面来区分。硬件层不同无非是连线和电压的不同。例如RS232协议,通过电平转换芯片的作用,使得发送和接收线的电压从TTL电平转换成了RS232的电平;而RS485协议,在经过电平转换芯片后从TTL电平转换成了差分信号,也就是AB线之间的差值。那么我们简单理解,硬件层,由于USART收发器从MCU就引出了两个引脚线(RX和TX),那么我们能做文章的也就是外面的转换芯片了。不管是RS232还是RS485都会有一个电平转换芯片,将USART提供的两条线作为芯片的输入引脚,芯片的输出引脚怎么用,看芯片手册就知道了。当然RS485芯片还需要一个引脚来作为发送接收功能的使能脚。但大体就是以上描述了。

        那么我们在编程应用的时候要做的是什么?

        1.做好USART的设置,包括波特率、数据位长、停止位长、校验模式、工作模式(收\发)、USART中断、写好中断处理函数等等。

        2.写好发送接收接口。

就这!没别的了。

写到这里,只是对USART收发器的一个概念的理解,后面会从编程的角度出发进行总结。

stm32串口1和串口3数据互通,经测试同时发256字节不丢包 void usart3_init(u32 bound) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOBʱÖÓ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //´®¿Ú3ʱÖÓÊ&sup1;ÄÜ USART_DeInit(USART3); //¸´Î»´®¿Ú3 //USART3_TX PB10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍìÊä³ö GPIO_Init(GPIOB, &GPIO;_InitStructure); //³õÊ&frac14;»¯PB10 //USART3_RX PB11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë GPIO_Init(GPIOB, &GPIO;_InitStructure); //³õÊ&frac14;»¯PB11 USART_InitStructure.USART_BaudRate = bound;//²¨ÌØÂÊÒ»°ãÉèÖÃΪ9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñÊ&frac12; USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öÍ£Ö&sup1;λ USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæÅ&frac14;УÑéλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²&frac14;þÊý¾ÝÁ÷¿ØÖÆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê&frac12; USART_Init(USART3, &USART;_InitStructure); //³õÊ&frac14;»¯´®¿Ú 3 USART_Cmd(USART3, ENABLE); //Ê&sup1;ÄÜ´®¿Ú //Ê&sup1;ÄÜ&frac12;ÓÊÕÖÐ¶Ï USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//¿ªÆôÖÐ¶Ï //ÉèÖÃÖжÏÓÅÏÈ&frac14;¶ NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//ÇÀÕ&frac14;ÓÅÏÈ&frac14;¶3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //×ÓÓÅÏÈ&frac14;¶3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀÊ&sup1;ÄÜ NVIC_Init(&NVIC;_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õÊ&frac14;»¯VIC&frac14;Ä´æÆ÷ TIM4_Int_Init(1000-1,7200-1); //10msÖÐ¶Ï USART3_RX_STA=0; //ÇåÁã TIM_Cmd(TIM4,DISABLE); //&sup1;رն¨Ê±Æ÷7 } //´®¿Ú3,printf º¯Êý //È·±£Ò»´Î·¢ËÍÊý¾Ý²»³¬&sup1USART3_MAX_SEND_LEN×Ö&frac12;Ú void u3_printf(char* fmt,...) { u16 i,j; va_list ap; va_start(ap,fmt); vsprintf((char*)USART3_TX_BUF,fmt,ap); va_end(ap); i=strlen((const char*)USART3_TX_BUF); //´Ë´Î·¢ËÍÊý¾ÝµÄ³¤¶È for(j=0;j<i;j++) //Ñ­»··¢ËÍÊý¾Ý { while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //Ñ­»··¢ËÍ,Ö±µ&frac12;·¢ËÍÍê±Ï USART_SendData(USART3,USART3_TX_BUF[j]); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值