用过HAL库的坛友想必对串口接收中断函数
& \- B7 G# f0 x; e9 Y5 MHAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)7 F" O4 V1 [/ i
中的 参数 uint16_t Size 深恶痛绝,我看到这个函数心里就在想,我又不知道我可能接收到多少数目的字符串,这个参数怎么给,因此通常情况下,我都是用的阻塞接收函数
# W7 l- r4 z9 \$ G& a/ wHAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);/ o. r6 ?3 w$ G+ B7 K
7 p) `9 `0 |( |
最近想到一种思路(借鉴原子的思路),不仅可以使用串口接收中断函数,还可以通过结尾为 0x0d 0x0a(即回车换行)判断接收结束% o8 t' w8 ^% u/ H/ |& y' G! M
每次中断接收一个字符,
& {4 z" q# `* v: S- f- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
5 R; m2 S9 H# `2 B$ b - {
" \. q( \' \5 \" R7 X - if(huart == &huart6)* G' c) Z/ K8 }, t" W) L* |
- {
% b8 Z5 c1 i S; |9 \# H - if((USART_RX_STA&0x8000)==0)//接收未完成
: R+ e$ Z( G5 S! `* O* b3 `" o - {
3 v5 w7 F4 B# j - if(USART_RX_STA&0x4000)//接收到0x0d
4 s& {# t; b9 R# @9 G - {9 P; e) K/ Z' O" B7 _ V- G& U
- if(cc2541_rx_at_buff[USART_RX_STA & 0x3FFF]!=0x0a)USART_RX_STA=0;//接收错误,重新开始6 |" U+ m: X- I/ t5 p
- else k8 g1 i4 c# D5 i4 K
- {7 s+ C# p' T/ F4 }
- USART_RX_STA|=0x8000; //接收完成
4 G: f' `! r, Q, ] - }
: V# y) _3 [' r( _ - }
% f2 \5 V' a! F. @4 A0 F4 ] - else //还没收到0x0d
/ i3 \( d3 v- z+ j' s9 s$ w" A# z - {
9 n5 Y1 z' G1 y0 O - if(cc2541_rx_at_buff[USART_RX_STA & 0x3FFF]==0x0d)/ t$ P1 h* q5 R1 v/ H
- {3 a8 j; D3 Q- Q6 D3 e/ B* ?8 q
- USART_RX_STA|=0x4000;: L) B6 _6 n, b0 {4 A2 [) m H( H
- USART_RX_STA++;' p' h' d7 Z; R# U; }
- HAL_UART_Receive_IT(&huart6,&cc2541_rx_at_buff[USART_RX_STA & 0x3FFF],1);: L5 e J! m# ^! n+ G
- }+ f8 e( v) g: ~% `2 ?; f* g0 b
- else
# Z2 [5 I( \, n - {
: C" n/ C4 w3 t& S6 s0 m) o# L( q9 C - USART_RX_STA++;
2 ^; V7 i4 e) z% _; ~/ X' D - if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始
" D/ n! {( x, Q! [" y( H - HAL_UART_Receive_IT(&huart6,&cc2541_rx_at_buff[USART_RX_STA & 0x3FFF],1);
' z+ c, W. v P3 ]) i2 _1 S4 a - }
" _8 t& R3 c# U9 ]% h+ s% y - }
; E) j5 q: _( i I" ]! B& [ - } l! V# c# Q/ v& B
- }/ c) R) r2 _$ j# {# D
- }
复制代码 其中
, N: H6 O4 T+ d3 y; \- uint8_t cc2541_rx_at_buff[USART_REC_LEN];
j. H( V- |/ q x5 \4 I$ f g - //接收状态5 v8 P; u5 ~7 u+ k# {% F9 g8 Q
- //bit15 接收完成标志. ~6 `& C! s) T: N* `: y4 m
- //bit14 接收到0x0d1 Q* ~- C$ F3 T) p* i& o3 g, O
- //bit13 接收到有效字节数目
* L' m* }6 E* M5 s* F' f - uint16_t USART_RX_STA=0; //接收状态标记
复制代码- #define USART_REC_LEN 200 //定义最大接收字节数
复制代码 在主函数里面,就可以这样写
M5 i8 E! W8 |; w. N- HAL_UART_Receive_IT(&huart6,&cc2541_rx_at_buff[0],1);" B; E% ^4 J- l& W/ F' g2 ?
- while( (USART_RX_STA & 0x8000) == 0);5 f: l4 y6 F- I8 k1 W/ N
- //4 j4 |2 r# e! e5 x* v
- 自己的代码3 W" z& k9 c' M9 c4 _! Y
- //
0 j# x b) j/ i& H) ?7 ?; }+ y3 { - uint8_t i=0;
; ?* {: @, ]' R% n8 u4 e, I - for(i=0;i< (USART_RX_STA & 0x3FFF); i++)/ t! u/ `7 H& s
- cc2541_rx_at_buff[i] = '\0';
" V7 |0 ^& `9 X - USART_RX_STA = 0;
复制代码 " F: z8 M, N' K" k
& s: W/ s- K* b1 F# X
|
是的,但这里可以一次性接收最多为200字节的字符串,以 0x0d 0x0a 结束,这样就可以不用知道要接收多少个字节了
楼主主函数那段代码应该是放在while(1)里面吧,所以不用加
什么叫一个字节式的接收啊
HAL_UART_Receive_IT,它的中断接受,你设置的是每次中断接收一个字节,不是啊?
需要接收到数据就马上进行处理的话可以修改it.c里的串口中断irqhandler
嗯,自己的思想+库函数就是创新!