STM32外设专题--串口
摘要:本贴讲解STM32的串口相关操作以及使用逻辑分析仪对串口进行分析,为后面讲解OS仓库中的AT组件打下基础。
串口相关的背景知识
串口的用途
串口一般用于MCU和电脑通讯(打印调式信息、下载程序)、MCU和MCU通讯(STM32外接NBiot)等功能,几乎所有MCU都带有串口功能(STM32、51、NBiot、4G模组、WIFI模组、蓝牙模组等),我们LiteOS的AT框架的底层也是串口,所以说串口在现在的应用中十分重要。
3线串口
RXD(receive external data) TXD(transmit external data)
三线串口是我们常用的串口,属于软件流控,类似于在数据包前面和后面加上控制位,我们的STM32一般就是使用这种方式。
9针串口
硬件流控制常用的有rts/cts和dtr/dsr,通过这两组控制线中的任意一组来进行控制,数据包的头和尾不需要加控制位。
波特率:用于衡量传输的速率,通讯双方需要提前协商好该参数,才能正确完成通讯
常见波特率9600bit/s = 一秒传输1200个字节(如果是三线串口,这些数据中包含了校验位、停止位等)
常见波特率115200bit/s = 一秒传输14400字节(如果是三线串口,这些数据中包含了校验位、停止位等)
起始位:在一个时间单位内保持一个低电平(0)代表数据传输开始
停止位:在一个时间单位内保持一个高电平(1)代表数据传输结束(默认停止位为1位)
数据位:起始位和停止位中间的称为数据位(默认是8位)并且默认低位在前(LSB)
例如1000_0010 = 0x31
校验位:默认不使用,如果使用,用一位奇偶校验位来检查数据书否错位
硬件流控:rts/cts和dtr/dsr一般不使用
使用逻辑分析仪抓取电平进行分析
环境:USB转TTL、串口助手、逻辑分析仪
波特率9600,数据位8,校验位0,停止位1,直接将0x01 0x02 0x03以hex形式发送
A1-A2为起始位在一个时间单位保持低电平,代表数据发送开始
A2-B1为数据为8位,将它们按时间8等分,取每个时间段的中心点,结果依次为1000_0000(LSB),0x01
B1-C1为停止位,在一个时间单位保持高电平代表数据发送停止。
C1-C2是下一个数据的起始位
C2-D1是下一个数据的数据位
D1-D2是下一个数据的停止位
STM32L4 HAL库函数串口相关分析
串口初始化流程
①配置串口用到的GPIO口、使能时钟、配置为复用推挽输出、时钟频率为高速等等
②配置串口,使能串口时钟,配置波特率、校验位、停止位等等
③如果需要用到中断在配置中断等
常用识别一帧数据的方法
读取数据末尾的换行符:我们在发送一帧数据时,会勾选串口助手上的发送换行符或者直接手动在一帧的数据的末尾添加上\r\n,接收端可以通过检测当前收到的字节是不是\r或者\n如果是,就代表这帧数据发送完成,可以开始处理。
通过空闲中断识别:我们使能的串口相关中断中,有一个中断叫“串口空闲中断”,当一帧数据传输完成,该中断就会被触发,我们就可以开始处理这帧数据。
当有数据来,UART_FLAG_RXNE标志位会被置位(1),当一帧数据传输完毕,串口处于空闲状态,UART_FLAG_IDLE就会被置位(1)。
串口应用于LiteOS中的编程思想
Linux中的driver思想和文件系统思想,将底层的串口(Uart.c)中抽象出初始化函数、反初始化函数、发送函数、读取函数,并将这些函数注册进Driver中的结构体,供上层Driver.c调用,Driver.c提供统一的接口,给AT.c调用,可以屏蔽底层的细节,AT层完全不会受到Uart.c层的差异的影响,换句话说,假设我们需要将这个系统由stm32移植到51单片机,AT.c及以上层无需修改,只需要去更改Uart.c中的接口,这种分层思想极大的提高了可移植性和可维护性。
printf实现方法
printf函数是stdio库中的库函数,它的底层是调用fput或者_write将需要发送的数据以字节为单位发出,如果在STM32开发中仅仅只包含stdio.h头文件,直接调用printf函数,是不会打印出来数据的,因为系统并没有帮助我们自动实现底层的fput或者_write函数,这个需要我们自己实现。因为stdio库的实现在IAR、Keil和ARM-GCC中有差异,所以导致调用的底层函数名也不同,请往下看。
Keil和IAR
ARM-GNU工具链
scanf函数也可以以此类推
Keil和IAR
ARM-GNU工具链
- 点赞
- 收藏
- 关注作者
评论(0)