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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:07
1.配置系统下载程序方式
% |/ Q' x! d; Z7 j! J
) [3 A" z8 a: X+ W
20200901143057124.png
! A! C% ?2 I6 M, z! w/ c

3 k  A0 |: n* U! S5 O# e3 g( ? 2.RCC外部晶振
: d0 M" s. B4 M, G
+ p+ f' \  V2 l
20200901143329762.png
$ G& Z2 _9 q! _) K4 o
+ q* E; H/ c* o5 X" e1 w
3.串口声明( _* s! A% o$ E

; \5 w8 y4 v, H5 h* @; }2 g6 n
2020090114343042.png
+ e3 g' p  c* S# G

; m. [( F8 R( q' k+ a: V
2020090114350548.png
) y' W, J6 U) i9 S+ n

! k& o  [' `3 \* |' h3 l$ I- E
20200901143544740.png
  g7 r' H) |& Z) g
- x  O' M( a8 Z0 i: a
4.系统时钟+ o% ]& C, J! m( R" X) z
1 }3 h% ~5 W4 [: b
20200901143654748.png

' K( ]+ p! w6 U" S% J6 j
; Z, q0 }8 ~, v$ v8 d0 r+ ?/ v; C 5.生成文件根据自己需求配置
, C' {5 [8 a3 I) |; i, E0 O* ^  w& B0 q9 _" L) S2 M4 M
20200901143817649.png
; c2 g- B9 k9 V- c
! y( }4 S) A1 U4 J2 h
我这设置了所有库,可以选第二个仅需求的7 e1 k6 ?: m. C) \4 T0 h
  f5 i+ H) \: ^) y
20200901143845598.png

% B! ~" B. \: g# N4 e
; x3 z; Q" J8 z' {7 z# |; d 还加了其他功能,这里可不参考,DMA要放在串口前/ z( \* C  X1 H+ M

( C6 `& J' g1 h. Y. n# y0 n( R5 F) p
20200901144049245.png
- A; `& ~* l! {( |8 G& t5 z
- ]0 w% z# F, E
6.生成后修改4 }; G2 F: [1 S; l
+ H" B; N0 [$ o7 x7 T" @
6.1 usart.h
7 ~2 m# h4 K0 ]; k/ D5 [3 X+ E
2 S! L1 D5 R- j$ E# h: {
  1. /* USER CODE BEGIN Includes */
    7 K; ?5 C2 o2 d# J) a$ C
  2. #include "stdio.h": ]! h0 V0 g8 f# C- d% E
  3. #include "string.h"
    ( j0 T" C. b0 B$ R  Y4 D
  4. /* USER CODE END Includes */
复制代码
  1. /* USER CODE BEGIN Private defines */
    5 t* H& O. y" K/ t

  2. ; e0 @* f7 Z7 a6 M+ E1 a
  3. #define USART1_DMA_REC_SIE 256- A* B/ B! t: W
  4. #define USART1_REC_SIE 512$ W$ x" R5 N; C5 f1 c
  5. #define USART_DMA_SENDING 1//DMA发送
    5 s% N2 T' C' ~' m: r/ y! i
  6. #define USART_DMA_SENDOVER 0//DMA发送结束
    + b/ r6 L( v* b, o1 J
  7. typedef struct- x- j* ?- a0 n
  8. {
    9 {5 @- _* t% [5 p$ s! ]( @
  9.         uint8_t UsartRecFlag:1;//接收标志
    7 V3 m9 D+ A9 I% s9 h: M
  10.         uint8_t dmaSend_flag;//发送标志
    ) f1 T0 q2 n& ^) T! [
  11.         uint16_t UsartDMAReclen;//DMA接收长度3 }- S7 U" n8 [. o5 S; ]  _+ k
  12.         uint16_t UsartReclen;//串口数据缓存长度
      Z7 D2 D1 o; {: Y, n0 z1 X9 k
  13.         uint8_t Usart1DMARecBuffer[USART1_DMA_REC_SIE];//DMAbuffer缓存数据
    ! k! G" X( y' Q
  14.         uint8_t Usart1RecBuffer [USART1_REC_SIE] ;//串口1缓存数据
    5 L) m: b: i+ V9 H  o7 K# y
  15. }teUsart1type;! \; c: a  `5 Z" K& I( n! d1 `
  16. ! b2 ^1 {5 u/ F
  17. extern teUsart1type Usart1type;//定义数据
      R6 }5 a3 V, E. X

  18. , L. U/ G( Y$ P1 |
  19. void UsartReceive_IDLE(UART_HandleTypeDef *huart);
    6 g. T9 j& D0 U# O) d, U
  20. void Usart1SendData_DMA1(uint8_t *pdata, uint16_t Length);* U& A6 G0 }9 P  C, F' z
  21. void Analysis_Serial_Data(void);1 z) e! \  f) s1 \8 w5 N* x
  22. void EnableUsart_IT(void);9 Q1 I2 t0 _% k& R1 [! Q0 D4 a& S( p

  23. : `* N9 ^1 G+ t. \; q: q! t
  24. /* USER CODE END Private defines */
复制代码

2 f* y% C4 g' G, i6.2 usart.c,接收为双缓存方式,一般DMA接收放在,DMArec里,若不及时处理,下次接收会丢失,放入usartrec里,可避免,实现处理多少拿多少,dma接收的数据根据处理情况放入相应位置。( r. V. W3 {( c: ]: Q
* M3 P2 a+ v5 }
  1. teUsart1type Usart1type;
    + z4 A* p( q& O# o0 q3 L. ]- b0 x, e
  2. /*****************************************************************************
    , h1 }$ u- h8 j8 p% g- M9 S: v; ]
  3. * 函 数 名  : EnableUsart_IT  W) Z0 t" [+ O- s! X& d4 b3 W
  4. * 负 责 人  : by
    / f3 Y- ~: p9 Q7 }
  5. * 创建日期  : 2020年8月26日
    ) _5 r/ P$ {6 S( d7 q
  6. * 函数功能  : 串口2初始化函数,空闲与DMA中断
    7 E4 ]5 y1 G9 U' R; Q2 s
  7. * 输入参数  : 无
    3 F( {+ n" \: T3 }
  8. * 输出参数  : 无
    * X( F9 a3 O2 t7 U) W
  9. * 返 回 值  : # R' a6 Z- |% @0 d/ q' M) c) ^
  10. * 调用关系  :
    ' R% B" z/ ?5 W" L! m9 p" Y
  11. * 其    它  :   3 a9 u) S$ R  F5 o! G5 t
  12. *****************************************************************************/
    . L) m7 {; ^- O$ F1 W& F
  13. void EnableUsart_IT(void)9 {6 s0 \$ s8 `# ^' g+ X. O0 w
  14. {   
    ; [  v0 l4 g3 ^% n1 N
  15.     __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); // 开启串口2 空闲接收中断2 }" j, J, R: @+ D8 B1 I2 f
  16.                 HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//DMA中断8 D2 c% X$ F7 O
  17. }
    7 R7 _4 X- C, R) M; F9 O, q
  18. /*****************************************************************************
    7 Q' N7 J8 R+ i1 J  [9 F
  19. * 函 数 名  : Usart1SendData_DMA
    ' G5 y" S# }( S; y/ L
  20. * 负 责 人  : by2 w. \: E$ e5 r6 K1 _3 E# L
  21. * 创建日期  : 2020年8月26日
      J# d8 {1 v8 x- i- `
  22. * 函数功能  : 串口2DMA发送函数
    ; i  y- V0 |7 w6 i5 j) m# ~  @
  23. * 输入参数  : 无. h9 p2 s6 ?% {  R! f# }, x* V
  24. * 输出参数  : 无, z* ^8 q) f/ Z, i# f6 i
  25. * 返 回 值  : 1 i3 B8 o! i- _/ a/ w$ X- R4 C$ l0 ^
  26. * 调用关系  :
    / V4 z. A& Y1 p1 a/ q6 k
  27. * 其    它  :   
    # f7 V+ A2 p  W4 U" T
  28. *****************************************************************************/
      W3 [( F7 C' |/ v4 l& Z
  29. void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)  # D) ~5 T0 i. m. z1 z' B5 b
  30. ( {# B8 i* r$ P% F" n( ]4 Z
  31. {  
    / I  @7 m. E$ j0 a
  32.         //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  7 K8 U) k/ B( ?
  33.         Usart1type.dmaSend_flag = USART_DMA_SENDING;  . K# |7 L: Y( k2 v) J; K( X
  34.         HAL_UART_Transmit_DMA(&huart2, pdata, Length);  9 O# i! W% a3 I4 c$ [5 c5 y, g
  35. }  * q0 }* }/ S$ X0 }: }* j1 O
  36. /*****************************************************************************; B/ }% {( o1 y/ x2 g
  37. * 函 数 名  : HAL_UART_TxCpltCallback6 M, i  T* {! T
  38. * 负 责 人  : by
    8 ]# K! y* \& U; C" M& U
  39. * 创建日期  : 2020年8月26日
    . ]3 D  M+ i( s7 b
  40. * 函数功能  : 串口2DMA发送回调函数
    6 I8 j* u2 _9 \) ~4 {
  41. * 输入参数  : 无
    # }# v" e! o" d# U7 B( j
  42. * 输出参数  : 无
    . Q/ E% l1 ^5 {* t' [8 O, ~
  43. * 返 回 值  : 2 t4 |" p3 o) E- L7 u
  44. * 调用关系  : 0 f- C2 Z! J8 \1 @4 F5 A! ^# N
  45. * 其    它  :   # z; ^4 l2 l8 c  B  B
  46. *****************************************************************************/
    4 C! u! N4 {2 i4 H
  47. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)  
    " ~8 [; \" V  i9 d) ]  p! Z
  48. {  % n# \1 b3 |5 f$ T( M% r
  49.     __HAL_DMA_DISABLE(huart->hdmatx); 6 W. g) B; j  K) N$ c
  50.     if(huart->Instance == huart2.Instance)        
    8 J; k8 I7 f! r( F4 ^! k
  51.     Usart1type.dmaSend_flag = USART_DMA_SENDOVER;  
    ) R. p1 B  E, f" P
  52. }  
    ( M# R6 ]# I7 R# _3 T
  53. /*****************************************************************************
    3 R0 i6 c! X, Q: T
  54. * 函 数 名  : UsartReceive_IDLE
    3 r* k# L0 r* C% h" y
  55. * 负 责 人  : by
    " D. S: Y, v  n8 g8 u# O0 x/ O
  56. * 创建日期  : 2020年8月27日6 X3 |  W9 k& e& ?6 e- G  R
  57. * 函数功能  : 串口接受空闲中断处理函数
    7 X+ U' I( q8 q/ |/ U4 P
  58. * 输入参数  : UART_HandleTypeDef *huart  串口句柄0 p' N2 D8 d, {0 p
  59. * 输出参数  : 无+ \5 m" f' `$ K9 I0 Y
  60. * 返 回 值  : - b# R6 X  X* V: v- h* I5 |
  61. * 调用关系  :DMA接收的数据缓存在USART接收中,释放DMA继续接收 ; Z5 P1 k! z/ z8 l7 F& U! c$ d7 d
  62. * 其    它  :
    0 \$ p/ D" ~" B/ @% a  [
  63. *****************************************************************************/
    " F& q- h; R; y
  64. void UsartReceive_IDLE(UART_HandleTypeDef *huart)  d& L' \# `1 X& t4 ~) }
  65. {
    & V' h! ^' q. D1 D7 Z2 W! \0 J
  66.         if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))/ [, e7 C& q$ S' i+ B
  67.         { 9 H. q; p8 b: Q! ^( D
  68.               if(huart->Instance == huart2.Instance)//判断是否为串口2! `, g1 w; R0 O: X
  69.                 {* f4 e; r$ i, ]* F7 N# @
  70.                  if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))   //是否为空闲中断& n0 V8 M9 _2 M$ I0 ~# R
  71.                    {
    7 y& H0 w4 s& d* f
  72.                    __HAL_UART_CLEAR_IDLEFLAG(&huart2);                     //清除空闲中断
    6 ?& J7 r& r6 u! T5 ^: H  N
  73.                    HAL_UART_DMAStop(&huart2);                                                     //停止本次DMA传输
    . v5 L4 |4 B/ S7 e. n! t
  74.             Usart1type.UsartDMAReclen  = USART1_DMA_REC_SIE - huart2.hdmarx->Instance->NDTR;   //计算本次传输数据长度
    ( p, W3 F9 h% `! s( N
  75.                                                 if(Usart1type.UsartReclen>0)( Q( t/ q3 N' R" Z4 U
  76.                                                  {
      e" X, U: i. x8 d! e2 }) ?
  77.                                                         memcpy(&Usart1type.Usart1RecBuffer[Usart1type.UsartReclen], Usart1type.Usart1DMARecBuffer, Usart1type.UsartDMAReclen);# z' F: T7 E  q5 p: s
  78.                                                         Usart1type.UsartReclen+=Usart1type.UsartDMAReclen;
    6 M+ ^$ X5 j# X2 t2 R
  79.                                                  }
    2 ]6 x4 |4 i( D  {0 D
  80.                                                 else if(Usart1type.UsartReclen>USART1_REC_SIE)//如果串口接收数据溢出,从0开始记录5 s4 L& g4 A4 Y4 N
  81.                                                  {( m! J; Y) d. @- {! v. E2 L) v
  82.                                                          Usart1type.UsartReclen=0;
    6 s2 F8 V. o( a
  83.                                                  }
    # M1 d" j/ v! I
  84.                                                 else+ d" _% G  v- ^' C: ?
  85.                                                  {
    6 l* U, I3 j8 ]
  86.                                                         memcpy(Usart1type.Usart1RecBuffer, Usart1type.Usart1DMARecBuffer,Usart1type.UsartDMAReclen);0 M# B) g8 J: s& x4 s) `
  87.                                                         Usart1type.UsartReclen=Usart1type.UsartDMAReclen;
    3 w8 \: {% g8 c. \$ Y/ x
  88.                                                  }                                       
    : \8 C% {; i$ V. ?* C5 Z5 }+ [$ {& d
  89.                                                 memset(Usart1type.Usart1DMARecBuffer, 0x00, sizeof(Usart1type.Usart1DMARecBuffer ));//DMA数据清零                                                                                4 ?; v9 \+ T2 F
  90.                                                 Usart1type.UsartRecFlag=1;//空闲标志位置1; d" Y4 {& A' M- Q6 f
  91.                         HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//重新打开DMA
    ' G8 P& \; f2 F' C$ o5 A
  92.                                         }               
    ! W$ ~  X: ~- h8 _1 ]3 N4 j
  93.                   }5 w0 P& q' W8 z& X, r
  94.         }& u, Q( s1 H4 A9 _: Y
  95. }( T  S  Q. }. |. y
  96. /*****************************************************************************
    5 y  ]; A% R( @
  97. * 函 数 名  : Analysis_Serial_Data
    9 J/ I7 v2 l6 B: T
  98. * 负 责 人  : by
    % N: f6 T$ ~8 O1 F/ e2 ?
  99. * 创建日期  : 2020年8月26日
    * S$ z- i  a' c
  100. * 函数功能  : 串口接收数据直接打印  L2 s% |" i3 |3 y7 D8 N5 F# _- a+ t
  101. * 输入参数  : void  无
    ! o- i/ j: ?6 y6 [% }
  102. * 输出参数  : 无$ t" I, I' h/ @5 Q) X
  103. * 返 回 值  : void
    # A( G" U( S7 K( ?& Q4 x
  104. * 调用关系  : , z3 p9 U! c. l0 m
  105. * 其    它  :
    3 k0 V8 d  f  ^5 J: o/ g6 r0 V4 g' g
  106. *****************************************************************************/
    / k6 y9 S% b# H0 }, N
  107. void Analysis_Serial_Data(void)
    4 c8 L& Z' f( M* |# Z/ Z$ I% _
  108. {$ X8 U" o4 ~, i1 J
  109.                  if(Usart1type.UsartRecFlag)8 ?( E7 b# B: e
  110.                  {                                 
    % d/ a/ H6 _2 T0 m2 E$ r
  111.                          Usart1SendData_DMA(Usart1type.Usart1RecBuffer,Usart1type.UsartReclen);          \0 u0 ?) k6 d9 R5 n) m0 a
  112.                          Usart1type.UsartRecFlag=0;
    . Q6 \/ @4 m) d
  113.                          Usart1type.UsartReclen=0;//测试处理为将全部数据进行打印处理,若需解析,可将解析长度进行减少,多次处理         % [( h3 U: C9 k) F" L
  114.                  }0 ]; R  D, {6 x6 @( D
  115. }
    $ a  L$ `1 W' w. @$ |; a& ?
  116. /*****************************************************************************
    ! N5 _7 O$ f& Z& t
  117. * 函 数 名  : fputc
    : c* y9 {. I0 b4 Q) X! J. x: z- y
  118. * 负 责 人  : by8 |) p- D3 U. N/ {. K
  119. * 创建日期  : 2020年8月26日
    ( C- {$ }6 `& R& c- d
  120. * 函数功能  : 串口2 printf重定义
    * y* ]# V  e. u; k' a
  121. * 输入参数  : printf(d%/s%/%c,a)
    1 i& j6 X/ T# z) w2 r  s% b" ]
  122. * 输出参数  : 无  r0 d4 v8 W; ^7 Z9 O9 B3 g7 v- c
  123. * 返 回 值  :
    # S' P% o, a7 R9 _7 G
  124. * 调用关系  : ! D8 N4 t$ ], H
  125. * 其    它  :   5 {! r" T; b" M, d5 }6 k1 }
  126. *****************************************************************************/, M. ?6 C! z) M8 @: |+ I; W: g- i
  127. #ifdef __GNUC__+ E; j" }6 h( T2 ?! y7 t0 A

  128. 2 g) F% c- Y! G
  129.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    8 \# r  S& [% C7 {. ?; |  Q& U
  130. set to 'Yes') calls __io_putchar() */
    4 k+ ^+ z% D* J; O( N' B' M9 t
  131. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    8 E3 d5 n) N4 t: @
  132. #else
    + c! k" g3 V3 e

  133. 9 m5 Y0 k- D& A9 A) ~
  134.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    ' c9 g9 o9 Q" {2 a8 K3 N6 c
  135. #endif /* __GNUC__ */$ J" v- ^$ q8 m3 X6 a- T- ~
  136.         ; k+ ~: L$ U8 Y
  137. PUTCHAR_PROTOTYPE
    4 W8 \; I. K0 b
  138. {, B" p! R& I6 h" I
  139.         HAL_UART_Transmit(&huart2,(uint8_t *)&ch, 1, 0xFFFF);' j' X- t- _1 T: I: f" r# K
  140.         return ch;( j8 n% l: V! [' f  {) z- K
  141. }
    + j4 q) q) H0 A4 m; ]9 {8 c: e

  142. 7 E1 w' V" L# ^  U2 T0 ^/ g
  143. 4 e3 t! |; j; Y3 J, m/ Z
  144. /* USER CODE END 1 */
    0 W4 g0 I& e2 _. O* P; L0 Z% w" @8 I
  145. DMA发送函数,网上给的教程while是用来保证DMA收发节奏的,节奏错误会出现死循环情况,给注释掉了。。。。" _0 P7 X$ q, G/ `# B" S: o
  146. 8 V; ~+ W. G5 ]/ P: `9 H/ G2 _
  147. //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  
    / S; b3 q" W$ ^! P
  148.     Usart1type.dmaSend_flag = USART_DMA_SENDING;
复制代码
- f7 }* s% f6 |2 N. `
6 b. q9 }) x4 {/ I. c
6.3  主函数,只用DMA通讯只需添加EnableUsart_IT();/*串口初始化*/,即可,对应usart.c里的函数
  1.   /* USER CODE BEGIN 2 */6 f, J: q3 I0 B% t1 O7 N# M
  2.   HAL_TIM_Base_Start_IT(&htim3);/*使能定时器3中断***/
    1 P. E  r+ D0 ?  I3 e  m
  3.   HAL_TIM_Base_Start_IT(&htim2);/*使能定时器2中断*/0 }9 ]# c% ~# c9 W; ^! G6 X+ {- s9 C
  4.   HAL_CAN_Start(&hcan1);/*can初始化*/; i% e7 ?  b! a8 }" P7 I. P
  5.   HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);                        
    7 t2 [! I+ @3 }" \8 k
  6.   EnableUsart_IT();/*串口初始化*/
    ! z' o1 H$ u7 [5 ?" D+ y0 m
  7.   CAN_User_Init(&hcan1);        
    + u" K0 O! N% `3 R: p) N# f6 ?4 h
  8.   /* USER CODE END 2 */
复制代码

+ z- S1 @, P6 ~2 v 循环,对应数据输出& u$ r( N, @. Y) N( {9 F9 @

. ^1 a* l: o* d' Q$ @' J' Z
  1. /* USER CODE BEGIN WHILE */
    4 [& d2 w; `5 o; H; _7 X. }
  2.   while (1)
    6 Q% Y/ [, N/ M1 J  x
  3.   {               
    & u0 ^3 i' R3 `( _5 j/ u7 f
  4.      Analysis_Serial_Data();
    3 e2 v" }9 q; o) T2 g
  5.     /* USER CODE END WHILE */
    + ]7 J7 x3 d. H% h) k# |- |( [1 C- `
  6. & O6 y5 n; i% l2 y: N
  7.     /* USER CODE BEGIN 3 */
    5 Z  S, c3 d) C% z: \: `
  8.   }" v% x! [8 R8 m$ Q
  9.   /* USER CODE END 3 */
    6 x7 x0 w% `/ c/ x" B3 @! [
  10. }
    % ~# }0 j$ o9 d# P
  11. 7
复制代码

  E5 }3 p1 u0 H" g0 I$ M" C" ?、实验结果,间隔10ms,连续发送,未出现丢帧,或其他错误# h2 v1 d- p% y
- j. \0 n3 h/ ^
2020090115084313.png

5 _* H+ }- t* }; l: b% P1 q7 k$ O5 k% H( Q

% F. s) S5 _. I2 N# B) T3 x
收藏 评论0 发布时间:2021-12-14 10:07

举报

0个回答

所属标签

相似技术帖

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