|
前言0 y- P1 x4 N2 } 9 ]; x$ I2 O# Z: y! B% N 在串口通信过程中,我们常常用到接受和发送中断,相信大家都不陌生。这里还有另一个非常有用的中断可能被大家所忽略,即总线空闲状态IDLE中断。当一帧数据传输结束之后,总线会维持高电平空闲,此时会触发MCU的IDLE中断。在本文中,将介绍使用该中断来进行不定长串口数据接收的办法。通过该中断,可以省却用于检测数据传输是否完成的判断操作。# n+ `- f4 v! C& u5 p , d* i! o6 [6 S* C 实验环境5 {' z4 ^) F, o7 }- w& U · STM32F411RE-NUCLEO$ Q+ B% \5 V$ @* N" C2 f · STM32CubeMX1 v# h' j* d6 I" L) X . u) |$ i2 y! l$ h8 m: r. U! [ 总线状态分析 ; m6 e2 [( {: Q% O7 B+ M 下图是发送0xAA 0x55的所抓取到的波形。从图中我们可以看到在发送该帧之前和之后,总线时钟处于IDLE状态。在该帧中,字节与字节之间,没有IDLE状态出现,即不会出现IDLE误触发的情况。; r5 Y8 d4 w* s/ i: `
不定长数据接收; I0 }0 k4 Z7 m. ^$ _/ _ ) J0 Z( g; B, k6 z& O 本次制作的工程是基于HAL库的。在原生的HAL库中,并没有集成IDLE中断的处理。所以,在本文我们介绍的方法中,需要修改一些库文件来实现。 " u: I/ Z3 ]1 R' h# h( Y 使用 STM32CubeMX 生成实验工程& G+ @( u% r4 E8 H# Y4 Q! d/ r & ?! ?( b7 z) y( l+ y 工程的配置如下图:) G. p" z# _- [ C+ O1 s 2 d( s* K2 X+ s& Q. r) l# ` f 1. 系统始终配置为100MHz' U, T k2 \- X6 N% Q 2. 配置USART2为Asynchrones,管脚配置为PA2,PA3。3 ?* J1 N3 V0 q; h0 ~( _- ]2 b' h 3. USART2参数:9600Bits/s, 8bits, None,1Stop
为了方便打印接收到的相关信息,需要对生成的工程做如下修改来映射print函数。 main.c-声明. a" y7 H% E+ T- C2 }
main.c-Code% |, a- o/ t0 a0 {8 M" c9 p
修改工程代码+ U4 N2 c y) b( z! d : R" Z, s1 M4 l& d5 S 增加接收Buffer- ?7 R0 @: p' {: x main.c- a% c0 ?0 g3 K; s) t
stm32f4xx_hal_uart.c
在接收函数中使能IDLE中断 stm32f4xx_hal_uart.c -> HAL_UART_Receive_DMA()函数
处理IDLE中断( {3 n6 }/ I2 N; L7 w & E. F8 }$ V# i stm32f4xx_hal_uart.c -> HAL_UART_IRQHandler ()函数
接收完成处理(IDLE产生,一帧数据传输完成)9 F5 w- J4 H5 @( V stm32f4xx_hal_uart.c -> HAL_UART_AbortReceive_IT ()函数
main.c
使能接收4 W2 M% }+ N8 L4 s main.c
实验结果 使用串口调试,通过STLINK的虚拟串口发送数据,MCU会返回接收多少个字节的数据,并将接收到的数据打印出来。下图是发送0xAA 0x55的实验结果。
小结) w% F" ]+ L, k" _7 Q 合理使用串口总线空闲状态中断,在接收那些数据量不确定的场合会非常方便,同时也能很好地优化代码设计。 s) E3 U8 j; a/ W+ K" i |
微信公众号
手机版