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

【经验分享】UART IDLE 中断使用-接收不定长串口数据

[复制链接]
STMCU小助手 发布时间:2022-2-15 22:07
前言6 Q6 l* W1 \* b6 _* E
在串口通信应用中,我们常使用接受和发送中断,相信大家都不陌生。这里有个非常有用的中断可能被大家所忽略,即总线IDLE 中断。当一帧数据传输结束之后,总线会维持高电平状态,此时,就可以触发 MCU 的 IDLE 中断。在本文中,将介绍使用该中断来进行不定长串口数据接收的办法。通过该中断,可以省却很多用于检测数据传输是否完成的判断动作。9 V  i% J$ y  W- |, U
实验环境' [% z" t0 Y# k5 g; w5 j- e
   STM32F411RE-NUCLEO. Z2 }6 d0 }' n% K  J
   STM32CubeMX5 p* _% E2 l  n: Y1 Y; G% a
7 F, @; K4 P; L5 ]
总线状态分析
! s' X. @- d" s4 L下图是发送 0xAA 0x55 的所抓取到的波形。从图中我们可以看到在发送该帧之前和之后,数据线处于 IDLE 的状态。在该帧中,字节与字节之间,没有 IDLE 状态出现,即不会出现 IDLE 误触发的情况。3 [8 E$ l1 \8 X9 R9 X8 ]; r
+ {# @% w9 X/ U) [* `
G_YB)_J~CWYDHOKQS]P0.png
' P, _+ @1 g' v6 d' E! U9 P: D' Z4 P8 K( j, o! P
不定长数据接收8 u' U8 M+ K% n1 @0 @9 t
本次制作的工程是基于 HAL 库。在原生的 HAL 库中,并没有集成 IDLE 中断的处理。所以,在本文我们介绍的方法中,需要修改一些库文件来实现。
  i$ W' C: d: X3 ]/ }$ p5 A: Y
8 x$ _7 ^- ^# _; V8 U+ W使用 STM32CubeMX 生成实验工程
7 c# h) w1 E4 A$ h工程的配置如下图:
  J" o' q$ s  }" z) Y) m0 k. K1. 系统始终配置为 100MHz
0 |3 @6 H2 ?+ j& T% y& a3 u1 j" b2. 配置 USART2 为 Asynchrones,管脚配置为 PA2,PA3。
% J5 N+ s8 _# h4 }3. USART2 参数:9600Bits/s, 8bits, None,1Stop
8 c  u9 M3 U) j* t- _& N- D' \4 S2 }" Y+ B
{NA4%H92Q97)J{D5LUGEWAE.png
3 W% Q7 h( R1 y  |2 S
/ p+ P$ H& N+ D: ]4 R为了方便打印接收到的相关信息,需要对生成的工程做如下修改来映射 print 函数。
# e3 R+ m2 ?' Z3 t. O: k. Hmain.c-声明
9 z3 p5 B  Z% {2 F+ p( k
  1. #ifdef __GNUC__0 d5 C# u; h. w( i) U) e
  2. /* With GCC, small printf (option LD Linker->Libraries->Small printf
      \/ y+ b2 R) E1 M7 o6 ?7 u6 q1 j
  3. set to 'Yes') calls __io_putchar() */( N6 b# Z: g2 M9 m" d' I
  4. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch): {; s9 M2 F3 i3 H* {' Z. N
  5. #else
    - L  T& Q% ?( ~7 F* L
  6. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    - N  A3 b, |6 P3 g
  7. #endif /* __GNUC__ */
复制代码
+ X* _4 V9 H. }3 a5 G3 O" k7 N5 Z
$ a7 W: Y/ T! s. y/ ^
main.c-Code' a% \+ ~" o$ t4 c
  1. /**
    ' I" N1 `8 i2 A8 K- X! ~% K

  2. - d: G  Z6 S- ]) \
  3. * @brief Retargets the C library printf function to the USART.2 Q" a. J  ]# t5 ?
  4. * @param None( P$ X* |% D( `; `1 y5 N1 h
  5. * @retval None
    2 }3 G* q' o% d1 m2 ]
  6.   */
    5 T; y8 M0 Z4 m7 V
  7.   PUTCHAR_PROTOTYPE, l5 ?6 |8 z: P/ x
  8.   {9 v6 x/ \/ |: s' _3 x) O* N
  9.   /* Place your implementation of fputc here */
    5 m6 X) {2 _% K8 Q* ]/ s7 I) \" n; k
  10.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */5 @: n4 c* q, r- Y/ K& g9 R
  11.   HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);* Y& F% D( s) b5 t
  12.   return ch;9 x2 [# s. P! h+ o0 J5 I
  13.   }
复制代码

; _6 h# W0 u) p$ [% s  修改工程代码
4 x; ?( ^: I. s/ m, }6 R% C  增加接收 Buffer
& n" K# f3 ~5 W5 m
  main.c6 G# E  s/ `3 E$ z9 @4 e  I
  1.   //Modification 0% Y7 f; v9 `1 f8 L. G7 m7 H
  2.   //Store the revceived bytes number
    : s% J- E6 ^- Q
  3.   uint32_t Rev_Size = 0;
    , U) [0 n" s5 A# _1 ?
  4.   //Receive buffer- S( F" m$ `1 T. \5 `/ Z
  5.   uint8_t UART_RX_Buf[15];
复制代码
; r/ K! r% J5 ?, Q, p. j
  stm32f4xx_hal_uart.c$ X  @0 t( f% }8 o5 C% D
  1.   //Modification 04 [3 @5 M: D/ S. [! i% U' {
  2.   extern uint32_t Rev_Size;
复制代码
4 f; Q' i. ]& b) c
  在接收函数中使能 IDLE 中断2 t# [2 @4 k- v( \  t; |0 A
stm32f4xx_hal_uart.c -> HAL_UART_IRQHandler ()函数* S7 b& q, C1 ~- p
  1. //Modification 26 B) \; I3 |* J7 T8 C! y: p
  2. if(((isrflags & USART_SR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
    1 x. V% V3 O; w$ W4 v- X5 a$ j
  3. {9 w5 g# x2 E9 N8 z  M
  4. //Record the received bytes number
    ; ]$ g. h7 B9 r' m- e; @
  5. Rev_Size = huart->RxXferSize - huart->hdmarx->Instance->NDTR;) b- n  @, U3 t! y/ }, x5 J
  6. //clear the IDLE flag1 Z) {. x2 U/ `0 }
  7. __HAL_UART_CLEAR_IDLEFLAG(huart);
    ; H" ?. j  x0 I. B/ q4 `; Q7 P
  8. //Abord the received process
    2 u6 x$ b; c8 U, @, A4 [. b
  9. HAL_UART_AbortReceive_IT(huart);/ |/ Z( q% r- c) x- K, L
  10. return;
    3 u1 l& D# ?% l' X* D( g
  11. }
复制代码

3 p- \$ I/ x; B" T

( g% [2 E1 N: i8 F接收完成处理(IDLE 产生,一帧数据传输完成)
6 j0 ^5 `' h$ d& Y; istm32f4xx_hal_uart.c -> HAL_UART_AbortReceive_IT ()函数. W2 m! l/ ^3 q% \6 q& W* k
  1. <div>//Modification 3</div><div>CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE| USART_CR1_IDLEIE));</div><div>// CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));</div>
复制代码
* T; U6 N  a7 @' b$ F9 y8 f% D; u
7 s" B: P& b7 x! a
main.c2 v5 l. f5 o: _
  1. <div><div>//Modification 4</div><div>void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart)</div><div>{</div><div> //Print received Bytes</div><div>printf("\n\r[IDLE]Received %d Bytes:",Rev_Size);</div></div><div><div>for(uint16_t i = 0; i < Rev_Size; i++)</div><div>{</div><div>printf(" 0x%02X", UART_RX_Buf[i]);</div><div>}</div><div>//Re-start receiving</div><div>HAL_UART_Receive_DMA(&huart2, UART_RX_Buf, 15);</div><div> /* NOTE : This function should not be modified, when the callback is needed,</div><div> the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.</div><div> */</div><div>}</div></div>
复制代码

- A$ z2 ~) U/ \& a7 @
7 f: x  B$ s0 c5 b, ^
) q; ~4 [2 [" m( m$ v使能接收
* S* s, a5 }, }) F5 e/ _& ]7 umain.c
* K+ y- ^% u1 a
  1. <div>//Modification 5. ‘15’ is the total number to be received. Make sure it can cover the</div><div>longest frame.</div><div> HAL_UART_Receive_DMA(&huart2, UART_RX_Buf, 15);</div>
复制代码

1 I- |/ Y  t5 _- e  g# c
% D4 p7 S& v( R
实验结果
1 m: g$ h0 L, E7 j: j使用串口调试串口,通过 STLINK 的虚拟串口发送数据,MCU 会返回接收多少个字节的数据,并将接收到的数据打印出来。7 }2 S0 ~9 j; W2 T0 H  h( A
下图是发送 0xAA 0x55 的实验结果。/ u- T) x, w3 K

. m  i/ J1 P8 z
8 ]6 H# Z1 V" l, f# S5 p 24I%WL`B_XX29`0L0N}JQ]E.png
' ?* R( o4 g: e8 T/ ^4 x; x: T" _2 F; ?. m1 _; ~
小结
: `3 d( a( g8 G) X, _' CIDLE 作为指示总线空闲状态的中断,合理的使用能够很大程度的节省代码程序设计工作量。这里只是做个简单示范,抛砖引
1 B  g: h8 G- e& h1 D, P* D玉,实际应用中希望大家可以灵活使用满足所需。
3 {% A/ g$ c" A' }3 o& |! l7 c+ D6 U

6 s: E, I. e$ E3 B0 p$ P3 p, s5 |! f
1 G) j( n. _6 x! {0 q( q2 y9 c
收藏 1 评论0 发布时间:2022-2-15 22:07

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版