今天翻出之前的USART学习总结, 重温STM32 的 USART 接收处理,然后根据使用更新一些资料。
先上最终代码下载:https://download.csdn.net/download/zhouml_msn/12396522
实验环境:
STM32F429IG(魔女开发板) + Keil_5.27 + 寄存器操作
实验效果如下
USART 的两种数据接收方式
1:RENE - 非空中断
2:IDLE - 空闲中断 + DMA
- 最好用!
- DMA接收:无需代码干预,DMA自动把接收到的字节,顺序存放到指定数组缓存!
- 空闲中断:自接收到上个字节完成起(RXNE=1),超过一个字节周期时长没收到新数据,产生硬件中断(USART的SR第4位IDLE被置1),这时USART_IRQHANDLER()函数被调用,用户可在这里识别中断的类型,并做数据处理。
空闲中断-使用场景
适用:绝大部分场景都适用。
不适用:接收的字节数据间隔,大于1字节周期时长的! 如正点原子的LORA模块,硬件机制1ms传送1个字节,即115200波特率下接收一字节用90us,但后面900us左右间隔是闲置的,这类机制,不适合使用空闲中断。
代码编写注意坑点
1. IDLE的中断清理方式.
- USART的非空中断标志位, 是自动清理的, 你只要读出数据, 标志会就自动被清, 不用自己费心.
- 但IDLE的中断标志位, 必须通过软件序列清零, 步骤如下:
- u32 temp;
- temp=USART1->SR;
- temp=USART1->DR;
- 这两句顺序还不能错, 之前没细心看手册, 调试差点爆血管. 前人不说, 撞墙也想不出来这前因后果!!
2. DMA 设置
- 使用DMA时, 一般会设置明确的传输数据量, 就是长度是已知道的; 而IDLE 空闲中断 , 最方便的就是接收不定长数据.
- 所以NDTR(传输数量)要设得比实际数量要大, 注意单位:你的字长, 如200. 大多少没关系.
- 中断处理时, 要重新设置DMA的NDTR. 另外: DMA是在关闭的时候才能修改!!
代码结构
整个功能分三小部代码进行编写,USART的初始化、DMA的初始化、中断服务函数;
fputc()的重定向就不贴出来了,可下载完整示例代码。
1)USART初始化
- 声明缓冲区: u8 RxTemp[255]; // 比接收的数据字节数大些就成;另外注意避免使用char类型
- GPIO 初始化
- UART 初始化 // 使能发送, 使能IDLE
- 使能UART接收 // 这一步已开始工作
- 使能中断通道,配置优先级 // 使用了魔女的NVICSet函数,一行代码搞掂
2) DMA初始化
代码中的参数都是比较容易理解的,注意打开STM32的数据手册, 翻查DMA资源表格,确定使用哪个数据流、通道就成。
3)中断服务函数
|