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

【经验分享】stm32CubeMX+STM32F7串口空闲中断+发送DMA

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:07
1.配置系统下载程序方式
4 |: k( r+ C, T7 w7 G5 Y" t; O5 `$ O* o4 q
20200901143057124.png

- J% w; h+ E5 D5 F& l; b  F! z* V" R/ M# a' K' V
2.RCC外部晶振; y9 U- ?9 |# c# l; Z" i* I6 P
8 `6 Q6 w! B6 _. ?" E# E
20200901143329762.png

" U0 b+ H5 }$ D! p
7 n3 c* U2 y6 l4 V 3.串口声明
7 R" {: [! O$ I* H& g; D
# _  E, [9 b8 C) ?# U& G  ~; r
2020090114343042.png

6 j6 X8 Q5 W& R; Z) c/ z. n& A9 g- h
2 C# t. z' l" v
2020090114350548.png
% q+ s7 b! z# L/ C0 }
% R/ S# M4 p! n; }: N
20200901143544740.png

% a+ ^5 V" Z; m* ]# q  v, t4 E' ^) j6 D4 d* p- H/ |+ P  z8 o0 m
4.系统时钟6 i% s5 l+ }' a. m# S6 u

) e1 t% c9 Z! v! L! K: Q
20200901143654748.png

7 u) L0 c! m3 y9 p1 i- ^& ^7 i
- g6 k- Q" K( v: L- h8 [ 5.生成文件根据自己需求配置
% l" Z' }9 t' C8 u( @7 l
* `4 V2 z! c9 B1 R  y
20200901143817649.png

1 v2 N7 z2 K* M& V2 I
& F& E# I) G9 R 我这设置了所有库,可以选第二个仅需求的
# `6 u; `* y& c
- B/ l& G' R$ m5 K
20200901143845598.png
1 t; y/ [; K  f5 U
% K# i  J8 J. v' X/ x4 I
还加了其他功能,这里可不参考,DMA要放在串口前' _7 Y$ u7 ^2 _, K& c
- x, g2 X* O9 {- w3 O, X* X
20200901144049245.png

: V  H: [* Y- v6 T2 h2 e' s' @# \) v2 `* G5 R6 a
6.生成后修改
( L2 w1 t9 c! G3 s9 [; V- T
  [9 Q9 [9 ~' {. g! ]2 r  [& V6.1 usart.h
: |7 S! e/ r0 C, E9 v# [# I: Z+ ]: A# _. z7 @; V( R* i
  1. /* USER CODE BEGIN Includes */& a5 ?) V4 G1 W5 q2 X
  2. #include "stdio.h"# `1 @7 D) Y' j+ \
  3. #include "string.h"0 E4 P" {( s+ M, M
  4. /* USER CODE END Includes */
复制代码
  1. /* USER CODE BEGIN Private defines */
    " A4 D6 c. f% x7 W9 V
  2. . H7 k" ^& G2 H% V3 K" p* U& ]
  3. #define USART1_DMA_REC_SIE 256! e' g, z' y! O( `# Z. S1 [7 G
  4. #define USART1_REC_SIE 512
    ' N, T% P+ k' @4 s- d
  5. #define USART_DMA_SENDING 1//DMA发送
    # G% @  k( M( ~) J% A$ O+ q
  6. #define USART_DMA_SENDOVER 0//DMA发送结束9 ]) n; N/ N( N0 n* h
  7. typedef struct
    8 I7 X( `7 f" x% I2 i) p5 [, a
  8. {) L2 b. V4 \; d: Z3 k) d; E  _0 J
  9.         uint8_t UsartRecFlag:1;//接收标志3 b" {5 z1 d3 b; |& d
  10.         uint8_t dmaSend_flag;//发送标志- X% e  A0 I$ Z
  11.         uint16_t UsartDMAReclen;//DMA接收长度: g' F4 e2 i" N+ |
  12.         uint16_t UsartReclen;//串口数据缓存长度. c& k- `# Q$ e/ q* |8 Q
  13.         uint8_t Usart1DMARecBuffer[USART1_DMA_REC_SIE];//DMAbuffer缓存数据
    " _  ^- v* t% a8 A
  14.         uint8_t Usart1RecBuffer [USART1_REC_SIE] ;//串口1缓存数据% p# @( J1 }# a7 X, I
  15. }teUsart1type;
    ) q& b" U5 n, N8 ]3 R

  16. 9 f4 F4 }3 C' [0 [7 m- G) [9 b
  17. extern teUsart1type Usart1type;//定义数据  }( ]; r3 w: j( }) [: x& ~
  18. 6 Y" K/ N7 t! P. _: V; R6 D  U
  19. void UsartReceive_IDLE(UART_HandleTypeDef *huart);
    5 X' F1 f: Y8 v# f4 i
  20. void Usart1SendData_DMA1(uint8_t *pdata, uint16_t Length);: t+ c5 ^7 m0 L/ }+ A  r
  21. void Analysis_Serial_Data(void);% q( N+ ~1 m6 M( ]5 R. k# d
  22. void EnableUsart_IT(void);4 @1 s! g+ j8 d" P" d( k$ W) R- s

  23. 9 B8 m% r( H4 g3 c3 Y
  24. /* USER CODE END Private defines */
复制代码
( x3 _9 m4 V7 ~% j
6.2 usart.c,接收为双缓存方式,一般DMA接收放在,DMArec里,若不及时处理,下次接收会丢失,放入usartrec里,可避免,实现处理多少拿多少,dma接收的数据根据处理情况放入相应位置。
8 @4 _' D1 }6 K
# `& c! \7 i, Y
  1. teUsart1type Usart1type;
    7 G; z* g/ B. s# Z1 o
  2. /*****************************************************************************
    7 P0 Y" x, ~& n0 s% W% u
  3. * 函 数 名  : EnableUsart_IT
    9 i7 j% y5 U7 F
  4. * 负 责 人  : by6 ~  K4 E: A& s
  5. * 创建日期  : 2020年8月26日
    & |0 V9 I$ m' l4 ?& u# J
  6. * 函数功能  : 串口2初始化函数,空闲与DMA中断( m- Z$ T- d1 x3 z! b/ k
  7. * 输入参数  : 无2 `( |- m# s# }: n8 @* l0 ?+ Z
  8. * 输出参数  : 无
    + u+ g: K; K, V% C0 N
  9. * 返 回 值  :
    6 W$ l1 A+ A* `4 k/ d
  10. * 调用关系  : , @  M$ R* a/ ~! a7 e0 Z' e
  11. * 其    它  :   
    ! R4 t6 R/ ]* ?# E
  12. *****************************************************************************// j6 f) M) K0 O! r; e5 c
  13. void EnableUsart_IT(void)
    5 D) j& N3 D1 L! ^
  14. {   ) u3 @5 t& p! i3 c
  15.     __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); // 开启串口2 空闲接收中断6 d, q: G6 J' ~1 b* u: i9 x5 e: g
  16.                 HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//DMA中断
    " _7 \# B  O! T6 H: @
  17. }
    . a, v; g) {0 B$ }6 d6 h- F
  18. /*****************************************************************************5 p2 H# ^0 |( E- |) h+ Y
  19. * 函 数 名  : Usart1SendData_DMA5 P1 V) w" a) J7 t
  20. * 负 责 人  : by) y4 F) v3 A6 w" a
  21. * 创建日期  : 2020年8月26日
    . ~4 W6 ]7 L- T) w/ [$ n. z
  22. * 函数功能  : 串口2DMA发送函数3 q) ~8 K# A3 u0 V2 e: W
  23. * 输入参数  : 无+ I& z- j- R' z1 J, n3 ?+ i
  24. * 输出参数  : 无
    ! ]' g/ Y5 r) C# e; |9 ^( |
  25. * 返 回 值  :
    . A( T% O  _# b  E4 J, {) L
  26. * 调用关系  :
    9 _- C8 @8 Q6 B, I
  27. * 其    它  :   0 Y1 q, i4 x" g4 `
  28. *****************************************************************************/
    * Z, c3 t# ^  v1 v
  29. void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)  ' t2 o+ p/ |3 N# ], {1 o1 S9 \; U  @
  30. $ w. V% m/ v# j. ~4 _- q3 a
  31. {  . M2 r1 H+ W8 b% B# w. ]* q
  32.         //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  
    - g' x% x  e( f& m+ r" h/ n- X( k
  33.         Usart1type.dmaSend_flag = USART_DMA_SENDING;  6 s9 l4 |! n- S8 v7 N8 e
  34.         HAL_UART_Transmit_DMA(&huart2, pdata, Length);  
    4 o, d1 h& v5 S2 a& @8 x
  35. }  
    4 D$ E, I* P2 p' j# X( Z
  36. /*****************************************************************************3 o4 T. @1 M5 u* l9 @% ~
  37. * 函 数 名  : HAL_UART_TxCpltCallback
    & q' o) ?' @1 e8 e
  38. * 负 责 人  : by/ o. Z$ v. U- \2 C
  39. * 创建日期  : 2020年8月26日0 t: i' `- o% Z% ?. V6 [$ J
  40. * 函数功能  : 串口2DMA发送回调函数
    8 m% D' p9 ^6 O" Z( D. ]
  41. * 输入参数  : 无& \$ [6 ^/ R; f; p  `3 a
  42. * 输出参数  : 无
    + X! F* l1 {2 q* X( \% h
  43. * 返 回 值  : + Y! \2 P# c+ j8 x
  44. * 调用关系  : # @6 l4 X% [, q# a' H7 l% \: ~/ q/ t
  45. * 其    它  :   
    1 s' ~5 S7 k  a! @3 @+ s: w1 @
  46. *****************************************************************************/. [4 [- N1 P7 F, ^
  47. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)  8 x/ a( ~! j9 T/ x1 X" Q7 C! X5 X
  48. {  
    3 s6 M3 v& G% m3 M+ {: T/ O
  49.     __HAL_DMA_DISABLE(huart->hdmatx); ! q  u* n% Z2 j1 `/ V
  50.     if(huart->Instance == huart2.Instance)        
    9 g. F# x0 n' K
  51.     Usart1type.dmaSend_flag = USART_DMA_SENDOVER;  " P2 a9 Z; F/ s
  52. }  
    5 K! O2 D7 E$ i3 ~: w
  53. /*****************************************************************************% ]0 n8 N0 M9 r* H. J  D3 _$ g
  54. * 函 数 名  : UsartReceive_IDLE7 U* i! L" h$ z! e, s: A
  55. * 负 责 人  : by1 Z0 }7 v8 Z0 [# o- U1 K
  56. * 创建日期  : 2020年8月27日
    6 U' c) U) i, U5 s; U% @& K' X' s
  57. * 函数功能  : 串口接受空闲中断处理函数8 J! R1 M, n# _. b
  58. * 输入参数  : UART_HandleTypeDef *huart  串口句柄$ G$ T% c6 P, V; K/ d
  59. * 输出参数  : 无, [% w6 D- m1 H9 L% E  W% v
  60. * 返 回 值  : " D- X) o0 d% T* I
  61. * 调用关系  :DMA接收的数据缓存在USART接收中,释放DMA继续接收 6 h$ F+ K7 {5 h8 }+ f8 K
  62. * 其    它  :
    * J; l3 ^5 t& z. @
  63. *****************************************************************************/& Y9 Z& g5 r: a: \7 l
  64. void UsartReceive_IDLE(UART_HandleTypeDef *huart)
    ! x% v7 U" B3 x; c  w
  65. {
    5 b: Q1 x) ^: U! C8 z9 ^
  66.         if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
    8 _7 Z( f9 H& Q, h4 S- F/ X8 t( |8 M
  67.         {
    , U# M0 s6 Q9 Q( [% t. n" D$ _: ?7 P
  68.               if(huart->Instance == huart2.Instance)//判断是否为串口2" S/ j9 t) t8 @, s
  69.                 {
    ) f9 y! _0 i* i& l* O9 q
  70.                  if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))   //是否为空闲中断0 h; O# z) ~! ?# A! o
  71.                    {5 b( ?. ]. G0 k: {6 m4 T6 O
  72.                    __HAL_UART_CLEAR_IDLEFLAG(&huart2);                     //清除空闲中断
      ]/ o/ {1 J7 m+ E, \! p
  73.                    HAL_UART_DMAStop(&huart2);                                                     //停止本次DMA传输
    ' I) B; ~' C% Y( W
  74.             Usart1type.UsartDMAReclen  = USART1_DMA_REC_SIE - huart2.hdmarx->Instance->NDTR;   //计算本次传输数据长度8 U; I2 M' @& ~$ e6 G
  75.                                                 if(Usart1type.UsartReclen>0)4 ^9 F3 J% A- [  X
  76.                                                  {  l" t0 y# [! L) r: u* d
  77.                                                         memcpy(&Usart1type.Usart1RecBuffer[Usart1type.UsartReclen], Usart1type.Usart1DMARecBuffer, Usart1type.UsartDMAReclen);  c. \4 V, u# E/ P: ]
  78.                                                         Usart1type.UsartReclen+=Usart1type.UsartDMAReclen;% S7 Q5 y. X0 a) w+ a  ~
  79.                                                  } 6 F! x' W+ q6 |0 ^9 A: [& s& ~
  80.                                                 else if(Usart1type.UsartReclen>USART1_REC_SIE)//如果串口接收数据溢出,从0开始记录
    3 ]6 R* M( ~6 X& s! E
  81.                                                  {% U/ H7 W9 N; t8 J4 c  v2 P
  82.                                                          Usart1type.UsartReclen=0;
    : n. V, D7 E9 U0 J
  83.                                                  }
    7 [3 v2 ?- J# ^! B- O  m, O& L. ^
  84.                                                 else
    $ j! s0 f* M3 e# Q. q
  85.                                                  {. U( i/ c+ n3 q& ?
  86.                                                         memcpy(Usart1type.Usart1RecBuffer, Usart1type.Usart1DMARecBuffer,Usart1type.UsartDMAReclen);& M1 h) }, h& a& ^
  87.                                                         Usart1type.UsartReclen=Usart1type.UsartDMAReclen;
    9 n* c- x9 f1 }& V, o
  88.                                                  }                                       
    ( l, |0 J; G# h7 e5 ]* p
  89.                                                 memset(Usart1type.Usart1DMARecBuffer, 0x00, sizeof(Usart1type.Usart1DMARecBuffer ));//DMA数据清零                                                                                , c# A- I. }; e/ d; ]
  90.                                                 Usart1type.UsartRecFlag=1;//空闲标志位置1: n% q4 `. R: |
  91.                         HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//重新打开DMA; C9 P  Y! c' {' H' n1 w
  92.                                         }                1 e" ]4 y, E& d; ?3 T! T- K
  93.                   }% N: [5 M: {* t; n8 b
  94.         }
    + q: z4 \, t& D0 H% K1 r6 c6 E
  95. }
    ) H1 L( K8 |! i# z7 Z) J
  96. /*****************************************************************************
    ) i8 {7 o- s8 a/ h" T
  97. * 函 数 名  : Analysis_Serial_Data' R, c; O/ r- e
  98. * 负 责 人  : by' F: k& V5 n* K  J& Y
  99. * 创建日期  : 2020年8月26日
    : X% I3 N" C' N# e  g% h
  100. * 函数功能  : 串口接收数据直接打印
    + \* m! h! I; L: p, b6 g% w( O; f
  101. * 输入参数  : void  无2 V- M* t2 Q) @! M& T) J  k
  102. * 输出参数  : 无+ l0 l3 l5 f- a) V6 Y
  103. * 返 回 值  : void- L5 i+ k; C# V, K; t" \  _/ ^
  104. * 调用关系  :
    . O" r5 _1 s2 z9 J
  105. * 其    它  :
    1 K2 C% R( T% P- O# C
  106. *****************************************************************************/
    / o8 z6 U, i& J: l' m2 Z
  107. void Analysis_Serial_Data(void)
    " {6 ^# [% V; ^4 ~7 T. i( `' H5 L
  108. {
    5 }5 k  A3 y& ~2 S
  109.                  if(Usart1type.UsartRecFlag): F. _0 A( m3 `2 J# ?% V' W
  110.                  {                                 
    . F( ^; ]$ h" B
  111.                          Usart1SendData_DMA(Usart1type.Usart1RecBuffer,Usart1type.UsartReclen);        
    1 Y- P: P1 S' x2 ~4 h8 [, }
  112.                          Usart1type.UsartRecFlag=0;" H' w! M( d: H3 A$ s/ A
  113.                          Usart1type.UsartReclen=0;//测试处理为将全部数据进行打印处理,若需解析,可将解析长度进行减少,多次处理         
    ' c$ h' P. ^+ I; E6 k
  114.                  }
    6 p& {8 Q. g0 k/ |. z
  115. }, S; w: X; ~& O/ u% }4 v" Z
  116. /*****************************************************************************+ U6 h9 N; r: Q- @" P3 Z$ n: d
  117. * 函 数 名  : fputc- ~- O7 n& \! Q7 c3 L, C
  118. * 负 责 人  : by+ Y" f) K! S7 _2 o, `, e
  119. * 创建日期  : 2020年8月26日
    / H/ N: @' M5 C# f
  120. * 函数功能  : 串口2 printf重定义# j' R/ E, Z6 v; h7 M4 @" I$ B
  121. * 输入参数  : printf(d%/s%/%c,a)
    4 }: h% ~" Z3 s1 `. @
  122. * 输出参数  : 无
    ' D' w4 |- U5 c6 w
  123. * 返 回 值  :
    - N1 q3 m/ s4 ^& {& s3 g# f
  124. * 调用关系  : ( O, n# V( V% K/ _
  125. * 其    它  :   
    ' p, `+ p- X$ `% W# o  {% c
  126. *****************************************************************************/
    ! d9 k# }* \# `6 q
  127. #ifdef __GNUC__
    6 G# |2 [7 S' s. ]* m# ^
  128. * o5 m- o" Z& a/ U; [+ S
  129.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    6 t8 b6 l8 R" J0 p8 S5 L+ t& \3 L
  130. set to 'Yes') calls __io_putchar() */
    ; X& \# `7 U- d9 J7 q0 f
  131. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)) n% W' [: N4 Z+ z% Z  a
  132. #else" d; i$ G9 k* I: v2 T0 C

  133. + B4 c, }; G- L) M: h# M; m
  134.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    2 J+ v  E: P4 x! Z3 l  J
  135. #endif /* __GNUC__ */& [" |! T0 P' [/ \. E, p; o! o
  136.         ; z# w( w) g6 q  R( E6 ]1 W' w, P
  137. PUTCHAR_PROTOTYPE+ s( t$ u; n" X, G: r7 `% _
  138. {
    6 W- r. ^4 ^+ @. F) t5 r$ A( |
  139.         HAL_UART_Transmit(&huart2,(uint8_t *)&ch, 1, 0xFFFF);
    . q( X) W, }# H, W' r" r/ j4 |2 a: d
  140.         return ch;
    ) L4 F/ h/ b4 L# ?3 @/ W9 n
  141. }$ A; N& w4 j+ ]. h
  142. 8 {1 V/ S1 x) i0 `7 G+ ?5 {
  143. : K8 i. L# Z5 g, x* G5 h
  144. /* USER CODE END 1 */, z, u1 G. E% p3 k& l) H$ t
  145. DMA发送函数,网上给的教程while是用来保证DMA收发节奏的,节奏错误会出现死循环情况,给注释掉了。。。。
    " @7 h* W3 e3 [0 |% [& w$ T
  146. ! N% \$ B1 [+ S' ^
  147. //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  
    / h% ?9 ^1 @, y4 T5 d: ~+ o
  148.     Usart1type.dmaSend_flag = USART_DMA_SENDING;
复制代码

/ x: k' r0 k0 D" E5 X; k7 e# z9 e; V; p- u4 n
6.3  主函数,只用DMA通讯只需添加EnableUsart_IT();/*串口初始化*/,即可,对应usart.c里的函数
  1.   /* USER CODE BEGIN 2 */
      f( S) q9 q/ H# r
  2.   HAL_TIM_Base_Start_IT(&htim3);/*使能定时器3中断***/
    ; ]5 F$ Y' `4 \9 ^
  3.   HAL_TIM_Base_Start_IT(&htim2);/*使能定时器2中断*/7 f/ U$ g- E' N( h
  4.   HAL_CAN_Start(&hcan1);/*can初始化*/
    7 s- Y2 v) \8 e
  5.   HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);                        
    7 @- P6 ?" D3 Z% W, H0 _0 [$ O. Y
  6.   EnableUsart_IT();/*串口初始化*/
    % S, t7 j# ?& }+ {
  7.   CAN_User_Init(&hcan1);        
    * E3 f4 U0 T0 }$ N5 [8 _
  8.   /* USER CODE END 2 */
复制代码
" ^6 G$ a5 R+ s
循环,对应数据输出
; s" U# Y' B7 X+ u8 c# |: t7 `: f( M' D8 q0 ^: t" q
  1. /* USER CODE BEGIN WHILE */" e2 M: |. {! ~1 l4 ]
  2.   while (1)# ~% @" m7 ?' t9 a+ I- A& f3 a& j( d0 ?
  3.   {                9 [; _2 i5 H* H# t2 b2 ]% i7 l9 g
  4.      Analysis_Serial_Data();: V: t5 k( K8 l7 r
  5.     /* USER CODE END WHILE */. i- V5 F& w6 J8 W

  6. 3 W, W0 `) Y+ z1 R8 `* [3 M4 q
  7.     /* USER CODE BEGIN 3 */
    $ ]9 q# p8 T& ~9 B+ t
  8.   }& W) P: ~' L& _
  9.   /* USER CODE END 3 */8 {3 d7 D$ I; Y1 ^3 Y
  10. }- _% Q$ P1 X! C8 d, H
  11. 7
复制代码

2 X! g+ T8 R  R( u9 b( E6 g& ~、实验结果,间隔10ms,连续发送,未出现丢帧,或其他错误
! d; f- z  h* h5 t
4 |# Q% N. i. J  U, n/ T
2020090115084313.png

, w+ s4 ^* r- l- Q
* q  O1 _( ]. [2 ^0 V4 V( y& E1 Y0 ^9 B3 G% `
收藏 评论0 发布时间:2021-12-14 10:07

举报

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