你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

HAL库串口接收中断函数的一种使用方法

[复制链接]
feiting94 发布时间:2015-11-24 19:41
用过HAL库的坛友想必对串口接收中断函数/ D- @8 [( Q* \% f7 R. [- |
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
& k$ \/ u; Z% y7 M5 K中的 参数 uint16_t Size 深恶痛绝,我看到这个函数心里就在想,我又不知道我可能接收到多少数目的字符串,这个参数怎么给,因此通常情况下,我都是用的阻塞接收函数  R8 D$ ?; O7 l9 D9 l1 N7 Y
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);$ R9 O3 {5 l' F) ~, E7 m4 ^+ p
: ]* V7 p4 c) c* ~
最近想到一种思路(借鉴原子的思路),不仅可以使用串口接收中断函数,还可以通过结尾为 0x0d 0x0a(即回车换行)判断接收结束
) |& @. {/ H7 _: m, o每次中断接收一个字符,6 {+ r- I& i% R
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    * c, r1 O8 s) O  u
  2. {
    0 L+ o' U1 X! d# P7 c' \
  3.         if(huart == &huart6)
    ! [+ p* g2 W. [; M
  4.         {
    4 B9 ]+ {4 r' L( U! E
  5.                 if((USART_RX_STA&0x8000)==0)//接收未完成
    , ]- u# x/ _" g8 V
  6.                 {
    0 L/ {( l2 q4 k- m# [$ F% }+ ^
  7.                         if(USART_RX_STA&0x4000)//接收到0x0d+ n# B9 k% y2 G
  8.                         {
    - c6 P  ?  z9 Q8 l
  9.                                 if(cc2541_rx_at_buff[USART_RX_STA & 0x3FFF]!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    & S2 X2 Z& O- t/ ^
  10.                                 else
    2 s6 A* ~5 X, z: G2 S1 u9 N
  11.                                 {
    : V: R! J0 w& A. c$ g
  12.                                         USART_RX_STA|=0x8000;        //接收完成7 X' C# p+ Q; Z% p* y0 ~( d  U2 t
  13.                                 }
    4 {# c4 J0 E; X0 }- _& W# E  r
  14.                         }1 [& h0 t# l6 h' ^: J2 R
  15.                         else //还没收到0x0d
    / c8 _0 z& i1 d) y* A# F
  16.                         {       
    2 c0 ]# B% m# F8 h  Y
  17.                                 if(cc2541_rx_at_buff[USART_RX_STA & 0x3FFF]==0x0d)* l  B, v7 g: I2 f; {$ n3 W
  18.                                 {
    # @+ L8 l8 p' ~0 c
  19.                                         USART_RX_STA|=0x4000;
    4 b. Y9 y/ h5 x4 e8 B) j+ \' j3 |
  20.                                         USART_RX_STA++;
    5 P+ w2 E- d; J. k3 s3 B+ I5 R& b
  21.                                         HAL_UART_Receive_IT(&huart6,&cc2541_rx_at_buff[USART_RX_STA & 0x3FFF],1);# y6 v9 i8 j! h8 L
  22.                                 }% U, o0 Q3 y4 L" O
  23.                                 else
    1 E8 O6 V) u/ ^& I
  24.                                 {+ b$ M6 S! J9 j2 i2 r+ d
  25.                                         USART_RX_STA++;
    5 T' A/ \7 [- g2 t9 y+ ~
  26.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始
    ' ^, a1 O9 {5 l
  27.                                         HAL_UART_Receive_IT(&huart6,&cc2541_rx_at_buff[USART_RX_STA & 0x3FFF],1);                                                    
    4 y  i9 A; z/ B1 v2 C% N3 y
  28.                                 }                 
    / k3 N% R! @* Q6 \+ [9 f9 m0 K5 J
  29.                         }
    * f0 `+ E" v3 F" p
  30.                 }               
    9 D; R+ l- o& Q4 c
  31.         }
      {. a6 n& n0 [. \* i
  32. }
复制代码
其中
% c# w7 E! D( l9 F  i
  1. uint8_t cc2541_rx_at_buff[USART_REC_LEN];" l; F0 N+ Q* d$ n
  2. //接收状态
    / f4 L, G; L/ k! ~
  3. //bit15  接收完成标志4 X6 q: q  b7 A4 C) q
  4. //bit14  接收到0x0d$ n7 n0 |6 V0 ?1 x
  5. //bit13  接收到有效字节数目3 l* ~* F: p7 w0 @: y1 r
  6. uint16_t USART_RX_STA=0;       //接收状态标记
复制代码
  1. #define USART_REC_LEN                          200          //定义最大接收字节数
复制代码
在主函数里面,就可以这样写
' f8 R  C& b/ D  x6 Z) _- R
  1. HAL_UART_Receive_IT(&huart6,&cc2541_rx_at_buff[0],1);. Y6 {! U' `9 E. ?5 q; N$ ^
  2. while( (USART_RX_STA & 0x8000) == 0);
    : ^  T5 B2 `# L+ C
  3. //
    8 O& g( `2 K; V) ~
  4. 自己的代码6 J' q: C9 U# l9 @0 e
  5. //9 a6 S! h& O% Q! i% @$ a9 C* v, m
  6.         uint8_t i=0;* H9 ]) l' \5 L
  7.         for(i=0;i< (USART_RX_STA & 0x3FFF); i++)' V- @* A/ U0 |
  8.                 cc2541_rx_at_buff[i] = '\0';
      y& u5 n( J( I# H% ^) y
  9.         USART_RX_STA = 0;
复制代码

% w: T% ~- v& W; S9 o
( ~( d$ A: ^# b' B" L' x% j# O
赞 收藏 3 评论21 发布时间:2015-11-24 19:41

举报

21个回答
em78p156 回答时间:2016-4-13 15:31:36
串口在成功接收一行信息后,就不会再接收数据了。因为完成接收后没有打开接收中断,而主程序处理完把USART_RX_STA清0后也没有打开中断。需要在USART_RX_STA = 0;后增加一句HAL_UART_Receive_IT(&huart1,&Rxbuff[0],1);//开启接收中断
feiting94 回答时间:2015-11-25 17:40:54
hithfy 发表于 2015-11-25 15:408 r) G& A% A+ H- Q
HAL_UART_Receive_IT,它的中断接受,你设置的是每次中断接收一个字节,不是啊? ...

1 `2 P  u0 D7 T/ q是的,但这里可以一次性接收最多为200字节的字符串,以 0x0d 0x0a 结束,这样就可以不用知道要接收多少个字节了
夏义道 回答时间:2016-6-5 12:14:51
em78p156 发表于 2016-4-13 15:31
" v" \4 P# p6 t3 J+ j2 g3 |串口在成功接收一行信息后,就不会再接收数据了。因为完成接收后没有打开接收中断,而主程序处理完把USART_ ...

4 U( |  w! m' b, X5 O楼主主函数那段代码应该是放在while(1)里面吧,所以不用加
风子 回答时间:2015-11-24 22:41:49
谢谢分享
wangzhenassd 回答时间:2015-11-25 04:03:22
谢谢分享!
orima 回答时间:2015-11-25 08:30:40
谢谢分享,论坛里关于HAL库的应用讲解信息不是很多。。。
hithfy 回答时间:2015-11-25 08:59:02
嗯,一个字节式的接收,这样最后实现了没?
feiting94 回答时间:2015-11-25 11:00:08
hithfy 发表于 2015-11-25 08:59
( O% p' q0 o6 v  X" P: |嗯,一个字节式的接收,这样最后实现了没?

7 U( {! c* T9 b* M9 h: s什么叫一个字节式的接收啊
hithfy 回答时间:2015-11-25 15:40:20
feiting94 发表于 2015-11-25 11:00
6 q- ?3 h" ?% [) W# L什么叫一个字节式的接收啊

# l) O" y/ K! ?. cHAL_UART_Receive_IT,它的中断接受,你设置的是每次中断接收一个字节,不是啊?
stary666 回答时间:2015-11-25 16:54:45
看看,,,,,,,,,,,,,,,,,,,,,
peter001 回答时间:2015-11-25 17:51:36
谢谢分享
党国特派员 回答时间:2015-11-25 22:11:01
其实串口之提供一种通讯方式,而通讯的协议要靠自己去实现。
埃斯提爱慕 回答时间:2015-11-25 22:17:13
提示: 作者被禁止或删除 内容自动屏蔽
tempchar 回答时间:2015-11-25 23:50:44
接收到的数据的长度可以从huart的rxXferSize-rxXFerCount计算出来。! n: L( J. U( E1 H) F) m& `( i# L
需要接收到数据就马上进行处理的话可以修改it.c里的串口中断irqhandler
hithfy 回答时间:2015-11-26 08:27:17
feiting94 发表于 2015-11-25 17:40
% @( C$ F4 K# s4 s+ t. `  _2 @是的,但这里可以一次性接收最多为200字节的字符串,以 0x0d 0x0a 结束,这样就可以不用知道要接收多少个 ...
& L. d7 l8 N' b, p1 f7 U# U" Q8 Z' n
嗯,自己的思想+库函数就是创新!
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版