一个关于STM32串口的问题。他想实现接收无限制字符数量的串口信息。9 H B& B. l( l# P 9 j& P U- {- K- j 但是他遇到了一个问题,他在主函数中发送循环发送内容(500ms的延时)串口一中断回调函数中如果收到了串口内容,就利用串口发送。# V" z- x" x& s9 O% y3 k+ p: S# F # d4 n3 P& G- a5 c% A0 R1 P/ b4 r1 m 但是他的串口一旦接收到了信息就会导致主循环中的串口发送极快。他的主代码如下7 J w8 L; w3 `' _4 H
看了他的代码,就这么短短的7行代码,让我汗流浃背。8 W7 T- Y1 P( p8 [. I+ e. F/ Z9 @ W2 q/ {4 [$ f3 o/ I 他的发送和接收中有一个参数是8,这意味着当串口接收的寄存器中有8个数据时就会触发中断回调。1 k+ e( t+ b% t 3 [" o, Q0 j% w" v. w0 N! z* b: T$ [ 我们需要注意的是,串口寄存器的数据会被存储到缓存区中,这里的缓存区相当于一个队列先进先出,当我们调用HAL_UART_Receive_IT(&huart1,&RecieveBuffer,8);% j: H( l1 q" L6 T( f ^! H9 S, P. i) |1 G2 `+ Q; \ 会将RecieveBuffer作为缓存区,将串口接收的信息存入缓存区。: Q+ ^/ ^. ]- o2 @6 S" \ 那么让我们来试一下这段代码。 ! F! W8 p& J) p8 Q" g 可以看到,代码死住了。其实不难理解,我们发送数据的时候,由于缓存区只有一个字符的空间,我们发送八个字符的时候会导致缓存区溢出。所以我朋友的代码可以“正常运行”也是一件非常奇怪的事情。 6 a) e9 V1 X8 ?* L2 I& B5 p* n9 | 所以正确的做法应该是:设置和缓存区一样长的读取字符。
这样子就可以实现每接收8个字符就调用中断一次 可以看到,我们正常的发送了8个字符。# c( p" T- O0 Y7 T5 h0 T& ^ 但是这样子有一个非常非常致命的缺点!9 M ^5 [5 V/ e$ S ( ? a7 e# r( A6 j2 ^3 Z 由于我们的代码每8个才会接收一次,所以当我们的发送的数量小于8时,必须发送多次才能会触发一次调用。 注意,这里的每次我们都是先发送再接收,因为初始化的时候是启用了接收。" N! V9 @7 G7 `. T6 t0 ? 9 q* |, g8 ~) M! w, \2 ~4 b! ?1 V 当我们发送3次“123”时才能让接收的字符>=8,我们把前八个发送了出去,此时缓存区剩下了一个字符是“3” + {+ U; T: u/ Q% k( }0 Y : C. F( O% E/ P( @3 v 第二次我们发送了三次“123123123”,再次让字符数量>=8,这时候把缓存区的八个“31231231”发送出去再接收后面的“23”,这时候缓存区的数据为:"23 "。' i$ F* I2 b( [# v! Z 5 X3 X u* B) ~7 I$ @' Y, U 最后我们第三次发送“123”的时候,由于23 + 123 + 123 这时候,虽然这里按理来说正好八个,但是实际测下来,当这时候接收的时候系统就会卡死。/ K/ i; c, y9 E( q7 m! @7 V 所以,实际上这种方法必须保证发送端的数据是完完整整的八个八个发送,多一个少一个都不行。0 s h" y; x8 t1 Y0 J: M9 p- z ; @/ x, ~7 q3 ~1 H$ O# w! L/ q0 Y8 Y 6 S, `+ T; n* y) k5 g% a3 @2 Q 解法 事实上最标准的做法是单个字符单个字符处理。定义一个大的缓存区,用来存储接收到的字符并且确立一个结束符来确定数据流的结束。
! _+ \$ O8 o, ~ 上述是正点原子的官方例程,其中USART_RX_STA是接收到的字符,即是确定一个结束符\r\n来作为一串字符的结尾并且检测长度是否超出长度。# m$ C. B2 ~5 t# _1 I5 \$ E 这样子的代码容错率非常高,也确定了一个规范,并且避免了缓存区溢出的情况。 转载自:电路小白" U c0 D5 N5 C$ q8 t% J G, S 如有侵权请联系删除* ]% }8 n; P2 b/ Q) D: {) z! Y ( u8 M- @5 r! u4 }) g8 ?# p |
【NUCLEO-WB09KE评测】STM32WB09KE的内部BootLoader使用
11111111111111111111111111111111111
STM32芯片ISP串口程序一键下载—FlyMcu
如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向
基于STM32数组越界异常中断经验分享
基于STM32之数组越界异常中断经验分享
基于STM32连接参数更新进程后导致断连的问题分析
基于STM32连接参数更新进程后导致断连的问题分析
基于STM32 Azure USBx 开发的经验分享
NUCLEO-U545RE-Q评测】4. 串口实用收发测试