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

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

[复制链接]
STMCU小助手 发布时间:2022-2-15 22:07
前言- j. U8 V: G3 ^$ U: t
在串口通信应用中,我们常使用接受和发送中断,相信大家都不陌生。这里有个非常有用的中断可能被大家所忽略,即总线IDLE 中断。当一帧数据传输结束之后,总线会维持高电平状态,此时,就可以触发 MCU 的 IDLE 中断。在本文中,将介绍使用该中断来进行不定长串口数据接收的办法。通过该中断,可以省却很多用于检测数据传输是否完成的判断动作。- N8 X, [: G5 j, M0 H/ M  q
实验环境
; m: e6 `* F9 m9 o   STM32F411RE-NUCLEO7 G# [# G% N$ _7 O  L
   STM32CubeMX3 U2 B9 p4 Z( G: l
/ I$ a0 }, ?: _$ O4 f5 k
总线状态分析
- A) \0 m/ A: s3 B9 }下图是发送 0xAA 0x55 的所抓取到的波形。从图中我们可以看到在发送该帧之前和之后,数据线处于 IDLE 的状态。在该帧中,字节与字节之间,没有 IDLE 状态出现,即不会出现 IDLE 误触发的情况。0 f4 a5 A' t5 A! _0 O
4 q7 ^8 ]1 u/ Q. t; b  z
G_YB)_J~CWYDHOKQS]P0.png # U2 H; `: J/ G4 _- b2 ?: ?- \' E5 m

3 S( q2 q( U% N* g: b不定长数据接收
+ s5 Y* c, T# }! D4 T本次制作的工程是基于 HAL 库。在原生的 HAL 库中,并没有集成 IDLE 中断的处理。所以,在本文我们介绍的方法中,需要修改一些库文件来实现。/ z  `" D* M& z: W2 C
2 V) R6 M! o) n( {
使用 STM32CubeMX 生成实验工程
& F" a! T: W# g) K7 N) j工程的配置如下图:) |* S( o8 q8 e0 M( c
1. 系统始终配置为 100MHz
2 n+ Y; n! i- z2. 配置 USART2 为 Asynchrones,管脚配置为 PA2,PA3。
5 u) X7 w; i7 b3. USART2 参数:9600Bits/s, 8bits, None,1Stop
7 E/ a0 C, F/ p& F# l! E( e7 S/ U# V- ?
{NA4%H92Q97)J{D5LUGEWAE.png
$ t9 @7 T/ [! V* m2 q0 H
6 |; \) a' T6 i0 M为了方便打印接收到的相关信息,需要对生成的工程做如下修改来映射 print 函数。
' Z. _$ L( ^- _+ Fmain.c-声明
- R( ]; U8 z$ ]+ o" K- k5 c$ W. i
  1. #ifdef __GNUC__
    ' G& K* n* U  g) m, y
  2. /* With GCC, small printf (option LD Linker->Libraries->Small printf
    / u, C3 [7 d# r
  3. set to 'Yes') calls __io_putchar() */# ~7 n' ^% j0 M, e1 w$ H* T$ }/ z
  4. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    2 z# M' }# y1 k
  5. #else" u! M. S( X! T: t
  6. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    4 L$ P0 C- v: }0 y6 m8 V: [
  7. #endif /* __GNUC__ */
复制代码
$ L6 m' D6 W; F3 j2 p

- s# M. R) L; w3 G# j1 @main.c-Code3 N+ U& S. M+ j. V( k
  1. /**5 J! ?! [* @+ D, @6 P

  2. 5 T6 ~% z2 N6 Y: Z; r; b% `
  3. * @brief Retargets the C library printf function to the USART.
    + @, @1 ]. F- p( H/ F( H
  4. * @param None
    ' J; M. Q. O; G# c2 h+ P
  5. * @retval None! B5 W' z+ T8 }3 H' Y* V# m3 C
  6.   */9 O/ G6 o* p; P  V: j2 H3 [
  7.   PUTCHAR_PROTOTYPE
    1 B7 }+ D5 m' i$ M" C+ Q9 D
  8.   {
    ; W4 A5 V! l! W8 Y+ E' k; M0 ?
  9.   /* Place your implementation of fputc here */& t+ c9 o* @. }( p0 F
  10.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */) N; O4 M+ a: x6 H) i
  11.   HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);9 i0 a! e9 Z7 G2 i' y: I
  12.   return ch;& y4 I5 q/ L+ n- I- I. W! }
  13.   }
复制代码

5 l6 [! G" F8 ~! Q) u% l" M  修改工程代码/ ]  Y( L! w0 ~* d/ Z& o
  增加接收 Buffer
/ f! f8 `7 O9 s+ B- I" h
  main.c0 Z$ }" J; `) i$ d; D1 G; m# w
  1.   //Modification 0/ P, z: r9 s: @! i2 l8 x$ Z: Y
  2.   //Store the revceived bytes number7 c3 B, N  J& S
  3.   uint32_t Rev_Size = 0;
    * t8 K8 l! v$ e6 o- a3 a# ^; }
  4.   //Receive buffer
    ( q  k% V4 j6 D7 F9 x
  5.   uint8_t UART_RX_Buf[15];
复制代码
1 S+ d% G& j* S1 l  C4 P4 w
  stm32f4xx_hal_uart.c+ R. h+ }( E7 Q/ _5 n6 @
  1.   //Modification 0
    + D# H9 E* Z6 Z1 o& a  f+ i
  2.   extern uint32_t Rev_Size;
复制代码

. O% I8 i: V$ _9 d( W' b/ o4 R( l  在接收函数中使能 IDLE 中断7 V* e: w3 J# T) ~2 w) D5 w9 L1 q
stm32f4xx_hal_uart.c -> HAL_UART_IRQHandler ()函数) E/ b2 k7 l* A% y" T9 I% O2 A% Q' R
  1. //Modification 2
    ! P. ~5 v9 W1 w) U& U! J5 `+ O
  2. if(((isrflags & USART_SR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))8 W  v% ?& v1 b+ I7 z7 ~0 i
  3. {
    7 c7 d  M- \! k) }8 K+ k
  4. //Record the received bytes number! j  n3 ?, |7 s7 g, r/ W; J8 I
  5. Rev_Size = huart->RxXferSize - huart->hdmarx->Instance->NDTR;+ T6 Z1 {9 f( y4 Y- q
  6. //clear the IDLE flag
    $ d9 W1 g, m7 G( G3 N" t: u
  7. __HAL_UART_CLEAR_IDLEFLAG(huart);
    $ H! ]' P1 b( _. O6 O
  8. //Abord the received process
    " |" |) O' E5 O2 \. E  Y. b
  9. HAL_UART_AbortReceive_IT(huart);* U; I! _3 Z$ s) f! A
  10. return;7 l" t4 a% E/ }; A5 i
  11. }
复制代码
2 V$ A. d0 {. c& h  e! Z7 g0 K
% H( _( o/ I' _& S% U1 w- J/ i6 F
接收完成处理(IDLE 产生,一帧数据传输完成)# b( ?2 B" [, f: Z
stm32f4xx_hal_uart.c -> HAL_UART_AbortReceive_IT ()函数  z* Q0 j9 n/ k1 t) n) z
  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>
复制代码
; w" E: r9 H8 }/ P- _( u( x7 V
. G7 Q& A! ^  s3 B* H) d
main.c# E" m2 X2 ?5 ~1 y  L" |
  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>
复制代码

, J3 x5 y: x9 V( \; N" c# d. y! ]5 k+ H

" I* _+ r4 }3 [6 j' M使能接收. _5 J" _0 H4 A7 K
main.c9 E, ~2 D' p2 U
  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>
复制代码
+ V) p" t3 s' C# j

; [, z! S8 e2 H  K0 i实验结果
8 E3 y# S: C6 e* V: I" h使用串口调试串口,通过 STLINK 的虚拟串口发送数据,MCU 会返回接收多少个字节的数据,并将接收到的数据打印出来。
9 s8 m8 f0 ~7 T& p下图是发送 0xAA 0x55 的实验结果。
( ], \$ K, t* u0 A* X5 k$ t6 B
) d" l$ G3 D/ f1 e$ X/ @( E
  j. D/ d# e6 k7 J 24I%WL`B_XX29`0L0N}JQ]E.png 6 X5 \( b% v5 b2 M

5 a0 n5 p  [. ?! N/ x1 C! h' E1 p小结" }" H; ^+ Y' ]( O) q  V
IDLE 作为指示总线空闲状态的中断,合理的使用能够很大程度的节省代码程序设计工作量。这里只是做个简单示范,抛砖引
% a# B3 _2 `1 j玉,实际应用中希望大家可以灵活使用满足所需。
/ R6 g" z+ z  H" r" k& f
4 M) c. G* G5 Y
: O3 f) U; \. P. `& N3 y% E6 F8 X4 _& B8 R* B# M
收藏 1 评论0 发布时间:2022-2-15 22:07

举报

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