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

STM32 hal库串口空闲中断最新用法

[复制链接]
STMCU小助手 发布时间:2022-10-20 18:47
前言
* B. G. z0 k: {0 A/ |串口在单片机中是使用比较频繁的一部分,一般我们人机交互就会使用到串口。串口的输出比较简单直接调用发送函数即可,接收数据就要稍微麻烦一些,因为我们接收的一般是不定长的数据。但是最近使用到了stm32的串口接收的时候,发现hal库竟然有提供串口空闲中断接收函数,无需配置和自己写中断函数。
1 s+ G$ g0 c) N: Y- x' v6 a5 m% g; a6 I) I2 j/ o0 }) @
一、串口空闲中断是什么?3 x9 E) O- N$ z( A; v; {
一般我们串口接收的时候都是使用的RXNE,接收到一个字节数据就进入一次中断,然后把它放入缓存,但是数据量很大的时候会频繁进入中断影响单片机的时效性。这时就可以使用到IDLE空闲中断,即在接收到一段数据后在一定的时间检测到没有数据到来,就认为此时串口总线空闲便产生一个空闲中断。
0 `, I5 P# d: U( W, x3 E' @( f
9 \/ ~7 _* I. z' Q' \- G% k二、使用步骤
/ p$ h; N( Q1 Z( v1.hal库空闲中断接收函数:0 n$ M3 Y7 U7 k) V
在stm32f1xx_hal_uart.h中
5 n/ Q6 `5 {* {9 a3 d, i5 v! w/ E+ z' u$ Y: a& \
  1. //在阻塞模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。* Q! z2 l" _* h+ n$ X7 O$ ?
  2. HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout);" @( i2 ^4 _6 s# n+ T6 @5 V* {
  3. //在中断模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。
    : m7 i2 x: N5 ~
  4. HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);5 R. \, e' k4 T" x) X( g
  5. //在DMA模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。5 ?7 J' x" f' b/ K) _2 H
  6. HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);+ g  S- k$ g: g5 d  ]
  7. //使用空闲中断时的接收回调函数; R+ Z1 U: F# p
  8. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);
复制代码
) r) j! p0 }2 F( G: }; v9 j: {
HAL_UARTEx_ReceiveToIdle_IT()
- p3 S2 m6 U% t  u+ Q4 z5 j# u% L! w6 a/ @: Q" _
  1. /**
    8 P+ L% M6 Y+ ]" X6 S" x
  2.   * @brief 在中断模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。! B# Q+ W! r4 h+ C3 V% b1 _, h
  3.   * @note   接收由此功能调用启动。由于RXNE和空闲事件引发的UART中断,接收的进一步进展得以实现。在接收结束时调用Callback,指示接收到的数据元素的数量。
    ( O- a6 z! E7 \/ o  J. V4 N9 ]
  4.   * @param huart UART handle.
    & B* ^7 Z( t) C+ T
  5.   * @param pData        指向数据缓冲区(uint8_t或uint16_t数据元素)的指针。
    5 K% W9 K' l4 |, \' S
  6.   * @param Size  要接收的数据元素的大小(uint8_t或uint16_t)。
    7 X- b( @2 V1 q# h! N/ @* h
  7.   * @retval HAL status
    & U* \5 }; D# M! n  f$ Q3 i
  8.   * */8 L5 C7 |! p4 [" F/ B
  9. HAL_StatusTypeDef        HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
复制代码
* U- ^* }. l  ~# ~; y3 d8 Z3 d
2.使用方法) b$ E1 Q' I, F
1.在主函数中调用HAL_UARTEx_ReceiveToIdle_IT()2 v" O' i7 v, ]
2.然后在回调函数 HAL_UARTEx_RxEventCallback()中做相应处理。
4 x& N1 O+ U# k! U
  1. int main(void). }! ]3 r& m; `* Z8 H) C
  2. {
    2 y5 p; _& E0 B2 k1 E+ b
  3.   /* USER CODE BEGIN 1 */
    / N3 ]% |2 Z' y
  4.         //__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);9 M( K9 |1 J; d* l( k
  5.   /* USER CODE END 1 */8 V" c* o3 v; q: e, ?7 k

  6. $ h( p% a1 ~& P! ~5 F
  7.   /* MCU Configuration--------------------------------------------------------*/, G9 n1 r% i; ]: ~! w  j

  8. 5 E; l! R, P+ N1 @& Q* v, E/ W
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    , G' l8 J1 x5 _' U: g
  10.   HAL_Init();+ i5 J/ Z  q1 [7 ^4 k  i6 R( u% [
  11. 2 y! `( r' [3 [- f* Y" {
  12.   /* USER CODE BEGIN Init */
    8 g6 w+ |9 h+ N9 c1 u
  13. 4 m& p6 ?) c7 }- F( i7 e
  14.   /* USER CODE END Init */" h. x& [0 O. Q1 O6 F6 g

  15. 9 n0 X/ Z; ]9 J+ ~
  16.   /* Configure the system clock */
    ! _0 N1 X( O8 ?& d
  17.   SystemClock_Config();& G" z. g8 Y1 [- C
  18. , m, G. P& S* j0 P
  19.   /* USER CODE BEGIN SysInit */
    * X; x5 ^! q( |# n' p4 G1 S3 w. y

  20. # C% m& h' ?  F5 V1 h& H. @
  21.   /* USER CODE END SysInit */5 @) O# b# A1 C3 `! Z. x& M
  22. 7 ?% E. B  B+ Z+ v" W
  23.   /* Initialize all configured peripherals */2 i! ]; \/ }: r& {: \, [6 J1 y, r
  24.   MX_GPIO_Init();% i* y) G: \( ]% w
  25.   MX_USART1_UART_Init();
    6 n( X; T( V' V3 F( p2 K; N
  26.   /* USER CODE BEGIN 2 */
    ) Q6 ~6 }) Z) O0 e/ A2 b
  27.   //空闲中断接收1 l/ k- q; Q" r, e% ^
  28.   HAL_UARTEx_ReceiveToIdle_IT(&huart1,Uart_ReadCache,410);
    ) t0 W0 B3 ^% x& Z+ _" m
  29.   /* USER CODE END 2 */
    . r8 e, D3 I" R0 y
  30.   Q$ t# D* C$ `0 |3 o: I
  31.   /* Infinite loop */) B( ^3 m4 ?3 |0 U
  32.   /* USER CODE BEGIN WHILE */
    $ \" \; S9 W9 E: `' Q1 M
  33.   while (1), N5 c. `$ n& w- s0 M6 C' `
  34.   {% a5 P) N' Q" @
  35.     /* USER CODE END WHILE */
    5 H9 I( y7 c: @. t( m

  36. : q% B4 j0 {7 [+ E7 g8 y
  37.     /* USER CODE BEGIN 3 */: {+ g; k4 _: D
  38.   }
    ) `+ j. h# c" B. S4 B( d) ]
  39.   /* USER CODE END 3 */
    % h! v1 ?" o, i: Q# |" n/ y
  40. }
    2 D% ~9 F6 |) k. |  K" [4 ^
复制代码

8 o) V! @, b9 u6 x% Y" ?
  1. //空闲中断回调函数,参数Size为串口实际接收到数据字节数
      \$ k* r* r/ L7 G! D4 N& E. j
  2. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)# @. X( ?2 ^6 j* v
  3. {: r: i/ w/ K' w, H+ g* `+ M+ r
  4.         if(huart->Instance==USART1)# H3 L: V, ~; h% @5 z) E( j# [# P+ o
  5.         {5 T" \& A  X9 g' L
  6.                 //把收到的一包数据通过串口回传3 i7 I5 u5 `( M/ ?& S
  7.                 HAL_UART_Transmit(&huart1,Uart_ReadCache,Size,0xff);
    5 p2 Q% y( Y2 O6 q  W( C* |0 H
  8.                 //再次开启空闲中断接收,不然只会接收一次数据/ K  Q# h, O1 f% }6 G
  9.                 HAL_UARTEx_ReceiveToIdle_IT(&huart1,Uart_ReadCache,410);
    8 H/ f( s! {9 v+ j
  10.         }
    2 }& N7 d! V$ i( U
  11. }
复制代码

, g4 D' R2 ?# ^2 L1 ^% P* h) y3.最终效果
! E- t6 q5 M! x# D2 a- v5 f' h9 m5 Y0 d- X
bdfc36342721436681e1c6011488e126.png
3 @) G/ b# U4 j( n5 R, H$ X  {6 M  ^+ i4 F
总结
4 p  N" ?9 `0 u% D使用stm32 hal自带的空闲中断函数后我们通过串口接收不定长的数据变得十分的方便了,只需要调用两个函数即可。不像刚开始的时候使用串口空闲中断还的自己开启中断和自己编写中断回调函数,大大地提高了我我们开发的效率。
9 g  x2 ^' P5 d1 {————————————————
6 ^& d* F2 I$ k( A( \! V. y版权声明:北世安
7 k  |5 _" a& J3 l* v2 D2 `, t

' t+ n7 X  t% P" o; b) a! G
赞 收藏 评论0 发布时间:2022-10-20 18:47

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版