|
前言 5 S, M4 m, m$ ^# l 在串口通信过程中,我们常常用到接受和发送中断,相信大家都不陌生。这里还有另一个非常有用的中断可能被大家所忽略,即总线空闲状态IDLE中断。当一帧数据传输结束之后,总线会维持高电平空闲,此时会触发MCU的IDLE中断。在本文中,将介绍使用该中断来进行不定长串口数据接收的办法。通过该中断,可以省却用于检测数据传输是否完成的判断操作。9 p8 H% ~- B, k 实验环境 · STM32F411RE-NUCLEO3 V: ~/ Y; w% d6 _7 k · STM32CubeMX) f; e" u0 `; }7 [3 y9 C/ F 总线状态分析 3 L9 C4 @8 {2 t, O( W 下图是发送0xAA 0x55的所抓取到的波形。从图中我们可以看到在发送该帧之前和之后,总线时钟处于IDLE状态。在该帧中,字节与字节之间,没有IDLE状态出现,即不会出现IDLE误触发的情况。6 A" z- c. c9 n V! `
不定长数据接收0 G6 `" Y9 E1 G( o5 u( _ 2 {! S+ U1 M. K! Q" L L 本次制作的工程是基于HAL库的。在原生的HAL库中,并没有集成IDLE中断的处理。所以,在本文我们介绍的方法中,需要修改一些库文件来实现。7 D( }, h3 S* L 使用 STM32CubeMX 生成实验工程- R+ p4 [0 `* t% C4 B% } 1 a8 `* K! Y" T9 s4 I. V4 ? 工程的配置如下图: i" Q; b# \( T 1. 系统始终配置为100MHz 2. 配置USART2为Asynchrones,管脚配置为PA2,PA3。 3. USART2参数:9600Bits/s, 8bits, None,1Stop$ }( c/ I# k- N3 \1 [3 T' r
为了方便打印接收到的相关信息,需要对生成的工程做如下修改来映射print函数。* ~$ H" U$ T0 T+ L9 A- c main.c-声明
main.c-Code
修改工程代码' j" k, g% i/ i8 g- G. P( \* H5 s; A , |" Z4 F4 U8 v- {- q }( j 增加接收Buffer main.c
stm32f4xx_hal_uart.c
在接收函数中使能IDLE中断 8 p- ?6 Z+ T) t" U1 X0 ` stm32f4xx_hal_uart.c -> HAL_UART_Receive_DMA()函数: O. d1 }, X* _3 A% Q+ L
处理IDLE中断/ ?, Z7 t2 @+ q$ o! E3 `( M stm32f4xx_hal_uart.c -> HAL_UART_IRQHandler ()函数; Z- L# r& a. q
接收完成处理(IDLE产生,一帧数据传输完成) " T& k) x1 |/ d' T( Q1 X5 u stm32f4xx_hal_uart.c -> HAL_UART_AbortReceive_IT ()函数2 p, e9 z9 Z8 m9 p* E
main.c
使能接收9 X: A: A* z! ]' b main.c
实验结果+ |) b0 s7 [& [# H - @7 |; \- Q' W( I 使用串口调试,通过STLINK的虚拟串口发送数据,MCU会返回接收多少个字节的数据,并将接收到的数据打印出来。下图是发送0xAA 0x55的实验结果。
小结 合理使用串口总线空闲状态中断,在接收那些数据量不确定的场合会非常方便,同时也能很好地优化代码设计。+ A0 c5 _$ M* J, d y; Z. G |
微信公众号
手机版