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

【经验分享】stm32f0串口 DMA 空闲中断接收——基于HAL库(代码篇)

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
一、STM32CubeMX开发
2 a2 t5 U# U; q% N+ B$ n  X( d1.1 新建工程
) l9 e3 L4 U4 v3 Y0 t0 S, Ifile -> new project
) m7 A) I' `5 B  D) \& m" ^  e. E! e# |. N# P
选择芯片-> stm32 core内核         
3 }9 Z0 d+ q2 z: [( ^  r& a/ R" ^7 a0 G  V7 {8 {
                   stm32 series 系列9 x4 G" d( _1 I* c/ K( v3 F
/ M9 U5 u5 q0 j" W0 F' l
                   stm32  line
1 S7 _2 g" K$ ^
2 `% a- h  T; x0 u5 N& d) L                   stm32  package% Z, H+ I/ j7 n3 P; f# ~

0 e' b* X+ T* Z6 A6 m选择芯片根据自身需求去选择,目前该项目是stm32f0系列
7 x: m9 A+ o, c, g, R$ t# S
" Y2 Y2 [1 t" W+ V" H3 t9 w  m                    stm32 core内核         M0/ p! f. {, ]" R( @, P

. x! R: o1 O; h- {: M& M                   stm32 series 系列      F0( t" |" j! Q# O% e3 R
. m  `2 K9 S& i7 [- K/ u
                   stm32  line                 F0X1
* x, r2 P7 X9 T# Y; U% D+ _8 z& q: J$ @7 W
                   stm32  package         TSSOP 20/ A0 H6 h' Y: y% P5 a( u. s* v0 F

" p' N6 c" f7 g& M4 O 1.2 配置 USART1
2 ], P% z  a: J( E6 D( j配置 USART1 的模式为 Asynchronous,即异步串口模式) y" E6 P% ]0 z- M

6 w+ c, @* l' f6 [5 R( d$ j5 ~" }
20210827163252369.png
; a/ H! T0 Y0 T  \$ M
3 T3 l1 o# i9 f8 _  Q
1.3 配置串口参数$ e" o  b- Z& Q2 J0 a8 u! I# m- \; E5 K
根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,1
, Q0 X* ~3 D! X6 ^6 w0 J* b9 W+ y
# r" f+ ]0 E4 W( H  y8 v/ i; I+ q
20210827163448427.png
" ]6 R+ \4 c, |$ @; G4 S
0 F$ N5 g! Z: S
1.4 设置DMA# Z* D1 s5 J$ {8 Q
" I, l' V2 `* F1 M8 n
20210827164240955.png
" l5 R6 _2 @9 g! b
- E0 V+ ?$ @4 \6 t6 F
1.5 添加串口中断
* p8 t& J( k4 O4 L  J/ P/ N8 n/ S5 n% f# r3 H
20210827164323729.png

' L& M" s  ]* `" w7 Z+ D4 ~  C
7 {1 [# O: I( m1 q- `# T& L6 E  f9 \ 1.6 生成源代码。6 [% X; b2 X4 A& x2 W  |
在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。; U! v0 Q& V3 \1 E: _6 E+ X

  v. \# ~  E3 o; x& n
20210827164544427.png

# l+ R- G$ b( D6 _0 w1 ~
' \; ~% Y3 ~0 o& \生成代码完成后可选择打开工程。 5 z& m- b7 ]8 e( h0 x: w& b

+ I7 c/ k/ K9 Y- p/ n
20210827164829635.png

# b/ H8 V4 D7 ~
6 M6 b) ?! [; w4 i二、代码部分/ Q; @& o% N6 y% y( G
2.1  接收中断处理) a, [$ B1 u9 y$ C) `( f
2.1.1 接收固定长度:(舍弃)
; }7 x: F" y2 p7 j+ d只有接收缓存到固定长度才会触发中断9 Y1 L' {* B. w3 ^
串口接收回调函数
4 w  T' _  \) Z
' [  Q* j+ }- x* c" q
  1. uint8_t aRxBuffer[RXBUFFERSIZE];
    & ^8 O6 M) ?$ x& ^% k
  2. /* Size of Reception buffer */, V# M, x& y" l- q- `
  3. #define RXBUFFERSIZE                    10. L; S4 @) @$ h1 }0 t6 Z& d

  4. 4 C) O* a& b' \4 V

  5. ! _' M* x. ^" r' |$ J
  6. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
    0 R0 \" B, t2 S& S. t
  7. {8 ?& W$ B1 }2 t. s
  8.   /* Set transmission flag: trasfer complete*/
    1 a' O( T0 s3 B- b5 G
  9.   UartrxReady = SET;# S( F; t! f: i: E9 J- |
  10.         HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);; l+ {, I, \* e% y4 E# P* b
  11.         HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);8 m: `" ~& A% b1 B- b1 n
  12.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
    ! y; N) l3 q; I
  13. 8 R; G, j' H$ I' e8 ~- z) S4 }" S
  14. }9 b! e) N4 C9 S# v

  15. ) C; r8 s, \4 }$ L
  16. void USART1_IRQHandler(void)# p4 w& e& N3 p
  17. {5 Z$ E( M2 X/ O$ I' V
  18.   HAL_UART_IRQHandler(&huart1);0 e4 N8 }1 Z; \: `, K
  19. }; Y. j% J. v3 l4 E# L! l, v5 y9 \

  20. 7 p' W, \& C+ Y% \7 r! G# O
  21. 2 d! z/ i2 d, U0 k" L& J
  22. static void MX_USART1_UART_Init(void)
    * n( O# Y8 L4 |$ X$ ^, z8 }
  23. {
    5 X. l3 m( m' z2 i* o. M8 Y

  24. 9 a8 a: ]6 u4 ~
  25.   huart1.Instance = USART1;( E$ Q: ^$ V* K/ ?& u
  26.   huart1.Init.BaudRate = 9600;4 H. a# ~8 R, t. S& {
  27.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    - M) ?5 H, m' N: M* q5 r! }+ t$ _$ i
  28.   huart1.Init.StopBits = UART_STOPBITS_1;. P5 `1 Y$ q. B* D5 l
  29.   huart1.Init.Parity = UART_PARITY_NONE;
    - d# q! Y# w8 U/ N6 S
  30.   huart1.Init.Mode = UART_MODE_TX_RX;
    % q4 |7 E4 t. B, n3 q3 `: O7 H
  31.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    3 @' b4 ]' B1 _8 t) z: @
  32.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;6 m" L5 k9 o4 ?; p: Y% C2 S1 b: D) k
  33.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    ) B9 M/ g6 h: M0 Z$ X5 Y7 k
  34.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;4 }# k! P6 K) U' Z% B3 [! a
  35.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    & m, o1 W5 j& ?" |0 d* [" G5 q3 k
  36.   {3 ?$ X/ \6 K6 v/ Y+ o9 |" q
  37.     Error_Handler();+ w8 w- e) w2 ?2 b" ?
  38.   }  
    9 ], N* ]5 `1 v& e
  39.         $ A6 H. I- H1 r5 R5 |
  40.         if (HAL_UART_Init(&huart1) != HAL_OK)" Q9 q0 m: P* h! b. Y( O& ~+ M# O
  41.   {
    9 m- G! {* J: w  [& E
  42.     Error_Handler();! j$ u3 a$ \% E+ l' [. @+ K
  43.   }
    ) T  h4 _1 o' b( m1 b, T- o' I
  44.         
      Z3 F6 e" t  ]: _: k7 G3 ?4 t
  45.         UartrxReady=RESET;
    2 o% y& m( E+ n/ F6 z
  46.   /* USER CODE BEGIN USART1_Init 2 */8 C/ z& y; V& d3 Q+ R& i( T+ n  t- P& w
  47.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    ' {& Z( d! m% k3 R! e
  48.   {0 m' u+ u) X' N$ f4 Z% Z
  49.     Error_Handler();
    , w1 A) |- `2 q) r' N3 ?3 l
  50.   }
    3 i2 p! i% W1 V5 q* j, z" ^- E
  51.         
    ) f/ U8 T# D& N6 N! q: d0 k
  52.   /* USER CODE END USART1_Init 2 */6 O3 f; r4 x1 M1 X( S: i9 ^
  53. }
复制代码

+ ^5 A# b/ j, Q: s$ M/ Z从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。) U3 P  m' Y, V- I. v

! J  V1 p- w0 j, g
20210902164819116.png
5 M8 X% _4 z9 u  p0 u5 Q' ~

  u& R8 Q) n0 D0 U  g1 ^& }1 C7 n2.1.2 编写空闲中断函数接收不定长, T0 x# a2 R7 g  o: O- j! h" ?
USART1初始化:, F! ?" m. B% Y0 m3 Z* h, w
  1. static void MX_USART1_UART_Init(void)
    , E; k: U  p9 A! u9 T
  2. {
    2 q  `* _6 M3 u8 j1 R; ?) S3 d
  3.   huart1.Instance = USART1;
    % e& B3 f1 i7 r9 ^: E: ?+ G
  4.   huart1.Init.BaudRate = 9600;0 a! J* J5 J8 J, R2 D( A4 b! G. E
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;: t  g6 l6 z- @4 w( a) [% \
  6.   huart1.Init.StopBits = UART_STOPBITS_1;
    3 `& k, s8 R) P1 y) ]2 _
  7.   huart1.Init.Parity = UART_PARITY_NONE;7 q8 u+ d" D& p7 a) D+ Z
  8.   huart1.Init.Mode = UART_MODE_TX_RX;. }; X4 D2 R- l( V  ^5 g7 G$ W0 R
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    2 j( C" R: c& A4 I" d( o
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;/ u8 v& [; X  ]
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    1 x1 n% B: {( k
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;& j& ?" w8 j+ G; G1 |
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    + k# C' Z" M0 V
  14.   {! ?) Y6 \  ~' A% h) J% \1 a
  15.     Error_Handler();4 Q  @. u1 X) I
  16.   }  ( M+ F" X; `4 w- f
  17.         ' w; N7 @& u! {3 O; c7 ^/ t0 U* {4 h; s
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)5 o7 L; |+ B+ Y' q0 c2 `
  19.   {
    4 m* k1 {& |' u5 `
  20.     Error_Handler();
    / g" R! [4 O6 |7 |* W' I6 k' D
  21.   }5 x$ C* a# y- X1 [  d! \

  22. 1 A0 G* x/ t+ K
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    ( U) c* F, y7 _/ T0 x3 t
  24.   /* USER CODE BEGIN USART1_Init 2 */
    . T3 o& T5 ^# f  d- Q5 r
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)# z( x; x' |# `0 x
  26.   {8 M6 V" Y4 R3 L9 I- }5 y% {! N
  27.     Error_Handler();
    $ V- c- y1 ]8 r& E5 c: \9 r& H
  28.   }6 u" `, V( m4 d
  29.         
    1 f! w, R, J  ^; z9 R$ c- P
  30. }
复制代码

* z% ]9 ^) J$ c& |" i空闲中断函数: 8 n, ?. n; t$ s4 A
  1. #define TXBUFFERSIZE                    308 k  G# O/ f0 S2 @8 X& O! a
  2. /* Size of Reception buffer */6 a. a! ?- g0 O: h8 n
  3. #define RXBUFFERSIZE                    30. r7 ~: V  C5 }1 p$ J* C/ P4 M

  4. , I1 X! g2 X9 E, P6 q
  5. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
    : H2 e- k# n; u# y# b: _
  6. {
      ?' P- Q# z2 {' g2 }
  7.     HAL_UART_DMAStop(&huart1);6 `3 b3 m2 Q+ {, w& }

  8. ) a3 M! ~' {5 O" o; n; J
  9.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);8 u. W7 ~  l6 y% Y  m
  10. 8 Z, `( Q1 [( [& B
  11. ' W4 S( C" n# z4 `( P* x( ~! b$ U8 ]
  12.     HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);8 g* G8 Z2 a0 y: E

  13. ( x* _5 @$ S" q* a  r
  14.     memset(aRxBuffer,0x00,data_length);+ g! j, U! `1 z, _+ V
  15.     data_length = 0;+ D7 n1 }1 |$ h1 j' j& `
  16.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    $ V) @+ S; u; w: [5 l' K
  17. }% S. k& A4 O& O7 T7 O, F7 ]
  18. 7 x3 V1 J. @7 R) P/ h! ^) I) }- s
  19. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    " L4 Q: ]+ Z5 F1 u
  20. {
    ' [1 t6 ]- X: ?  g& f
  21.     if(USART1 == huart1.Instance)
    # k8 N( ]8 P$ t; Z' }0 X+ T
  22.     {
    - G# V, c+ b; F: s
  23.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    ! T9 j4 o. \; V6 C0 @. e3 O% v8 T
  24.         {
    3 G9 J) N$ u* C. s) P
  25.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);! g1 ]2 ~/ S- t; d
  26.             USAR_UART_IDLECallback(huart);
    , o2 t* B8 H% E( I& {
  27.         }6 P1 E8 G. t- h# P( c1 }& `+ a. E1 F
  28.     }$ x, D% S9 w" S1 }
  29. }
    / T3 v  L2 k% x, D9 Y  @2 R

  30. ( d2 l0 H7 H+ J! H7 ^
  31. /**8 b2 a0 m7 P7 B$ ?% z) V8 M4 G4 w
  32.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.! |, F2 U! P) q8 D
  33.   */
      f( x4 s- G3 H6 s  E
  34. void USART1_IRQHandler(void)
    5 x' W5 i2 ?$ ~9 y. D
  35. {/ F, t6 ^0 q3 h; O7 N
  36.     HAL_UART_IRQHandler(&huart1);9 {( h$ B( H& g0 \5 O6 q
  37.     USER_UART_IRQHandler(&huart1);. h. Q  w5 v* U6 Q* Y: {) t, d
  38. }
复制代码

5 \2 V2 N& y- F8 b) j可实现不定长的接收!
9 l3 x+ I5 Z% b8 `4 r% m
" Y* P( I8 i/ g3 r/ ~! a  p$ Q$ ~
20210902171851390.png

* w& ]2 m4 N' o& w/ F/ W% d
% x2 z+ T: ^( \" }: j, E 注意:
6 C* C) z& X9 i  p5 s8 S在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。4 A+ H9 m, F6 K. J4 [" N6 s

4 P) t. D% X% Y" u+ e! d' J 三、使用ringbuffer实现任意数据类型的FIFO处理接收数据
' e" N! z3 `" p: S) }使用原因:
" ?  C# W, N+ A5 @( _- ?, E! G- r: A- W! n* j( z" S$ `: j( m
        虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。& @9 I3 R) B% [( f$ I  M) D

; A$ j  w+ c" [9 C        因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖& f6 F. C% J2 c: s% f$ K/ I' p
% g6 x$ V& f  r( |/ p* ]. u
① fifo头文件:
1 E& H& A) i' F  t: W- b$ M3 {
  1. #ifndef        __FIFO_H_  M2 Y4 l2 s+ D% f
  2. #define        __FIFO_H_
    : _! H* e) y3 N8 h* H! ^+ O+ h

  3. ) }' d1 t8 j/ K* ~, }( W( h
  4. #pragma pack(4)- j6 Z0 Y, n' C: i' K
  5. typedef struct FIFO_Type_STRU
    , O" r1 k7 ~- v0 r" I* o
  6. {
    , H5 E( A7 P1 v" m/ H1 o
  7.         unsigned int                        Depth;                        // Fifo深度
    & e3 e4 \& F+ |) c
  8.         volatile unsigned int        Head;                        // Head为起始元素
    ) x- ]' I( ^8 O; V3 }
  9.         volatile unsigned int        Tail;                        // Tail-1为最后一个元素* A& ~1 ]0 k7 |) u! A' n
  10.         volatile unsigned int        Counter;                // 元素个数. h7 L9 D9 m8 S7 Z2 {$ D
  11.         unsigned int                        ElementBytes;        // 每个元素的字节数element' ?$ }! p0 {5 J  c. ?8 B3 J
  12.         void                                        *Buff;                        // 缓存区  E& |6 P" ]4 |, m
  13. }FIFO_Type;6 j' A1 I. p8 C! f# o
  14. #pragma pack(): o9 f- D- K/ X
  15. 7 W- W5 p0 q# [' K  N% C
  16. /********************************************************************//**6 q, T7 x  Y1 m
  17. * @brief       FIFO初始化
    , O1 U! w6 [& M" ?  `: w6 ]
  18. * @param[in]   pFIFO: FIFO指针! @2 K3 w" A2 ^
  19. * @param[in]        pBuff: FIFO中缓存
    6 U& K: m5 s% ]0 F, ]
  20. * @param[in]        elementBytes:FIFO每个元素的字节数
    ; H) o3 ?4 F4 b6 ~# |+ Z
  21. * @param[in]        depth: FIFO深度% M$ e( o8 a& G0 T
  22. * @return      None8 l+ e" |- ^1 |; v5 h( i" q  e6 V
  23. *********************************************************************/2 L+ _4 D& y# t" P1 c$ d) q
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);
    : U$ `1 @5 u9 n& P. C

  25. ( H' c% J: S) t6 Y6 v+ {
  26. /********************************************************************//**4 E; ?7 t! i/ R' b/ r, i* ?
  27. * @brief       向FIFO添加一个元素
      \2 }( b$ X7 m' F6 J1 |
  28. * @param[in]   pFIFO: FIFO指针+ e7 y3 r- U+ P  J) Y
  29. * @param[in]        pValue: 要添加的元素0 J5 o/ j# ^/ _$ ^. ]' E
  30. * @return      1-TRUE or 0-FALSE
    ( t4 p" B3 O7 t2 W( m: i: M' U
  31. *********************************************************************/
    8 G8 A  u- J' S) M. z- y
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);# T/ @& l( q. O% y/ w6 s
  33. 0 W+ |5 D9 Q! B# S( H
  34. /********************************************************************//**+ x: g: H4 ^& n' M$ A
  35. * @brief       向FIFO添加多个元素
    1 k1 A- Z* l4 K* o, E% t$ I3 }
  36. * @param[in]   pFIFO: FIFO指针- j/ Y) e8 \& W+ T' ]
  37. * @param[in]        pValues: 要添加的元素指针
    0 Y& ]: f5 Z. M; x3 W
  38. * @param[in]        bytesToAdd: 要添加元素的长度
    5 A% V! ~! i+ c8 Y4 _
  39. * @return      实际添加的元素个数
    / \* _2 _/ k5 r3 f( Y& F
  40. *********************************************************************/: G& P8 }0 }: T% X7 R
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);+ {8 f# y: D! G, w

  42.   Q7 E' ^% ]. C: k: q! X$ k
  43. /********************************************************************//**7 A# w8 `0 D: c/ S) Y
  44. * @brief       从FIFO读取一个元素
    & a5 ]: {$ Y: n6 _* T1 u9 h' g
  45. * @param[in]   pFIFO: FIFO指针5 v) \! w& h, v1 P
  46. * @param[in]        pValue: 存放要读取的元素指针
    7 i1 B: C5 U8 |, C  w& Y' ?; @
  47. * @return      1-TRUE or 0-FALSE
    + S, Z4 g7 D9 q* a) c2 h
  48. *********************************************************************/
    2 _# x3 e6 J# ~
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);
    . Z7 V! @8 K7 O" H

  50. ! ]+ P7 a  Z: r8 `0 T3 W- W5 X3 i
  51. /********************************************************************//**
    ; l$ C$ y' \6 D4 p3 h
  52. * @brief       从FIFO读取多个元素
    & x2 x( U- {8 R8 @' h) ?' g1 T
  53. * @param[in]   pFIFO: FIFO指针$ ~$ b/ i0 S- x. ?
  54. * @param[out]        pValues: 存放要读取的元素指针
      f6 X* ^7 S) ?; U) g5 y2 \
  55. * @param[in]        bytesToRead: 要读取的元素长度3 m/ x+ _8 {: h8 J$ l) x; C
  56. * @return      实际读取的元素个数
    ! {& i- ^) m% p  w6 i5 N
  57. *********************************************************************/! c6 T: s* d! e  ?: q
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);1 s" h5 p6 J5 C! H: i
  59. 3 g8 z- u1 S; v8 I

  60.   K$ H3 Y5 B- E7 j9 y
  61. /********************************************************************//**9 w0 J5 i, P' s/ [; b+ }0 x1 c
  62. * @brief       清空FIFO9 m, @1 ]4 V8 A" A: W2 ], B
  63. * @param[in]   pFIFO: FIFO指针1 \& k' Y. D7 X/ L% p
  64. * @return      None9 J; w5 D7 `- x5 g( W% b" a
  65. *********************************************************************/
    0 B( `: {- S0 T
  66. void FIFO_Clear(FIFO_Type *pFIFO);
    * J1 |* F- W+ i) F! o( A

  67.   x5 R. y% Y) X
  68. , z9 [5 i9 t, E& C
  69. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);* T. r6 R  h; c. |3 v4 i
  70. : F( j" w0 t) K" ?: o
  71. #endif
复制代码
6 h" p) ^% `& A. z( K
② fifo.c程序主体9 X  h" D5 h" {$ s  d
2 t- q/ t; Z# a9 n
  1. #include <string.h>5 b- O6 Q& J* [6 V4 ^* f
  2. #include "fifo.h"
    ) U  F2 {& d& Z0 k& |6 v
  3. # ^( b: E+ b+ R7 m" P6 T

  4. ) Q% M2 h; C: H* c8 u! z$ R: F  E
  5. /********************************************************************//**. P, D  ^! M0 |+ d; ?; M
  6. * @brief       FIFO初始化
    / o  W* ?& C3 r% z) j
  7. * @param[in]   pFIFO: FIFO指针
    0 V1 T5 Q3 {% z
  8. * @param[in]        pBuff: FIFO中缓存+ v  F: A: f" k5 t0 M4 [
  9. * @param[in]        elementBytes:FIFO每个元素的字节数# o5 U0 j3 {, a+ V: o  V
  10. * @param[in]        depth: FIFO深度
    5 g: a9 Q" D: Q& R: k: N$ g# ]
  11. * @return      None
      j& k6 q! l# A1 O
  12. *********************************************************************/3 ]( z% |0 }& ]$ P' i$ j
  13. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
    2 b8 U( P" L+ ^: U" e$ O8 N* v
  14. {" x. L* v! S9 u0 U; L
  15.         pFIFO->Buff = pBuff;6 Z& ^4 F- A5 u2 ?# h
  16.         pFIFO->ElementBytes = elementBytes;' p' D, D4 z2 h$ g1 i. K2 u' k
  17.         pFIFO->Depth = depth;* |6 E: f! W- K9 H: |& b# Z  T3 a# s
  18.         pFIFO->Head = 0;8 a! R# Y" ^5 e0 Q$ p
  19.         pFIFO->Tail = 0;
    + y* O+ W* o8 c1 O+ x
  20.         pFIFO->Counter = 0;5 H2 E* B# ^% z
  21. }
    6 Z$ A1 m) q8 g& L
  22. $ T! i( ?; ~6 L) }, x
  23. /********************************************************************//**
    5 E3 [# ~8 z7 R0 y& o$ f6 \
  24. * @brief       判断FIFO是否为空
    % I5 g7 L# o9 }: C9 x: v: O
  25. * @param[in]   pFIFO: FIFO指针
    & Q) |' _) H2 E( t/ f
  26. * @return      1-TRUE or 0-FALSE
    * v* {4 n/ d$ y0 d
  27. *********************************************************************/
    3 v0 h$ y% {; M1 H) B1 l2 w4 d) K
  28. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
    $ D. n1 K5 \4 h- O
  29. {
    7 R5 U1 Y9 q3 i
  30.         return (pFIFO->Counter == 0);5 G" G0 G: x$ X1 E0 K
  31. }
    & b. l7 B5 ]4 \* a" X0 I! ?2 {; y
  32. # J) n1 J: c, Y6 o
  33. /********************************************************************//**
    # f: R9 ]( l9 o9 V
  34. * @brief       判断FIFO是否已满& B5 \( J' ^+ s, Q* k& ~4 @4 v3 D
  35. * @param[in]   pFIFO: FIFO指针
    : R1 e4 Y5 l$ \) D' {
  36. * @return      TRUE or FALSE, B. d+ `8 S; I% _2 z
  37. *********************************************************************/3 i% ]; ^# r0 Y, F7 E. y
  38. unsigned char FIFO_IsFull(FIFO_Type *pFIFO)# e/ A' r$ I) Y4 r1 `) |
  39. {
    0 C! H2 Z% Y+ L
  40.         return (pFIFO->Counter == pFIFO->Depth);$ V6 k5 f) K+ c
  41. }; `; b2 R1 C7 q9 e

  42. ; m; S/ f+ S6 L5 d0 Z+ h, z& `9 m
  43. /********************************************************************//**0 w% B3 B* V/ G2 i/ v
  44. * @brief       向FIFO添加一个元素* J  A: \1 x/ b$ s3 A& I$ F7 \
  45. * @param[in]   pFIFO: FIFO指针3 h: ]6 G. K5 ^' ]7 H6 A
  46. * @param[in]        pValue: 要添加的元素/ D/ Q  x4 c5 |3 w. s- f
  47. * @return      1-TRUE or 0-FALSE
    / @7 P1 k( t9 T
  48. *********************************************************************/
    ; J; n* n7 n3 u  V4 t
  49. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)# ^' F6 O/ c, V- j1 U: |, P& N2 n
  50. {
    , H6 l. Q0 {1 v- v4 g1 s/ r8 o8 U
  51.         unsigned char *p;& E9 j9 z1 v8 a

  52. 9 w1 ~. |8 L. h- z+ V2 @' C) q
  53.         if (FIFO_IsFull(pFIFO))4 \4 F( E, i' \5 X4 k* R: `( N1 g
  54.         {
    . z+ D+ C: C. O
  55.                 return 0;: c& r1 Y  R8 E: i# Q# o- s
  56.         }
    5 H" Z2 P1 b0 I" G8 L
  57. 5 d' K, b/ K5 i# o$ [$ z6 {
  58.         p = (unsigned char *)pFIFO->Buff;+ P8 d3 \2 q) K9 I- j5 s+ b3 c" h4 C
  59.         memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);
    6 X' U# q8 H; A9 \. ~5 K& j7 y
  60.         
    . O" f# y% m0 N; v2 y' E1 a6 _
  61.         pFIFO->Tail ++;. e8 o$ r! N# d% N' X- r& o
  62.         if (pFIFO->Tail >= pFIFO->Depth)
    6 o" R- L6 F0 W3 L3 t5 N
  63.         {
    2 W/ P7 V6 _- }* z) ~( i
  64.                 pFIFO->Tail = 0;* X0 l" k, l/ ~$ P! j1 Q
  65.         }6 c+ H# C4 a# T! \/ M6 v8 M: ?$ U
  66.         pFIFO->Counter ++;5 y7 g. ^. j3 I; r
  67.         return 1;
    6 f! O! c. p% |4 G, e* ~
  68. }, Y) Z) W7 I+ W" `
  69. 4 x. L' C& ?1 m5 h+ z
  70. /********************************************************************//**2 l5 j* E. O8 R
  71. * @brief       向FIFO添加多个元素
    % y- I% Q- c- e, K6 d
  72. * @param[in]   pFIFO: FIFO指针* p; v6 A. o/ v" _7 @
  73. * @param[in]        pValues: 要添加的元素指针; S, t! x( d+ z1 |' U2 V( X# m6 {
  74. * @param[in]        bytesToAdd: 要添加元素的长度  A: @  u( P0 T! h( f/ m) G" @
  75. * @return      实际添加的元素个数7 y4 i7 }$ b% `. n. }; p" l% Q* |# ~
  76. *********************************************************************/5 z" ]# c' K. I3 A  c) x1 V# n
  77. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)* \5 l! W1 b6 f3 ~- C0 L
  78. {" T8 B1 K  ^0 D' L- k. H+ R' u% j) V- _% E
  79.         unsigned char *p;
    + X5 _7 _) \( ~3 X3 ^; u9 h
  80.         unsigned int cnt = 0;# i: f* x$ |2 A+ j) j6 `0 O# H

  81. 9 H+ \/ J% O7 X* O& Q( K6 ^
  82.         p = (unsigned char *)pValues;
      I1 q$ G+ e" r8 r  x3 d5 X  ~
  83.         while(bytesToAdd --)
    ' U) A& }- Y; v! v# y4 {) \  @
  84.         {
    0 h& Z" Y+ y) y" w1 L! Z9 Y0 v
  85.                 if (FIFO_AddOne(pFIFO, p))$ f# |" X4 r3 q9 K4 U
  86.                 {+ a+ y& m9 R0 l! X5 ]
  87.                         p += pFIFO->ElementBytes;" r/ \! `2 `3 G% |0 \5 v
  88.                         cnt++;
    , C  l0 D, b" u- f5 h) |9 T
  89.                 }
    5 y2 p' V) Q0 C  [, ]
  90.                 else$ U. L& C4 U! ]6 V4 J, E
  91.                 {
    & k/ f8 ^0 k9 @, z! L# M( l
  92.                         break;+ h% o' e. A7 ^5 c* s
  93.                 }
    ; b; `, n' E/ A, g3 B, a* L
  94.         }' t/ h* Q) q. ?; r5 @
  95. 4 V% @6 T5 G4 l8 j; b
  96.         return cnt;
    1 T1 {! e# H# X5 M
  97. }
      y; m: q: M& n) j) `
  98. + L  {% B! I# W4 g+ E
  99. /********************************************************************//**
    . P8 ]  f; U8 }  D  B$ A' G, w
  100. * @brief       从FIFO读取一个元素
    / B, R% ^( g8 P! G1 l( c( Y2 |
  101. * @param[in]   pFIFO: FIFO指针; H& q7 n+ T, s7 X- j/ y
  102. * @param[in]        pValue: 存放要读取的元素指针
    $ B) S& x, S) R
  103. * @return      1-TRUE or 0-FALSE0 E. }; Y$ g' r* l
  104. *********************************************************************/- S, Y7 g- V# x5 y2 @9 i9 D
  105. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)
    2 |3 I8 O7 K% {
  106. {
    * b1 A. V. a$ \5 P3 E) o
  107.         unsigned char *p;; U7 i+ t% u5 ?$ w# `
  108.         if (FIFO_IsEmpty(pFIFO))
    ( w4 H) g' z& V' }: d' d2 _
  109.         {
    ( r* G$ y1 W' c2 h
  110.                 return 0;
    / b+ r2 v5 |3 s6 ^
  111.         }
    5 B% p2 u: f7 H
  112. ' r8 ?" p, |: G
  113.         p = (unsigned char *)pFIFO->Buff;( p# o# ~; l7 z4 D$ ^
  114.         memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);
    0 j" G7 w: e. _/ G/ J

  115. - _5 r& z  e" c9 S( S; B7 ^
  116.         pFIFO->Head ++;* j! i; t' s/ m( A  c2 u& g/ E
  117.         if (pFIFO->Head >= pFIFO->Depth)
    . m) I* l) v& e" a; V: z
  118.         {
    ) P: y8 U% T# T( Z0 `
  119.                 pFIFO->Head = 0;4 }; w# q9 t. J. n
  120.         }2 C/ `4 Y; z! i* s( c: l
  121.         pFIFO->Counter --;
    ( M( e. A2 m% v9 ]! b: {
  122. $ d) J# J5 M/ @- h; C
  123.         return 1;
    4 n# p4 g0 Y. q- W
  124. }: K, ^  P; `; |) n# p
  125. ( n" `+ Z2 p9 Z# @
  126. /********************************************************************//**
    + c- Q+ i* ~6 }* ]7 A
  127. * @brief       从FIFO读取多个元素
    / r( E' e7 _$ F- O# ]
  128. * @param[in]   pFIFO: FIFO指针
    ; k0 ]9 t! H9 @/ B. g9 d
  129. * @param[out]        pValues: 存放要读取的元素指针
    ! t7 p$ z7 a5 j9 @
  130. * @param[in]        bytesToRead: 要读取的元素长度5 I" K% @, a5 |' n# b
  131. * @return      实际读取的元素个数
    ) h* {: Q( m  K, H  h4 F
  132. *********************************************************************/
    $ a% F& P6 q, l# _  R
  133. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)
    6 F- {; f! m0 d& W! K  s5 N( y" A
  134. {
    1 j  [8 \# p  p3 x% t
  135.         unsigned int cnt = 0;
    % O6 F; ?- S; K9 k3 a2 _: _# s
  136.         unsigned char *p;. e$ n- Z1 Y* h# O( a4 x9 G  T

  137. $ l$ t8 o' O- C; J5 s) A
  138.         p = pValues;
    + l% T/ u3 R7 G  ^7 b6 V2 f6 i
  139.         while(bytesToRead--)6 A1 D) \  u+ m1 H
  140.         {, h5 K$ y) q* s0 w' ^
  141.                 if (FIFO_GetOne(pFIFO, p))1 s: S& N3 F& {
  142.                 {
    , P6 q  o% U# R0 u
  143.                         p += pFIFO->ElementBytes;
    % ]3 j1 [/ c+ C
  144.                         cnt++;
    : g0 ^( u8 Y' s+ N
  145.                 }
    0 I5 H" H# Z3 m( H7 a+ H: |0 G! k
  146.                 else
    - @" k* U( F0 G7 v# J% J0 P9 ^+ {
  147.                 {
    2 v: E- L: e% p: ^/ T5 k' |
  148.                         break;1 X2 ~/ ^# R) u/ e; L
  149.                 }5 p+ D: }9 x3 |5 z
  150.         }
    * w' k% F" N% J: l1 I" m, Y6 Y
  151. , c' }7 \" h+ ?8 r! P! O6 u
  152.         return cnt;
    ) f! O4 u- _' v
  153. }$ }' V( O& ?; X8 k

  154. 2 E8 D5 k- |' q* c# q/ ?2 n9 F
  155. /********************************************************************//**
    - u5 [5 y7 h, T7 n, L& W
  156. * @brief       清空FIFO3 {. M$ Z/ N5 b5 L) [$ l1 h' s
  157. * @param[in]   pFIFO: FIFO指针1 ^/ _) d1 K- y( ?2 g- X
  158. * @return      None1 S$ f* U. K+ m- |
  159. *********************************************************************/1 v* h4 z" V5 j# Y, h+ a* K  w
  160. void FIFO_Clear(FIFO_Type *pFIFO), k$ c6 I' x8 U9 ~6 H% n
  161. {  x; T% t; m+ U, U
  162.         pFIFO->Counter = 0;0 i, U4 ^2 i: F8 Y; n6 Q( z# M0 V
  163.         pFIFO->Head = 0;
    ; H* X8 w" Y" L3 m8 k
  164.         pFIFO->Tail = 0;3 z: p" R# o  E9 X
  165. }
复制代码
8 C9 Y, j  V" ]! X% A! ^6 F2 Y# g
③ 串口初始化
3 u" ^# L2 Q9 r* S
  1. static void MX_USART1_UART_Init(void); v8 _5 }; W5 r# p* v
  2. {7 k& T0 C) p9 \4 `, a" _
  3.   huart1.Instance = USART1;
    : g/ L4 A4 V& Z8 T$ M/ A' u, G( J9 C
  4.   huart1.Init.BaudRate = 9600;) m( y5 W, k& y, P& M1 z; G- ^
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    % h9 N; K& r5 ]* m$ l! t( P* Q
  6.   huart1.Init.StopBits = UART_STOPBITS_1;
    3 _  n* w  U! c5 j- _- y
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    7 Q5 R, v; h5 }: S% f+ R8 _
  8.   huart1.Init.Mode = UART_MODE_TX_RX;' y6 x( a8 f4 n& V5 a$ f
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;3 n9 y* L/ b* ~1 ^4 x
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;! Q0 V& U% |* f% q1 }
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;! {6 l) r& V% @/ K8 U+ M
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    ) h. g/ e# U3 E1 \' Z& C( `
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)! s+ n3 @& x3 I/ X
  14.   {
    2 S8 D5 ?$ F$ j0 I! i  O
  15.     Error_Handler();' b  u# B+ m# A/ ^3 N/ M4 p, k1 m9 w
  16.   }  
    ) A5 R# y6 X0 |3 j9 Y& ^/ m& n3 {
  17.           ^' F  c8 v+ s7 l; ~
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)( b: w  I  m5 c5 c1 w
  19.   {, f$ @* p5 t' c3 I; r/ ], M0 ]
  20.     Error_Handler();
    ! E9 J9 w1 e/ O; z4 |
  21.   }
    0 y/ j4 v$ q7 q, S3 q6 w& U
  22.         : C$ a2 q! q5 T3 O
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    7 u0 k# G( \, w1 o2 I$ h6 y  y( Z
  24.   /* USER CODE BEGIN USART1_Init 2 */
    ! \5 v. e0 Q: z- j+ N" o" {9 ]9 Y" F
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)  U6 F" S4 h( K3 x; g7 z' n* I7 T
  26.   {' P: a/ j" p  f$ n, J$ Q
  27.     Error_Handler();7 \2 Q  a9 w  z- G6 i! T
  28.   }: k. s  l! b3 {: y/ b0 I6 }; e9 |
  29.         4 e9 P( Y( v  w: w5 s. J, M/ u9 {
  30. }
复制代码
: c. h& M* Z7 Z, R0 u2 Q
④ 接收空闲中断; Y( `: }* b/ D9 c
  1. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
    / k4 a8 t: t8 ^. K! f& y
  2. {7 I; O2 C. g7 \! x2 l
  3.     HAL_UART_DMAStop(&huart1);) O# t6 t  C  w8 c2 @
  4. 4 m& w: {) y8 a- b
  5.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    / Q9 m8 ]$ V2 c
  6.         
    6 F1 N1 W6 ]& [' w4 A3 N
  7.         FIFO_Add(pfifo, aRxBuffer, data_length);9 t( X6 P+ {5 M* F( P, |# {
  8.     data_length = 0;
    * \' c% h# Q. f! x0 U8 [
  9.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);8 ]; V6 X. c9 p0 H3 f8 f
  10. }
    + X  G9 J: c  y7 N  V* ]
  11. 6 ^0 C- J1 o* ?% Q# I+ @) u! n/ N
  12. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)5 D6 e/ G. I/ z$ l+ ~
  13. {& p" L( E+ U7 y4 o, @: Y
  14.     if(USART1 == huart1.Instance)
    & r5 m! ^0 n1 _3 X6 o: U( I
  15.     {% Q2 E6 v/ \& ^$ ^# x0 `/ N
  16.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))" R( I9 w% ?+ M3 D: k$ q0 u- S
  17.         {
    ) o1 o# D! ^' h' g
  18.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    . x* S0 |" A& \! ^' N
  19.             USAR_UART_IDLECallback(huart);8 L# m9 Y7 b& |
  20.         }2 J6 U6 Y2 W3 \- }9 U
  21.     }
    . Q# d" {: l- P8 Z$ j
  22. }: n8 U2 r- ]0 B  V5 G, x" D

  23. ( ?5 s5 i7 {! }0 j7 O" x+ h) I
  24. /**9 n6 r6 c: P6 C6 i; ~: L9 j
  25.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.5 ^. z/ v- {  T
  26.   */  \# c) M7 i: z8 C3 A: G
  27. void USART1_IRQHandler(void)
    9 P' F2 D  Y) o" l! v% {
  28. {- z- {5 l) i, V2 H" K( `
  29.   HAL_UART_IRQHandler(&huart1);5 f* @' @" C  A& I, {' b2 C
  30.   USER_UART_IRQHandler(&huart1);
    9 s/ z# ]4 g2 x; W# `9 f
  31. }
复制代码

" F7 o) P5 a" b. b5 A⑤ 主函数调用:1 i2 {+ K+ X- `/ G- K
  1. #define TXBUFFERSIZE                    30# v8 T; R0 w) U- l
  2. /* Size of Reception buffer */
    9 i8 `/ O/ j" [& U% D
  3. #define RXBUFFERSIZE                    TXBUFFERSIZE
    1 T& H7 ]9 d) \4 Y
  4. #define RXFIFOBUFFERSIZE                TXBUFFERSIZE * 5
    + V" L, w8 g! G2 l

  5. 8 M$ w9 I$ }9 N+ M: q
  6. + W; I7 C8 N/ ~5 W/ t
  7. uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";
    : e. f6 z5 w3 }+ r( ^0 I& P

  8. ; Q7 v" P% V; s" ?+ p7 P
  9. /* Buffer used for reception */" H( [* P5 k# c  I
  10. uint8_t aRxBuffer[RXBUFFERSIZE];/ ~* t! E0 x( M. }2 C2 N) C2 U
  11. 8 d! [, m8 s  V
  12. uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];. o  P1 [$ Z- V3 c% Y* q
  13. FIFO_Type        fifo;5 I2 d2 u8 s/ v3 d0 S4 u$ E/ ]; b! c
  14. FIFO_Type        *pfifo;7 Z  c; k4 `: Z* ?$ l4 A) H" e
  15. ' C- R- v7 P' Q
  16. int main(void)- W, x! ]4 Y# G" _
  17. {; P% v& H( q( Q2 b' d2 R1 o
  18.   /*此处省略硬件初始化*/9 `; R: O  [, p0 x% E
  19.   if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
    ; n9 x% k' P; G
  20.   {
    . }- x. h5 |" A) X* Q" {
  21.     Error_Handler();2 z! l6 V; y' r/ n( A
  22.   }
    ' q+ H& N5 G, Y2 U6 o8 ^
  23.         . Z2 M" h) p; f% v# b
  24.   pfifo = &fifo;
    # F5 _4 V7 `* D/ o8 J- |

  25. , U# ~) F9 V) h0 e. I  w" r
  26.   FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
    0 ?% F5 N" p/ m' h) z# ^+ E

  27. 0 C5 C2 V2 t, T, f* M7 m
  28.   while (1)
    7 N' ]+ s! t) I$ X6 C5 E3 t
  29.   {
    1 E. V  o+ J3 p7 ]( z7 z+ x$ S# n
  30.         /*一次接收的缓存,重新发送*/
    8 o/ b3 p& \1 ~8 ^( O* |
  31.                 if(!FIFO_IsEmpty(pfifo))  O8 D1 ~9 Y! T# w# N" P  P; M
  32.                 {
    ) C* n2 Z2 m  N, ?* t; k
  33.                         uint8_t a[100]; //存放读取fifobuffer的数据1 p# C' M8 s1 M! r4 [
  34.                         int i = pfifo->Counter;//先保存接收缓存的数据个数
    % g. B- x6 A) M+ y
  35.                         FIFO_Get(pfifo, &a, pfifo->Counter);( J$ a/ s+ e% _& J5 f. i
  36.                         HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率* f  p8 q" A0 l, [, G, N
  37.                 }( S' Z. t$ j1 W
  38.   }5 n- v2 ~. e! h
  39. }
复制代码
* u* X# \% q. J/ ~/ i& Y
测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
! U3 M6 ^5 q0 U: P7 D0 \* c2 B1 X
* L: a+ O6 p# V
202109031459585.png

& h# N( U+ z) y' ]1 s" n5 a/ c- H' O
问:关于 stm32 HardFault_Handler问题处理?
  C* l. G  K& R* q+ Q
1 C" w7 H- z2 f* a% V7 u8 GANS:: ]5 Y3 A- \; ]% t

# q: U. X  Y2 B) u# p        在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,! N; C9 {/ c0 H5 A0 q- T6 x

* k3 K$ P! _" n7 A$ G$ b" g
20210903150306628.png
" S7 K5 n- t: p% m; m
3 s0 p# l1 c+ n) p6 B
20210903150316369.png

/ ~7 b. K9 M, T& |
* K- z* B6 R3 _* \* k1 k" E" G 最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!; M0 a. S( I1 j/ C) }; t) o
  1. pfifo = &fifo;
复制代码

6 A3 Z, b7 i6 r+ f/ j( h5 i
$ G7 m! j7 Y2 h1 o  Z4 A% c# ?# [0 k6 c, G3 F  w

1 V" O- P0 W" \! j" }
赞 收藏 评论0 发布时间:2021-11-25 15:00

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版