系列文章目录
文章目录
- 系列文章目录
- 前言
- 1. 串口发送模式
- 1.1 轮询发送
- 1.2 中断发送
- 1.3DMA发送
- 2. 串口接收模式
- 2.1 中断接收
- 2.2 DMA接收+空闲中断接收
- 总结
前言
本文主要阐述stm32串口的几种工作中使用模式和编程思路,作为一个知识储备。以便于后续关于rt-thread的串口设备框架的理解。测试开发板使用芯片是STM32F103,库使用ST提供的HAL库。
串口通信协议:
通常情况下1个起始位,8个数据位,无奇偶校验,1个停止位,每传输1字节数据相当于传输10bit,在波特率为9600的情况下,1字节需要,1.04ms,115200传输一字节数据需要0.087ms。
1. 串口发送模式
串口发送方式主要分为3种:轮询、中断、DMA发送。下面简述一下各个模式优缺点
模式 | 优点 | 缺点 |
---|---|---|
轮询 | 代码最简单 | 会导致代码阻塞,会被任何中断,在带os的系统中还容易被高优先级任务打断 |
中断 | 将发送优先级提高到该串口中断级别,不会被任务打断,只会被更高优先级中断打断 | 占用cpu和中断 |
DMA | 不需要cpu参与数据发送,发送也不会被打断 | 代码复杂 |
1.1 轮询发送
轮询发送是将需要发送的数据写到串口的数据(DR)寄存器中,然后通过循环等待发送完成TC标致位置位判断数据是否发送结束。一般串口在115200波特率下发送1字节数据时间大概0.087ms,1k数据至少需要89ms的时间,在没有os的情况下,程序需要阻塞89ms,只会被中断打断。在有os的情况下还需要考虑到任务切换和高优先级任务的使用,串口发送的一包数据就会是断断续续的,时间更长。
一般开发板教程中都会用此方法带领入门,实际只有功能简单且对数据字符间隔较低的场合会使用这种发送模式。
1.2 中断发送
中断发送是对轮询发送的一种改进,其目的是连续发送一包数据,不被低优先级中断和任务打断。其思路是开启串口发送中断,在应用层调用驱动层发送函数时,将中断发送标志位置1/或直接发送第一字节,触发串口中断,在中断中发送剩余数据。期间每次传输完成时进一次中断,其余时间cpu可以运行别的任务,而且减少了查询发送完成标志位的时间。对于没有os的系统来说做到了时间片处理非阻塞发送。
1.3DMA发送
该模式需要根据手册提前配置DMA通道模式等信息,通过HAL库提供的发送函数,DMA会自动将内存中的参数搬运到串口外设中,CPU执行完发送命令就可以执行别的任务了。在dma发送结束时会产生DMA中断告诉用户数据是否发送结束。
2. 串口接收模式
串口接收也有轮询模式,只是确实不实用,本文也不过多叙述。
模式 | 优点 | 缺点 |
---|---|---|
中断 | 代码简单 | 需要多次进入中断 |
DMA | 不需要cpu参与每字节接收,仅产生少量的中断 | 需要配合空闲中断处理 |
2.1 中断接收
中断接收是一种常见的接收方式,适合波特率较低(9600)或任务不复杂的情况下使用。9600传输数据时,使用串口中断接收数据大约1.04ms进一次中断,在要求不高的情况下使用中断接收也能满足设计要求,尤其对裸机基于时间片的代码框架来说影响不大,代码也简洁。但是随着波特率的提高此方法则不太适用,当波特率很高(115200以上),若使用串口中断接收意味着每87us会进入一次中断,那么对主程序的时间片影响将会很大,故推荐使用DMA。
2.2 DMA接收+空闲中断接收
需要提前配置DMA通道,DMA模式,使用DMA搬运数据,串口空闲中断判断驱动层的帧结束。当空闲中断产生时将DMA映射的数据拷贝到应用层的接收缓存区。与中断接收区别是不用每个字节进入一次中断,拷贝数据也是将一帧数据拷贝到缓存区。发送1K数据则会在89ms内进1000次中断,若再提高波特率,对裸机时间片的系统来说影响就很大了。
总结
串口总体上分5中模式,用户需要根据自己的项目需求、实际应用场景选择合适的收发模式。