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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:07
1.配置系统下载程序方式
# s% ^  M. Q% X# i! i" _. l* _+ D, c5 t
20200901143057124.png
6 H5 \- }3 k0 O; s' d
$ j1 j' k9 ]& L8 }( [5 s
2.RCC外部晶振- _7 Z) ]& l) Z
% J) G  U4 o- B. A/ \6 Q" G  ^7 ?9 j
20200901143329762.png
. d7 I3 t+ i9 ^  z
/ E9 F) D+ A8 R. t* Q" A
3.串口声明
. }. l0 f& u- Y# `/ m. A/ n. P) B7 W/ g. \& t' t  ^8 M
2020090114343042.png

3 w( _& S; P3 F
" L8 a/ \( T$ L% w& w+ K1 R  A  e+ e9 m
2020090114350548.png
/ C7 h0 W# w4 T% G% I6 x) w

( z" L. K) x( a% r6 F) y
20200901143544740.png
: w, x" z  {; f! v+ j

& _. y8 X5 a) P5 |4.系统时钟
" R1 E/ U9 `- W/ D( V3 l% n8 F) \& _) B) @
20200901143654748.png
4 q8 L/ q$ f& {0 D
% w" P7 V6 m( v$ s
5.生成文件根据自己需求配置9 J9 o; {( g' v

' P3 F! a7 F2 ^: a" H, O  g
20200901143817649.png
+ U5 ?& x2 l6 E* r! |% l$ O
* t+ g- j: M, B) S, F# d$ V
我这设置了所有库,可以选第二个仅需求的0 _, Z* o3 y  x. i2 V* s7 n

/ o' w! p8 O5 f( W6 s. o) m% v; I3 e* D
20200901143845598.png
  c! R; l  k0 T) o; e9 o1 ~. c

+ {6 n' t0 S: Y$ ` 还加了其他功能,这里可不参考,DMA要放在串口前
' T7 G/ Y. t! h
2 ?1 l0 t+ d$ j/ c
20200901144049245.png

' e  O) }* u% Y. M. k: _8 \* A5 J8 z- N; r  j- f1 s
6.生成后修改* _5 A6 ]* ^, h$ x2 q% t$ Q
7 _7 Y1 O# H  P; B+ S8 S
6.1 usart.h
4 @; ^6 H+ `8 n& h4 C; r; b, x7 `; C& S7 g- S% P4 R6 E8 T  ?
  1. /* USER CODE BEGIN Includes */* U3 j7 s: _& Z" j& B  j
  2. #include "stdio.h"
    / d* Q1 j: g" ?7 v6 b4 b) f7 N. ~
  3. #include "string.h"
    . E6 w- O; j6 Q6 I
  4. /* USER CODE END Includes */
复制代码
  1. /* USER CODE BEGIN Private defines *// {# D6 B8 @5 @: C, a7 e/ ^) G. R

  2. ! e# K4 i% z& i& o
  3. #define USART1_DMA_REC_SIE 256; _) V* ]7 m. ^3 c
  4. #define USART1_REC_SIE 512
    9 w8 M! D; f1 P& Y' X9 T. R, M
  5. #define USART_DMA_SENDING 1//DMA发送
    ( O! j6 W) K1 d' X& m8 M4 z: D. b
  6. #define USART_DMA_SENDOVER 0//DMA发送结束
    : F) B: h. R& `% L7 c9 s
  7. typedef struct5 |& y6 k+ n% v& m% k
  8. {& m, ^# H' S& g/ b
  9.         uint8_t UsartRecFlag:1;//接收标志
    & L$ t2 M' v) x3 m0 n
  10.         uint8_t dmaSend_flag;//发送标志
    . b# `& @' U, Q- ?, G* K* d
  11.         uint16_t UsartDMAReclen;//DMA接收长度
    0 `! M0 U- o% i! L; T/ F0 t
  12.         uint16_t UsartReclen;//串口数据缓存长度
    ( S/ d: {# n. L8 G. W2 n$ z
  13.         uint8_t Usart1DMARecBuffer[USART1_DMA_REC_SIE];//DMAbuffer缓存数据
    . ^' D7 i( G) v
  14.         uint8_t Usart1RecBuffer [USART1_REC_SIE] ;//串口1缓存数据' s/ y2 e7 R' t, C, I' e
  15. }teUsart1type;
    3 w1 n4 ^7 V, N

  16. # B9 Q8 r- H, c* j
  17. extern teUsart1type Usart1type;//定义数据
    $ Q: m6 C* P8 L& \' l9 B
  18. . Q$ c. j+ C# e. E
  19. void UsartReceive_IDLE(UART_HandleTypeDef *huart);( l. C- l6 z3 F' b
  20. void Usart1SendData_DMA1(uint8_t *pdata, uint16_t Length);/ B; v6 p& {8 d! I! ^/ J4 n
  21. void Analysis_Serial_Data(void);
    8 {2 M7 m8 A  z
  22. void EnableUsart_IT(void);  m( v6 j: ?: V8 [( G

  23. ! ~3 b$ a9 s: o! M. p
  24. /* USER CODE END Private defines */
复制代码

; V: h6 [6 n: J9 t* t7 @5 O4 z+ D: B6.2 usart.c,接收为双缓存方式,一般DMA接收放在,DMArec里,若不及时处理,下次接收会丢失,放入usartrec里,可避免,实现处理多少拿多少,dma接收的数据根据处理情况放入相应位置。$ E4 n' i" k1 j* x
# N/ t2 c2 P4 E
  1. teUsart1type Usart1type;, h* o: C: y4 u: A3 D
  2. /*****************************************************************************% j0 T5 T4 d" x( k
  3. * 函 数 名  : EnableUsart_IT
    " f1 q" ~8 V4 g4 L* M! y6 K
  4. * 负 责 人  : by2 f. L) U' }: ]' ?: |: ^
  5. * 创建日期  : 2020年8月26日3 P( n! {% V& |; D0 `
  6. * 函数功能  : 串口2初始化函数,空闲与DMA中断
    4 W# k" x9 w" d; y, d
  7. * 输入参数  : 无! k' ]1 |+ o1 U7 A2 Y
  8. * 输出参数  : 无
    . M( ?2 }% c  e8 @! l5 J. ^" S& p
  9. * 返 回 值  : 1 w" F- I! u, {. p/ S
  10. * 调用关系  : # N/ C* Y6 G/ n, D5 X& s8 n; Q4 n, k( J
  11. * 其    它  :   
    8 i6 x* \. r: ]
  12. *****************************************************************************/
    ; w0 a2 h, K# i
  13. void EnableUsart_IT(void)0 W. q& ?! N5 X: ]2 X6 G
  14. {   
    ; p! U( T0 h, o
  15.     __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); // 开启串口2 空闲接收中断8 G- Y+ g  a* l' }  b% K
  16.                 HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//DMA中断
    ! w1 a. a* f) [) A4 K
  17. }
    ( ^. B8 q+ J; f$ B1 m. w
  18. /*****************************************************************************
    " N8 [9 L4 z+ h/ e) d+ O
  19. * 函 数 名  : Usart1SendData_DMA
    8 w0 u" B" K7 Q; C9 T; a
  20. * 负 责 人  : by
    ' I! ~) @. O: e3 G' i+ ]" U' H8 [
  21. * 创建日期  : 2020年8月26日
    $ ^4 L6 \8 l" p  M
  22. * 函数功能  : 串口2DMA发送函数' u/ @" t; A$ |- T8 w4 T
  23. * 输入参数  : 无
    $ \, Y1 J0 k; [
  24. * 输出参数  : 无
    & K' N* C* R6 |5 w/ Y! D  Z
  25. * 返 回 值  :
    7 s3 w7 Y7 q% [& e
  26. * 调用关系  : : w2 M$ w" p# I7 x5 ?
  27. * 其    它  :   # D6 l3 z! J1 p9 \/ O
  28. *****************************************************************************/* K$ G! Z7 r& E: V2 x
  29. void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)  
    7 k: s2 {" `' U9 B5 R( ^' w

  30. 1 i- S2 @% B0 \4 c. [: i+ l
  31. {  
    $ r' @3 o, @1 d4 P
  32.         //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  ( t, t( Z  D4 n# ^: A2 D+ m
  33.         Usart1type.dmaSend_flag = USART_DMA_SENDING;  
    # C, U) }7 }* U* a* z, s
  34.         HAL_UART_Transmit_DMA(&huart2, pdata, Length);  
      \/ P5 t' b3 R8 L3 R
  35. }  
    $ |8 F! B9 N/ A5 \1 ~6 }6 {
  36. /*****************************************************************************+ j  r- s, R! h2 ~/ R
  37. * 函 数 名  : HAL_UART_TxCpltCallback4 G8 O- [* A% J* [% {0 W$ `. M
  38. * 负 责 人  : by5 q/ u) |. i- v7 O8 N& o: e) c: ]% N
  39. * 创建日期  : 2020年8月26日  l; E$ r4 w5 _9 I
  40. * 函数功能  : 串口2DMA发送回调函数, d! ?% K' ~5 E: _. v# g( G
  41. * 输入参数  : 无
    0 o. |7 V" G& P  h" a
  42. * 输出参数  : 无' b# f5 U" z$ |5 P7 I
  43. * 返 回 值  :
    / i- W" E" M" i9 F( L+ Q
  44. * 调用关系  : $ s) Y' P6 M% ~  p7 C+ U
  45. * 其    它  :   " }9 Q- I1 H( _3 V
  46. *****************************************************************************/3 `* @# W! k' c, \
  47. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)  
    , _. B$ b7 e4 X1 a! _. c; Z
  48. {  
    , [4 i8 S" U( K% S) e, \
  49.     __HAL_DMA_DISABLE(huart->hdmatx);
    2 j  R# r7 L% H/ n
  50.     if(huart->Instance == huart2.Instance)        " f( p" T+ x+ ~  u$ R. ?5 V
  51.     Usart1type.dmaSend_flag = USART_DMA_SENDOVER;  
    7 |: U  S0 _6 `- Q. N% R
  52. }  
    ; M2 J' _( L( L& M
  53. /*****************************************************************************+ f' l+ {( }; V# w: t8 ?
  54. * 函 数 名  : UsartReceive_IDLE
    + c! b0 \- E" \  s& p( Q
  55. * 负 责 人  : by9 J6 l4 ?2 j1 @8 R
  56. * 创建日期  : 2020年8月27日; ~  Q2 [2 ~- N- Q6 a. Q; n+ A
  57. * 函数功能  : 串口接受空闲中断处理函数, \# z$ v% h  V4 ]
  58. * 输入参数  : UART_HandleTypeDef *huart  串口句柄, V9 z% a6 p" _0 Y1 }
  59. * 输出参数  : 无; a( E7 I5 f* @1 m8 B, \
  60. * 返 回 值  :
    0 Q0 C4 W  x+ _  U3 g. g8 s: M* N
  61. * 调用关系  :DMA接收的数据缓存在USART接收中,释放DMA继续接收 8 s7 B5 x' \* p/ }# g0 D
  62. * 其    它  :
    % @4 n  y/ D. @, g' J
  63. *****************************************************************************/
      @9 Q7 a" P0 F7 w3 y* U+ j" @; x: s3 j
  64. void UsartReceive_IDLE(UART_HandleTypeDef *huart)
    " ?. e( J, {5 P3 U0 n
  65. {
    $ z: X4 E8 d1 [* Q% D
  66.         if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
    0 I: h' S; X2 T: d: p. s
  67.         { # A; r- U6 d" Y$ m. i0 ~+ p: L, ~/ S
  68.               if(huart->Instance == huart2.Instance)//判断是否为串口2
    3 K7 m) h. o$ U0 L- E5 g7 K* x
  69.                 {0 j/ C" p1 q: b$ G+ S- w  v
  70.                  if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))   //是否为空闲中断
    $ o2 c& W  H/ ]" b! }
  71.                    {
    $ }( l6 ]' g: R1 n
  72.                    __HAL_UART_CLEAR_IDLEFLAG(&huart2);                     //清除空闲中断. s% v. U7 ]7 A; }% _5 a3 b
  73.                    HAL_UART_DMAStop(&huart2);                                                     //停止本次DMA传输
    ( s1 U7 [% z$ P
  74.             Usart1type.UsartDMAReclen  = USART1_DMA_REC_SIE - huart2.hdmarx->Instance->NDTR;   //计算本次传输数据长度& X" \6 m2 }) Q! ?- H, f
  75.                                                 if(Usart1type.UsartReclen>0)
    4 H8 Q7 E- A' l
  76.                                                  {& [& q- _5 S4 x/ f$ I% ^
  77.                                                         memcpy(&Usart1type.Usart1RecBuffer[Usart1type.UsartReclen], Usart1type.Usart1DMARecBuffer, Usart1type.UsartDMAReclen);- z; R2 a8 o2 ]( T( ^1 S
  78.                                                         Usart1type.UsartReclen+=Usart1type.UsartDMAReclen;8 |- o  H! A( o' @2 Z8 Z* R. z
  79.                                                  } - C/ T. h3 \' r9 I1 C& |. y
  80.                                                 else if(Usart1type.UsartReclen>USART1_REC_SIE)//如果串口接收数据溢出,从0开始记录
    3 S; \; n* N/ j. [- P/ F
  81.                                                  {! [& t' o0 Q! W
  82.                                                          Usart1type.UsartReclen=0;) C( q& B" @$ F  l2 \$ f
  83.                                                  }2 s! r6 m7 {7 R6 T  ]6 f7 _, w
  84.                                                 else
    ) Y+ m# s7 t3 N, C+ r
  85.                                                  {
    2 n+ |; _$ G! s, x, w1 D. y( ~9 {
  86.                                                         memcpy(Usart1type.Usart1RecBuffer, Usart1type.Usart1DMARecBuffer,Usart1type.UsartDMAReclen);
    1 z6 T# P# ^! m: [9 T
  87.                                                         Usart1type.UsartReclen=Usart1type.UsartDMAReclen;
    - s, ?, k' T- X8 V6 Y% L+ X5 l
  88.                                                  }                                       
    4 D, h9 {# m3 @2 A" z. e
  89.                                                 memset(Usart1type.Usart1DMARecBuffer, 0x00, sizeof(Usart1type.Usart1DMARecBuffer ));//DMA数据清零                                                                                & o9 j" B% R+ \- m6 V; a  G8 ]
  90.                                                 Usart1type.UsartRecFlag=1;//空闲标志位置12 l2 I  |3 l8 w9 }7 T6 S$ p" b
  91.                         HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//重新打开DMA" [) Y, d/ M( O9 y
  92.                                         }                + v5 C! Z9 [, Y0 @3 h8 L3 w) ]- u8 m
  93.                   }
    0 r: p/ ~" d7 L% ]* [+ L- K  q9 }( S
  94.         }" R8 Z9 ?0 W" f* i, o  a' @/ ], l
  95. }+ Q# T+ v# P( b% G
  96. /****************************************************************************** l$ C! W4 K2 Q, c+ Z4 K$ v4 U" k
  97. * 函 数 名  : Analysis_Serial_Data
      @  J" A6 c, \0 T9 g' y
  98. * 负 责 人  : by" s/ h, C; e5 ]! ?7 S- z0 U0 L. q! }
  99. * 创建日期  : 2020年8月26日$ X2 m& ]! f6 L  A4 j2 p) W. B! X
  100. * 函数功能  : 串口接收数据直接打印6 H; j( |  B+ Q4 D* A0 y. t
  101. * 输入参数  : void  无
    ! B- g. d1 S& _8 [
  102. * 输出参数  : 无
    " v- a$ d! @% C& ?# t# Y
  103. * 返 回 值  : void' j5 m1 U: ?- ^# X9 v
  104. * 调用关系  :
    : ^: I$ F. \2 Q0 [8 Z; j
  105. * 其    它  :
    : B" K, X: B' w  j% D( k
  106. *****************************************************************************/; `( f5 L. ~8 O# c4 @% s# ]
  107. void Analysis_Serial_Data(void)- ~3 g( J/ p2 a) H. i& d% ?
  108. {
    " u6 O( I8 a$ D" i4 m( W0 J
  109.                  if(Usart1type.UsartRecFlag)
    # O4 K- }1 ^, d8 r) }% f$ X' v
  110.                  {                                 
    , Y2 I/ Z  j: o8 y7 o- q6 O6 |( ~! g
  111.                          Usart1SendData_DMA(Usart1type.Usart1RecBuffer,Usart1type.UsartReclen);        
    1 f0 U) p4 j) t3 L' w: K+ r0 ]
  112.                          Usart1type.UsartRecFlag=0;& p9 Y, ~( G% m5 B* E- m
  113.                          Usart1type.UsartReclen=0;//测试处理为将全部数据进行打印处理,若需解析,可将解析长度进行减少,多次处理         
    : K) ?+ B9 g4 {
  114.                  }
    : R8 M$ f  j6 r' m
  115. }
    8 B/ `# y* l9 r. x5 C! h/ m% d4 @' S; V+ s
  116. /*****************************************************************************
    + p, U! U: O& J/ H3 P& i" x0 [+ f
  117. * 函 数 名  : fputc3 S; _" I7 e6 w6 h
  118. * 负 责 人  : by5 j! G2 s0 n  g
  119. * 创建日期  : 2020年8月26日
    3 t- A+ o2 l7 e' k- S, U9 N7 F
  120. * 函数功能  : 串口2 printf重定义
    + }9 Z* b, n" g% F" p
  121. * 输入参数  : printf(d%/s%/%c,a)
    - x! s' I2 V* h9 X
  122. * 输出参数  : 无
    $ W4 E1 O/ M: x2 Y
  123. * 返 回 值  :
    $ |" L* E& ]# D, V3 D6 p: \
  124. * 调用关系  :
    1 p2 h" B7 B  T2 ~: @
  125. * 其    它  :   8 X6 Z. L' Z6 a0 ^
  126. *****************************************************************************/) B! ~8 M/ b5 t3 d" k3 ?$ z9 \4 l
  127. #ifdef __GNUC__  m) U- ?6 u8 b* E2 S
  128. , b9 L" i" O2 c
  129.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    % l$ [: x0 v: ?0 q
  130. set to 'Yes') calls __io_putchar() */  L5 W0 x7 W) v8 s- \$ ]
  131. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch). A; Y: b: h/ a
  132. #else
    8 F2 @4 s2 N4 f, `

  133. : w6 e2 c2 d& l8 e+ v& T4 C
  134.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)! q/ @( G6 T; y! j0 ?/ p
  135. #endif /* __GNUC__ */! b; D9 m, Y5 v+ ?+ F# \  V! b  \
  136.         & y( \' G+ W. z) A) \; P- f. @
  137. PUTCHAR_PROTOTYPE
    $ D  P" Y; ^9 u; R- @2 M' W
  138. {3 V  m% W6 P% ]1 L. }; K. t) E) W
  139.         HAL_UART_Transmit(&huart2,(uint8_t *)&ch, 1, 0xFFFF);; X) I* O! `2 Y3 H0 b: I% C
  140.         return ch;+ E3 j8 i6 }7 `; K- K
  141. }( u. ^, r2 f3 x# U% J

  142. 6 o* [& Q" `! g; L6 c

  143. 3 k3 i% p( Y4 k
  144. /* USER CODE END 1 */
    0 C2 u# S6 i3 b8 R) E
  145. DMA发送函数,网上给的教程while是用来保证DMA收发节奏的,节奏错误会出现死循环情况,给注释掉了。。。。
    0 ]/ c/ W: ?$ v8 N1 b% e' V2 R

  146. ) e5 c$ Q9 S% F3 A. Z
  147. //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  
    0 Q# i" E- |1 U1 ?
  148.     Usart1type.dmaSend_flag = USART_DMA_SENDING;
复制代码

* K7 a( S5 H! R0 R; X- G
1 K2 P% \% y$ k+ n: Y& E  z" F- w6.3  主函数,只用DMA通讯只需添加EnableUsart_IT();/*串口初始化*/,即可,对应usart.c里的函数
  1.   /* USER CODE BEGIN 2 */
    " h% X& S+ H& S, Y  p, P) k' V/ v
  2.   HAL_TIM_Base_Start_IT(&htim3);/*使能定时器3中断***/1 G; ~& ~1 m# B- H7 w, Q+ |
  3.   HAL_TIM_Base_Start_IT(&htim2);/*使能定时器2中断*/; S, T2 j  c7 v
  4.   HAL_CAN_Start(&hcan1);/*can初始化*/
    # ]: K# n+ R- i  N5 e* ]
  5.   HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);                        2 q. _7 A% t5 ~2 b
  6.   EnableUsart_IT();/*串口初始化*/6 [! X; D; S4 k; k$ G$ o% w
  7.   CAN_User_Init(&hcan1);        
    4 i) _" A0 p0 l, g
  8.   /* USER CODE END 2 */
复制代码

& O) @4 _8 b- F# k( u 循环,对应数据输出: L8 L7 |; X( v$ g7 O5 |
8 J! n6 l. c( t, Z) m' K& H. j- _( }
  1. /* USER CODE BEGIN WHILE */
    5 u! `: w$ A2 p) M/ N1 r
  2.   while (1)! K5 T9 D# v& m* q& M2 V5 e
  3.   {               
    . a8 q! r6 B* O& ~; z
  4.      Analysis_Serial_Data();+ o" A; e0 U1 d$ {! x# k
  5.     /* USER CODE END WHILE */0 |$ M* ?. l: P

  6. ; c! f1 B- {" W: Q3 Y6 F2 u
  7.     /* USER CODE BEGIN 3 */
    7 R9 V- k* Q. O7 ?
  8.   }& A! y- l9 K# x& f. i
  9.   /* USER CODE END 3 */: `' ~: }+ W& e. J3 k
  10. }
    8 K6 J, h8 [# K
  11. 7
复制代码

8 t) r' n1 a. h、实验结果,间隔10ms,连续发送,未出现丢帧,或其他错误& p$ w( q8 e% W# ^* t# i

5 }) U! E6 _5 f6 M1 t
2020090115084313.png

: h7 y* F4 {# r  z) u( E1 A3 f! Y& F# A1 i2 t
5 I! {4 Y2 {9 b8 p8 I" l, l
收藏 评论0 发布时间:2021-12-14 10:07

举报

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