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

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

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:07
1.配置系统下载程序方式
  G2 D& l6 B6 r7 `1 n3 ~
# F+ T3 D) K: j! U
20200901143057124.png

' D; O7 X% |+ X# m, c
0 Q! L1 p9 f, J0 n1 j 2.RCC外部晶振: K; B7 p+ d4 E9 G
& V( O! Q) ~% {( G
20200901143329762.png
& [) o; i* M- t8 w

8 z  @" J8 P4 F6 ~6 t$ b 3.串口声明2 R0 r7 B% W) @+ w
3 r7 k- s- m+ B4 [
2020090114343042.png
4 p; W+ u- H7 L" K
! J4 |( Q3 I1 U4 G1 j) ]
2020090114350548.png

3 f; Q0 X7 h/ s! S. q
5 O7 y; _8 Z' [/ Q, z4 y% R
20200901143544740.png

$ p# _: R7 P. B$ H  e2 X/ \; h7 t+ p3 `, ?$ F
4.系统时钟% V' ^  O# ~. g& T4 X% T
! V8 b! u1 L  \% J6 P
20200901143654748.png

' V) [! ?) y0 C" n8 u# Q3 O
& v; m6 q, ?3 F$ K 5.生成文件根据自己需求配置
) u. V' a& L8 }- o. W7 X: _6 T4 ]; \- E
20200901143817649.png

3 a6 j' k1 f  e- k0 g; c# D. K) G) x, q! U/ w
我这设置了所有库,可以选第二个仅需求的2 Z" H; K# o; Q% w% U( x

6 ~5 l/ `& h5 d6 G! B) k
20200901143845598.png
: v- a! Y0 A! p

$ D- n* ~0 k( L8 R 还加了其他功能,这里可不参考,DMA要放在串口前+ W0 r$ Q& W; w+ T: u6 L
8 G& E. j* `. P( e/ X. c; |
20200901144049245.png
0 L: a& g+ \: R2 l" k/ {1 T

8 [+ a9 p% ?9 E/ W: M& m+ O$ k8 V6.生成后修改( B/ }$ e- l$ u

2 Q  b( ]! {( L1 k2 k# E: y6.1 usart.h
, v. A( g& c* ~' j- }+ B- p6 y4 \3 A, J% I, z' V* V+ f
  1. /* USER CODE BEGIN Includes */
    * Q8 S9 `, E( E6 {7 t& s8 {
  2. #include "stdio.h"
    8 j* p  y* N$ L9 w5 a; w6 D$ ^' o
  3. #include "string.h"/ S8 |1 S, i) k: a2 Z! S, I
  4. /* USER CODE END Includes */
复制代码
  1. /* USER CODE BEGIN Private defines */
    ! T$ n$ b3 s$ H

  2. % E. \; c+ |  s4 Y, i( f. I0 R
  3. #define USART1_DMA_REC_SIE 256
    # P: m# s; @/ E1 S. i0 \
  4. #define USART1_REC_SIE 512
    . \4 q+ D8 E5 M) x& ?' r7 I
  5. #define USART_DMA_SENDING 1//DMA发送 ; ]4 O: Y- p2 u0 I, j
  6. #define USART_DMA_SENDOVER 0//DMA发送结束' L) G7 Y2 u5 {3 J4 o7 L% S
  7. typedef struct
    2 c; V, F5 s# j* {/ s* f
  8. {# b% f9 }  p5 g% `
  9.         uint8_t UsartRecFlag:1;//接收标志
    6 N$ S0 i& j: W( b
  10.         uint8_t dmaSend_flag;//发送标志  M0 |' M* h5 h
  11.         uint16_t UsartDMAReclen;//DMA接收长度7 }# P. f& T" a5 A
  12.         uint16_t UsartReclen;//串口数据缓存长度2 {( b; t" b5 Y) f, [# l+ I
  13.         uint8_t Usart1DMARecBuffer[USART1_DMA_REC_SIE];//DMAbuffer缓存数据' I; s  J' w& `2 [4 t4 @% Q
  14.         uint8_t Usart1RecBuffer [USART1_REC_SIE] ;//串口1缓存数据# y4 l! g* l7 f
  15. }teUsart1type;
    - b- K' C# m0 ]% ?/ @  N9 a. b

  16. ; ^* D! P0 S3 E1 z
  17. extern teUsart1type Usart1type;//定义数据5 F5 A( ?$ j$ ?6 `1 P/ t8 y7 N+ ~
  18. ( H0 z* C3 s( z9 {# D: B
  19. void UsartReceive_IDLE(UART_HandleTypeDef *huart);
    * J7 \& h, L7 F/ ~- ?' {" _! U3 W& L
  20. void Usart1SendData_DMA1(uint8_t *pdata, uint16_t Length);
    # i' t' j+ h) X: Q1 J( k2 C/ l* j3 U
  21. void Analysis_Serial_Data(void);
    " t" E6 |2 I+ ~  ?9 U' `
  22. void EnableUsart_IT(void);: {; A$ s/ g/ H9 c" t* u5 `! F

  23. 3 f% ]. y. O* ~& @
  24. /* USER CODE END Private defines */
复制代码

! k. \, X. ?* {6 \1 k/ T6.2 usart.c,接收为双缓存方式,一般DMA接收放在,DMArec里,若不及时处理,下次接收会丢失,放入usartrec里,可避免,实现处理多少拿多少,dma接收的数据根据处理情况放入相应位置。5 J. _) @2 P  i3 @* t2 i' x
7 Y; K! |. m( B" m$ C- C. M
  1. teUsart1type Usart1type;
    $ s0 `7 Y6 y; U2 [7 f3 S
  2. /*****************************************************************************
    , Y! L) |( Y1 i9 v: \* G! t* B
  3. * 函 数 名  : EnableUsart_IT3 }* c  p! q6 U$ v0 ]3 a5 j
  4. * 负 责 人  : by
    - V) h1 e2 F! \) z7 H
  5. * 创建日期  : 2020年8月26日# ~- R' F+ c% m! K+ d3 ~
  6. * 函数功能  : 串口2初始化函数,空闲与DMA中断
    - B- L; l) u. B, l
  7. * 输入参数  : 无# @9 x3 L6 I. d% W& g* \- H
  8. * 输出参数  : 无6 x2 T: [. s2 |8 t( b8 S4 t) y
  9. * 返 回 值  :
    + N! ]8 K* A3 k: `& ]' @2 q  F1 ^, t/ L) Y8 V
  10. * 调用关系  :
    5 |' i2 k9 _& a6 S" r6 x) T; ]
  11. * 其    它  :   
    6 z- n8 ]! `2 l, B* c# y! m+ \2 X
  12. *****************************************************************************/
    1 s  C4 i; e; D2 H
  13. void EnableUsart_IT(void)' W2 I7 V: q/ Z& K3 ^
  14. {   
    6 _2 ]5 i" S7 s2 t% q- _8 _( v7 n( y
  15.     __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); // 开启串口2 空闲接收中断
    0 ^- s2 c; {9 k
  16.                 HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//DMA中断' O! e2 i, q- y5 i( [8 F9 S5 I
  17. }3 v2 w& f2 ]1 L! C
  18. /*****************************************************************************
    : {+ K" t7 t1 {/ U
  19. * 函 数 名  : Usart1SendData_DMA
    6 C, x* ~2 \% [3 G$ ^; A
  20. * 负 责 人  : by
    * d" D+ e" M; L+ \( X
  21. * 创建日期  : 2020年8月26日; X+ y% t5 F+ O: _. U
  22. * 函数功能  : 串口2DMA发送函数! c  G5 Y# ]/ F1 F  L; {& S/ M: U
  23. * 输入参数  : 无8 t6 E3 f; t. F1 M6 u- G
  24. * 输出参数  : 无
    # e! {7 z1 }4 D* ?. l
  25. * 返 回 值  :
    " E  V( G% e2 Z/ o2 _- n' n5 d
  26. * 调用关系  : # z4 E6 ]& V4 N
  27. * 其    它  :   
    * O1 M/ @7 R# Z4 T, G1 I
  28. *****************************************************************************/6 x! ?0 T% c" N( y4 d, E3 f4 {
  29. void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)  ! y5 Z9 M; i5 O' e
  30. - t5 H2 i5 q2 \. A) T
  31. {  2 ~  A& V5 O& T& a- g
  32.         //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  
    - N% p2 X& b& `: u
  33.         Usart1type.dmaSend_flag = USART_DMA_SENDING;  
    % ?7 C% ~* D3 u4 ]9 l5 p
  34.         HAL_UART_Transmit_DMA(&huart2, pdata, Length);  
    * t9 a8 N' N/ U; b  `* q$ `: F
  35. }  . [! Z" J9 K4 P' a
  36. /*****************************************************************************5 r* K2 Y$ h! J% n
  37. * 函 数 名  : HAL_UART_TxCpltCallback
    # D2 |  J: W6 T. m/ {; K" _9 E1 S
  38. * 负 责 人  : by2 Z& L" m. i7 H: Z# r) A% W
  39. * 创建日期  : 2020年8月26日* l# i/ t- L- B1 }: g/ g# L
  40. * 函数功能  : 串口2DMA发送回调函数
    ( z6 P$ _$ m! [) v2 Y) `9 Z' N
  41. * 输入参数  : 无
    1 Q! y( K) V4 K/ \6 j
  42. * 输出参数  : 无
    1 {3 D: l6 o! Z" n. z
  43. * 返 回 值  :
    7 h0 a/ R1 y8 t$ x3 |+ A
  44. * 调用关系  : . v# g! Y7 O; b0 A+ S8 W7 @
  45. * 其    它  :   
    : _; u- u; W: R/ l* ?0 k/ ]
  46. *****************************************************************************/
    8 A0 V8 o0 F! x# J2 G+ @
  47. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)  
    / z  F& \; N4 t* ]
  48. {  $ }" E8 J; G6 F: V! J
  49.     __HAL_DMA_DISABLE(huart->hdmatx);
    , ^9 R, \  w' i. ~' S* N0 L" L1 w
  50.     if(huart->Instance == huart2.Instance)        1 A6 {& l5 J+ V1 u
  51.     Usart1type.dmaSend_flag = USART_DMA_SENDOVER;  
    * g, Z* T2 s4 x
  52. }  ) O+ U9 M7 h" L, Y; {: f8 O
  53. /*****************************************************************************
    4 Q: ?2 R2 {! a3 q; d9 B
  54. * 函 数 名  : UsartReceive_IDLE  \) y% v2 ~8 A  K- B5 `
  55. * 负 责 人  : by
    7 I: p/ |* ^7 O
  56. * 创建日期  : 2020年8月27日
    ' h& j- J+ C7 I" ~3 x
  57. * 函数功能  : 串口接受空闲中断处理函数
    - u, Y4 Y6 u) ]" P. }+ G( n" }
  58. * 输入参数  : UART_HandleTypeDef *huart  串口句柄
    ; m5 x" S! g5 o4 \4 [! R6 ?0 f
  59. * 输出参数  : 无' m/ c' S6 w; b, h" p) n
  60. * 返 回 值  :
    ) j# c: A! x0 T2 M: R; E! ~+ Y
  61. * 调用关系  :DMA接收的数据缓存在USART接收中,释放DMA继续接收 2 B  r. Z* o: @
  62. * 其    它  :   T/ J8 D9 h2 J8 s5 N9 R1 e
  63. *****************************************************************************/
    ! u" U: x* E0 o! |. q
  64. void UsartReceive_IDLE(UART_HandleTypeDef *huart)7 d2 k  s8 g6 s( v' c
  65. {1 J  T2 l3 b6 f! F! U
  66.         if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))1 f* v1 }7 V; ]" Y9 L
  67.         {
    7 N7 o) a8 L" q$ C6 |# r" J
  68.               if(huart->Instance == huart2.Instance)//判断是否为串口2/ A; ^0 h" |6 q, p, E
  69.                 {
    - l4 Q& U8 O5 f
  70.                  if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))   //是否为空闲中断0 s8 U  w, C( T/ P
  71.                    {  k, B7 H. Y6 U* b3 e6 ]% F! I
  72.                    __HAL_UART_CLEAR_IDLEFLAG(&huart2);                     //清除空闲中断
    3 ~/ {2 b, R( H& u9 |- E3 l" a
  73.                    HAL_UART_DMAStop(&huart2);                                                     //停止本次DMA传输
    + J" a$ ?: l. ]: p1 `
  74.             Usart1type.UsartDMAReclen  = USART1_DMA_REC_SIE - huart2.hdmarx->Instance->NDTR;   //计算本次传输数据长度
    , K# t' O  }5 H
  75.                                                 if(Usart1type.UsartReclen>0)
    / n1 d/ \' _% ]! w% G% _
  76.                                                  {0 X& A/ ~* S5 O: j
  77.                                                         memcpy(&Usart1type.Usart1RecBuffer[Usart1type.UsartReclen], Usart1type.Usart1DMARecBuffer, Usart1type.UsartDMAReclen);
    9 t: f" z2 F1 z6 H1 J& p% |
  78.                                                         Usart1type.UsartReclen+=Usart1type.UsartDMAReclen;2 \: G  ^4 U" x# u
  79.                                                  }
    2 ?6 R4 J0 V/ {+ e7 q& y
  80.                                                 else if(Usart1type.UsartReclen>USART1_REC_SIE)//如果串口接收数据溢出,从0开始记录
    % Q: C% V% ?3 v5 e' j" j
  81.                                                  {
    3 ], `! e4 ?  \# r* `  W; o
  82.                                                          Usart1type.UsartReclen=0;
    5 A5 i* A4 Z! @
  83.                                                  }, q; ~- l$ H% A
  84.                                                 else
    , N. q8 k$ C  ^. n
  85.                                                  {
    : A( I9 W& L' f
  86.                                                         memcpy(Usart1type.Usart1RecBuffer, Usart1type.Usart1DMARecBuffer,Usart1type.UsartDMAReclen);
    / y* \% q. [3 U6 K  u  L0 Q- p
  87.                                                         Usart1type.UsartReclen=Usart1type.UsartDMAReclen;
    7 t/ r4 e# L- k  b7 m% Z2 [& |% f
  88.                                                  }                                        ) a' e. k4 L- j& J+ c$ l
  89.                                                 memset(Usart1type.Usart1DMARecBuffer, 0x00, sizeof(Usart1type.Usart1DMARecBuffer ));//DMA数据清零                                                                                
    3 J7 Z) ]! V/ b7 _
  90.                                                 Usart1type.UsartRecFlag=1;//空闲标志位置1
    0 o$ K+ C. T7 k3 b8 \
  91.                         HAL_UART_Receive_DMA(&huart2, Usart1type.Usart1DMARecBuffer, USART1_DMA_REC_SIE);//重新打开DMA
    : _  ~6 w4 t4 c* x
  92.                                         }               
    . T3 f. e. y5 g( H$ Z
  93.                   }, q# W/ j; R+ Q3 H2 p
  94.         }
    6 j" o5 A7 @0 m- g( |  {
  95. }
    8 R0 V" [: P' A- a1 A+ y) k( B
  96. /*****************************************************************************4 F5 Y/ T7 ~2 \; G7 `7 Y- q" W
  97. * 函 数 名  : Analysis_Serial_Data* _& w6 B4 s3 O' \- Z# K
  98. * 负 责 人  : by. @. @  @- G4 L; S/ }  \  h
  99. * 创建日期  : 2020年8月26日/ E7 i$ i' V) Z
  100. * 函数功能  : 串口接收数据直接打印1 p; ?) r8 |3 r
  101. * 输入参数  : void  无7 J1 ?7 P- Y1 |
  102. * 输出参数  : 无
    - o" D4 z" h( y* x% v
  103. * 返 回 值  : void
    # V! o& F+ d2 X+ Y! B0 r
  104. * 调用关系  : ( e$ B3 p) @2 _0 K/ Z
  105. * 其    它  : 5 R# [0 f7 Y* \: T* l$ K
  106. *****************************************************************************/$ u1 @% c& O) |/ L1 f1 {
  107. void Analysis_Serial_Data(void)+ s4 Z$ ~$ Q5 Y$ E
  108. {
    & @% L  b; H2 k/ f9 M" e
  109.                  if(Usart1type.UsartRecFlag)
    + ~7 M# [' O1 h! f$ ]+ h9 g
  110.                  {                                 3 D: `. ?7 q  R6 |" M5 H7 G
  111.                          Usart1SendData_DMA(Usart1type.Usart1RecBuffer,Usart1type.UsartReclen);        
    " L. f. [% o. b; l* u3 c9 z: R
  112.                          Usart1type.UsartRecFlag=0;! r5 j; y" {' E; E
  113.                          Usart1type.UsartReclen=0;//测试处理为将全部数据进行打印处理,若需解析,可将解析长度进行减少,多次处理         7 R6 Z2 ^- {0 Z+ C8 d: ]* ^
  114.                  }5 j8 L) I: K: Z) i7 [, ~
  115. }
    4 t0 L9 [; r& [& Y
  116. /*****************************************************************************; o4 W& _) L, ]. N' Y3 n! E
  117. * 函 数 名  : fputc
    3 D6 o' V$ u% C' N
  118. * 负 责 人  : by
    9 n  I) Z, Y' X
  119. * 创建日期  : 2020年8月26日3 H3 U% Y, l3 ?$ ^9 z1 r
  120. * 函数功能  : 串口2 printf重定义/ k# a' F  P7 l( Q0 n3 f* u
  121. * 输入参数  : printf(d%/s%/%c,a)
    ! d/ ^5 O1 W, c: M$ i! D
  122. * 输出参数  : 无$ c2 q" o$ R9 ]& r2 j" `, _6 J
  123. * 返 回 值  :
    ; I7 N5 G: {( }2 V2 k
  124. * 调用关系  :
    7 b7 |9 H: q  I
  125. * 其    它  :   
    ; U3 c# t& @. L1 V, Z
  126. *****************************************************************************/! d& l5 A. ]1 i- Z! r* p- {% }
  127. #ifdef __GNUC__
    2 o7 t  ], n: H9 b% x+ ~8 o
  128. + O0 T; z; D7 k; l+ Z( J
  129.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    ; ~# @; f; c' @. \# d
  130. set to 'Yes') calls __io_putchar() */4 j% p. v/ k( V; U( {! M: P7 B
  131. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    & W# {5 W) a! ?5 r* z3 b$ a) T* ]4 c
  132. #else
    3 c0 l7 o8 C& ?1 M) `) U$ p& {

  133. - ]2 ?$ a6 s, k1 e3 P7 l# n  R
  134.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    3 J1 {- z  W4 |4 k, }8 T
  135. #endif /* __GNUC__ */
    ; M% a7 T  }; d8 r7 T) @$ e
  136.         
    3 b6 j5 g0 b" m' O
  137. PUTCHAR_PROTOTYPE
    3 ]8 A" y& o% H7 ~, n( l7 S
  138. {: Y; G! D. a& n0 d% W) N# M
  139.         HAL_UART_Transmit(&huart2,(uint8_t *)&ch, 1, 0xFFFF);) g! J8 |9 j/ G/ y% Z5 G4 @" e5 }% E
  140.         return ch;& A# H- \% V* k+ S$ X
  141. }
    6 _- {7 F0 G2 G* ?3 p- J" C9 I
  142. ) F7 N" r) p0 t3 m! h$ y% J, X
  143. 5 M2 H' ^# r% ~3 s4 J
  144. /* USER CODE END 1 */& W7 k' a$ x1 s9 E" m& V
  145. DMA发送函数,网上给的教程while是用来保证DMA收发节奏的,节奏错误会出现死循环情况,给注释掉了。。。。! h% v0 V( i0 t$ H
  146. 3 Z! W: x; u1 ~, }, N6 |
  147. //while(Usart1type.dmaSend_flag == USART_DMA_SENDING);  
    3 O5 ]  e+ q$ s8 e) _) U
  148.     Usart1type.dmaSend_flag = USART_DMA_SENDING;
复制代码
8 T0 _0 {/ U5 V& o. w" p

1 t1 X# e; d7 N1 G6.3  主函数,只用DMA通讯只需添加EnableUsart_IT();/*串口初始化*/,即可,对应usart.c里的函数
  1.   /* USER CODE BEGIN 2 */' d' ~- V( b( z2 R4 b
  2.   HAL_TIM_Base_Start_IT(&htim3);/*使能定时器3中断***/( u4 T7 T9 W  f4 y6 Q6 L* Y
  3.   HAL_TIM_Base_Start_IT(&htim2);/*使能定时器2中断*/
    ' `0 ?: V) s5 m3 C
  4.   HAL_CAN_Start(&hcan1);/*can初始化*/& l: k1 `$ G9 r% |& j/ J
  5.   HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);                        
    6 H: b& f$ N; q+ W+ k
  6.   EnableUsart_IT();/*串口初始化*/) w+ M. D, S/ x" w
  7.   CAN_User_Init(&hcan1);        * N" ~: ~7 Z3 }; t
  8.   /* USER CODE END 2 */
复制代码

6 w! E. q8 s! g: } 循环,对应数据输出) k2 W6 t* M3 k4 w) E1 m
" ?: @- ]3 W+ E0 P
  1. /* USER CODE BEGIN WHILE */
    7 B, e8 g9 D+ H2 F# ?* C
  2.   while (1)' n0 v) R+ L( ?# k: e1 F
  3.   {               
    + h6 J* a7 N" b0 Y" J8 x% E, a
  4.      Analysis_Serial_Data();3 W- \7 n+ L; `" Z
  5.     /* USER CODE END WHILE */
    4 v0 a1 h6 I% O) l4 I8 Y

  6. 1 W; c2 d- Z1 t4 `
  7.     /* USER CODE BEGIN 3 */1 W: W9 U5 g/ J8 L' m
  8.   }
    5 P0 T" o/ }' n; o" }7 d7 B" u
  9.   /* USER CODE END 3 */
    7 m( r8 N, {" y' W7 `
  10. }
    0 X# ^! O# o' }5 @$ S
  11. 7
复制代码
1 h& ]" ?  G7 c( q7 ]: |' v
、实验结果,间隔10ms,连续发送,未出现丢帧,或其他错误
: t$ `8 @: `  L# k3 [( ]
' P- a8 s3 s6 b( M9 C2 B
2020090115084313.png

4 @& i2 x: T1 I+ e/ _2 L+ V( _  h9 k9 R9 F; s. T2 f4 u. S6 P
. _- \1 [& f) ]" L. \
收藏 评论0 发布时间:2021-12-14 10:07

举报

0个回答

所属标签

相似技术帖

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