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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
一、STM32CubeMX开发
) J( X8 E' F. ^4 H2 Q. o5 h5 F$ V1.1 新建工程
9 `' Q0 |& l( I, z# efile -> new project
  D3 ?8 |& P0 P* I. c( ]
$ T" o" T6 A; e& X- U. v* q0 K选择芯片-> stm32 core内核         
' ^/ w' u% s/ O9 \) p& G4 G& ]  s1 T$ S- h; m/ v" h! a
                   stm32 series 系列7 v2 F7 h7 r8 U+ v
5 T& ?2 w8 h( Y4 U1 z8 @
                   stm32  line& H& J9 z1 E5 `7 v8 P

& W* @2 O3 L7 N# e# z1 [; M                   stm32  package
6 }4 Z+ s' s1 d/ W' g9 b% e' }# P$ K
选择芯片根据自身需求去选择,目前该项目是stm32f0系列  I( w0 B4 R/ i# Y

& E. h: b+ v& B/ ~/ `' `1 h! a1 u/ ^# M                    stm32 core内核         M0
$ ?6 m! L) ]/ c; b
4 ]+ ~! A) @# q1 g                   stm32 series 系列      F0
" Y3 d1 D& V# Q2 r' O
: Z# }* }" h; m+ F% ~4 M                   stm32  line                 F0X1
0 P7 F) p" ]% d# K1 f. P
/ @) i6 d) H1 S0 D8 _! A  x                   stm32  package         TSSOP 20' n, g4 @2 S8 K' r: I! T$ {' ~/ E

, T4 g  P: q; p6 p5 O: Q5 U' o4 z* Q0 T 1.2 配置 USART1& E; m+ J$ z' o' b7 ^: b
配置 USART1 的模式为 Asynchronous,即异步串口模式
% g* @3 a- @0 ?: b+ s: v4 U9 F. I' Z5 T# i) b
20210827163252369.png

  d( W' r' ^" H2 o6 L6 N8 Y( v9 n8 x2 W- [( U
1.3 配置串口参数
% y: Z7 t0 L4 T6 X* Q- T- L4 c 根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,1, K( y; {0 A! i' b4 @

8 P$ J$ L0 f4 P
20210827163448427.png
% f" C8 Z" N5 q/ k1 V2 X9 Z
+ w- L& M+ W5 C  c' h$ B
1.4 设置DMA
$ `/ I. }5 E5 [& A( X; i; B5 i/ L) a6 E+ _* M
20210827164240955.png
1 ^4 v/ d4 d% |  h( I9 c: @

/ J: |+ l3 s3 X0 d& A 1.5 添加串口中断
. g  Y  i2 r5 u
4 Y& Q" p! W' q4 M. l
20210827164323729.png
7 h& ^- G7 j: o. B2 p+ P* Q$ g9 {+ W
1 [9 M2 x7 ]/ A* |) f  X  j  A- O/ c
1.6 生成源代码。
/ R: j& A( j1 q  i: n在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。
- v9 t. J$ w$ Y2 s( c
, t( U6 c$ {9 Y& K/ y+ c. V2 C6 c
20210827164544427.png
1 F' U* ^% T  a' W- n0 |

& |9 ]1 F+ Z$ R4 L2 a; Y  x0 V9 _生成代码完成后可选择打开工程。 $ O5 }: S2 F; e* c  h$ C

. {/ T1 j9 B5 t' I: `' B/ [  ^
20210827164829635.png

+ N$ P/ R' ~( l+ }" r! l* o! P
5 ~, }  A+ ]9 N3 j: Q二、代码部分7 r1 v- g( V' D# ^( U+ Y
2.1  接收中断处理
$ L0 a, ^/ F, R( }& H  x2.1.1 接收固定长度:(舍弃)
/ m! b8 ?/ x& {' A0 L只有接收缓存到固定长度才会触发中断/ T* y3 x5 Q; }/ l: V  A
串口接收回调函数. Z( f* c$ T1 z9 z; R% E0 M
. B( w) [. g, C' K
  1. uint8_t aRxBuffer[RXBUFFERSIZE];
    ! b) o* I3 n: w& t  I7 _. J
  2. /* Size of Reception buffer */
    2 n6 n  i8 i6 C4 E- p
  3. #define RXBUFFERSIZE                    10" K. ?+ j  F. ]% _4 i

  4. ! O/ N6 r2 c+ v1 b. X/ H* a3 k
  5. # N, m2 m& S# t! \, `( n( r
  6. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
    4 R5 E% ~7 u8 T! F5 Q
  7. {- t6 ~8 R3 e" I7 O, W
  8.   /* Set transmission flag: trasfer complete*/
    - M4 N; s" t, C8 K( T
  9.   UartrxReady = SET;9 K. n: V3 s* h! |% e9 ]+ M
  10.         HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
    4 M. e1 K3 K6 J1 q' w0 e" n# k
  11.         HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
    / |3 X, M# d$ T# G* Y
  12.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
    , s( Y& K0 ]% o$ Z7 B4 y

  13. 0 E% ^7 `1 o: I( Z% K- |) J
  14. }
    # g7 A8 K- f, M

  15. % G) d. ?$ ]4 }6 l! ?3 M- A
  16. void USART1_IRQHandler(void); ]6 j5 _& Z* R5 Y3 k2 V+ l/ Q, D5 }
  17. {+ P( Y6 q) ^8 A* M! b9 w
  18.   HAL_UART_IRQHandler(&huart1);; C' W) F1 x' c+ q
  19. }
    0 ]- m8 t, ]' e

  20. 6 k8 A4 D& T9 _/ Q+ V5 A1 s1 G
  21.   T3 D. ]$ ~4 h) M: Q
  22. static void MX_USART1_UART_Init(void)$ u/ E  p% p% x- ^: O- P
  23. {
      b, V- M) _* [1 O

  24. ( _7 M3 v* ]2 @" V/ f+ r
  25.   huart1.Instance = USART1;
      z, Y& j' p0 h  c2 T
  26.   huart1.Init.BaudRate = 9600;
    5 M9 ^" G# F( f  c- d3 V
  27.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    * x" R. u6 ^/ ^& G9 w% d
  28.   huart1.Init.StopBits = UART_STOPBITS_1;3 P5 ]; o) y+ U3 }. C8 k
  29.   huart1.Init.Parity = UART_PARITY_NONE;
    9 ^9 W, _) R$ u" l  D, u& C% s
  30.   huart1.Init.Mode = UART_MODE_TX_RX;
    9 Q5 J2 K7 c* J5 K
  31.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    " e+ f# t6 H& {: D
  32.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;0 u  y* S6 \# F* D  b8 n7 j
  33.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;2 Q& d8 {2 p8 y# t6 |
  34.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;: W# Q& M$ A0 J- m* H# u
  35.   if(HAL_UART_DeInit(&huart1) != HAL_OK)- Q! F9 P. ?9 Y
  36.   {  i4 m# [/ r+ t& B8 _9 w7 ?9 D
  37.     Error_Handler();
    $ p: D' ?( Q+ g  W3 m
  38.   }  : u; e! u2 y/ v  a. L3 e
  39.         & D( d# M0 M% h
  40.         if (HAL_UART_Init(&huart1) != HAL_OK)
    * F+ G+ k9 W' M$ Q& i
  41.   {, T) Y( j& [, l$ A3 w
  42.     Error_Handler();$ k& M0 |6 S. B6 A5 c& V  o( O
  43.   }* Z: h8 r8 [( v9 g/ q" G5 Z- [
  44.         
    : V5 o8 [, \5 n$ t+ d1 }0 ^
  45.         UartrxReady=RESET;
    ' p4 G; A3 Z) q8 M3 ]  K2 }
  46.   /* USER CODE BEGIN USART1_Init 2 */, e" f2 _- Z. P7 @' r' j
  47.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK): J/ j* h( v' b( ^6 J% \8 A
  48.   {
    5 ^* l3 S3 z# x6 A8 \) x( S3 F
  49.     Error_Handler();
    / ?- v, b* N/ Z) z
  50.   }
    ; @7 c' }# E  C8 _) Y( V
  51.         
    $ q: b  O" K6 v3 W% d$ P5 [9 _0 n
  52.   /* USER CODE END USART1_Init 2 */, j7 o  R( d0 x1 b
  53. }
复制代码
; `: [& d9 {  |6 m% G, ?5 B
从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。
) x, b! u' ~/ f
, y1 {8 D3 |* P  F
20210902164819116.png

/ j! f' j2 P4 r7 T; \7 V
5 M9 p  Z0 P# o3 N( U2.1.2 编写空闲中断函数接收不定长
# T( J( z( N; W# JUSART1初始化:* a' ?; {1 [( o- K4 m9 ]0 I3 W
  1. static void MX_USART1_UART_Init(void)" ^( _5 E( _( ?% J9 b, l2 R3 h' l
  2. {8 B( Y) B2 |. C" n! L
  3.   huart1.Instance = USART1;- [) P) C$ r' E' l
  4.   huart1.Init.BaudRate = 9600;, J. a- [  N& [# I2 ?
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;( `* r: }' E! T+ y2 S8 V
  6.   huart1.Init.StopBits = UART_STOPBITS_1;6 z- d% i$ a/ A4 N! W
  7.   huart1.Init.Parity = UART_PARITY_NONE;0 n/ h0 _8 l; }* b+ {2 I' |
  8.   huart1.Init.Mode = UART_MODE_TX_RX;. n- O% }" @; J: u# e, }
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      Y7 @& s$ p. N2 A/ `: n0 L- f7 Q, a* ~- j
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    % \! ]( X, V( _4 p2 j9 S7 K  a% }
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    ' Y2 M7 o- N, l) Q% ^, W# Z
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;# a+ a/ q# I& k$ R) b" L" h7 n% ^' S
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    7 S2 [. B" u, O: J' l/ K
  14.   {$ k! R( a- F8 z0 a
  15.     Error_Handler();
    3 ?7 K. C" ?( g% ?+ T
  16.   }  ! Y! o9 B* S7 O+ A
  17.         
    ) V2 m2 {# u" v
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)- N: b5 R8 H/ _, w% d2 U* b
  19.   {
    0 f6 f  k* J+ \5 a- u4 F1 B" |
  20.     Error_Handler();! P$ |, p; n& b6 _2 g
  21.   }
    * W) G2 K4 ^- }
  22. + Z, I; P; t/ P$ }( x' F! r
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 5 F: a5 Q. @& C& y
  24.   /* USER CODE BEGIN USART1_Init 2 */. r: ?) c! _# d  o6 S+ O+ [' v8 w
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)1 t* y7 P' |* E$ h
  26.   {
    0 ?; d4 D5 ]/ |  K* P, u" E- I( G! l
  27.     Error_Handler();4 f% T1 V; u  B, ?' d5 g+ m) h
  28.   }( s5 E4 K  X, _0 B8 d/ A% @
  29.         : R3 A1 I; ~6 _+ h$ w
  30. }
复制代码

+ a; Q* z% ]3 A1 q空闲中断函数: + f6 i" v. ], a. {
  1. #define TXBUFFERSIZE                    30; O; D: k) p3 v& r. a
  2. /* Size of Reception buffer */6 Z/ n9 l$ @0 a/ ]
  3. #define RXBUFFERSIZE                    30
    ! ~/ O) A6 b1 C+ C% z  s' j  z4 I

  4. 6 ]# T' @' B, t& V1 J5 Y; c
  5. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)7 ~1 s9 h* H" v% X6 C3 ]0 X# W
  6. {& C% a2 T  U1 ~7 E# a
  7.     HAL_UART_DMAStop(&huart1);
    . E2 p4 |  \, K: K3 n

  8. ; g# p7 |5 ~! Q% J* p. ~
  9.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    * v6 Q7 j* h# U2 E. J4 Y; X! I
  10. / ~' ]$ E. B7 O0 q; x2 g0 L
  11. ' P9 U. V/ @# i+ Z
  12.     HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);, b# d& R2 |8 c6 Y" M" h! F

  13. $ J3 I2 ~9 C/ \0 J, x) i
  14.     memset(aRxBuffer,0x00,data_length);
    4 v" k- y! U& ?$ w  j  Z) Q
  15.     data_length = 0;
    9 B$ k" E  T9 g# E7 t$ T
  16.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    : @; u; h4 d* _1 i, _2 e  ~
  17. }3 a# x2 C" c1 q8 [

  18. ; Q$ V, U( w& w" @! I
  19. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)1 B* l) o/ Z# D8 C9 O6 F0 W# @; j8 J( m
  20. {( O0 W( e! ~5 b. b3 r
  21.     if(USART1 == huart1.Instance)
    - f" t3 v3 f, _2 X5 s3 f* c
  22.     {
    7 f3 e5 G  K, W' O. _! r
  23.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    ; J; p. D' Y; i
  24.         {
    & B, s4 T) n) z" O: J, T
  25.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);4 o" i  g3 G6 F! K  C
  26.             USAR_UART_IDLECallback(huart);
    ! w: y: N- {3 A* W$ R0 A
  27.         }! M7 Y" x$ h& ~4 }: `
  28.     }
    # z8 w# C9 X; ?  V1 T& J7 ]
  29. }) ~( {) u! X1 Q, N: |

  30. / L) }7 R. @; k* a( x6 [) K5 z" c
  31. /**9 o! n, y6 i8 d( Z% m+ C% `
  32.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
    9 X, n3 Z- a' D- h$ ^, h: M2 y0 K" H
  33.   */' ]3 n  L5 G, ~+ f
  34. void USART1_IRQHandler(void)
    5 a7 {, T1 J) @* V, r
  35. {4 l' R% j# @% d5 u( y5 y
  36.     HAL_UART_IRQHandler(&huart1);5 f: h$ o; `+ }9 d4 }
  37.     USER_UART_IRQHandler(&huart1);
    7 c1 b; r' i9 X) e/ U
  38. }
复制代码
; ]0 H$ Y6 w7 f( ~' X9 `
可实现不定长的接收! ) A1 @" J3 h* i' l

  T6 o1 k% X, W0 e* v
20210902171851390.png
1 a6 E% y0 _; d4 J, N6 }& J1 k6 M
) d4 }1 b; E) R9 q" C2 N
注意:- f3 I4 T) |4 m& ^( t8 |
在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。8 T: R$ ~! k$ M" h7 W! N% M
7 k+ d4 F. T  Y- K" A' }; R
三、使用ringbuffer实现任意数据类型的FIFO处理接收数据/ A0 @8 s1 W2 p" p# `* z# ~' |  Y
使用原因:
/ [0 F4 k6 q* `
7 v5 h" ~  E1 u/ I1 `1 R8 ~        虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。
2 F5 }* v' P) R, z2 b# ?; D" W. A9 w, K
        因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖
9 A4 a# W) B4 C; `4 |* _/ `* B/ ]; q2 |+ r
① fifo头文件:; C4 V- |- Z4 Z5 R; K, |8 D
  1. #ifndef        __FIFO_H_/ s) M% P: [9 ]8 z5 E% B1 J' f
  2. #define        __FIFO_H_
    ! P3 C. n7 E+ Z" E

  3. / x) j2 S0 g+ [( E( m9 x8 X
  4. #pragma pack(4)
    7 E% ]1 u6 n" U" i" K( v4 t
  5. typedef struct FIFO_Type_STRU
    ) {+ e8 y0 f; \" t& X
  6. {
    # w9 v6 x, P  S+ c5 T( j
  7.         unsigned int                        Depth;                        // Fifo深度$ X8 \4 T' g& x3 ^3 D
  8.         volatile unsigned int        Head;                        // Head为起始元素
    4 L+ w( A2 E3 q" N+ f
  9.         volatile unsigned int        Tail;                        // Tail-1为最后一个元素6 A7 v5 f6 d$ [. P
  10.         volatile unsigned int        Counter;                // 元素个数3 W1 S% P* ^* ]5 d
  11.         unsigned int                        ElementBytes;        // 每个元素的字节数element6 m; G( J; f& M4 {; z
  12.         void                                        *Buff;                        // 缓存区. z. O: s) f) f
  13. }FIFO_Type;
    * V5 z, K) I1 n* ~- h8 Q
  14. #pragma pack()
    , h/ z* E( I: M
  15. 7 D" a4 c* `, D1 p) H$ c9 \
  16. /********************************************************************//**
    9 a" r- D: W1 a1 e- m
  17. * @brief       FIFO初始化9 |( S) V$ V0 S# a9 l# m. w# t+ u
  18. * @param[in]   pFIFO: FIFO指针% z  F( `) x+ y9 u/ ]/ I* K
  19. * @param[in]        pBuff: FIFO中缓存0 H" H/ q! k7 u
  20. * @param[in]        elementBytes:FIFO每个元素的字节数3 D- z# V) d1 T- ], `. n
  21. * @param[in]        depth: FIFO深度+ E% D) ?7 U; E) w9 G3 a
  22. * @return      None
    / n" j) Z' Q) [5 b. x" N
  23. *********************************************************************/# J( K$ z: p% j% }  y
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);
    % R0 U2 A" O/ Q; a0 L  Q
  25. 8 D- V6 x/ d& V; p- A
  26. /********************************************************************//**! D- \; R! U9 p2 `
  27. * @brief       向FIFO添加一个元素
    % L9 h9 [. W1 X( Y5 f1 T9 c
  28. * @param[in]   pFIFO: FIFO指针( A, l( z) b; |- j. e
  29. * @param[in]        pValue: 要添加的元素! V$ z) a: q# y; l+ V( r
  30. * @return      1-TRUE or 0-FALSE: N5 A) O6 h% V, O) X
  31. *********************************************************************/' e( ]  l* k- O" @2 J+ s: \
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);1 v+ x' _% y2 ~* L

  33. ) C, D3 C* {* J; |) `8 d( Q
  34. /********************************************************************//**0 C8 D8 J! O7 p* b
  35. * @brief       向FIFO添加多个元素
    7 I2 d3 b% x- b, h# h. Y
  36. * @param[in]   pFIFO: FIFO指针
    1 ?9 }' y; S. R2 i2 w2 _
  37. * @param[in]        pValues: 要添加的元素指针
      R6 z3 E; ?! m- V1 E2 N' W7 {
  38. * @param[in]        bytesToAdd: 要添加元素的长度
    6 y( n7 ]3 N0 d7 Q: S: ~- \
  39. * @return      实际添加的元素个数! j, V6 ], r$ N8 h9 H
  40. *********************************************************************// @: l7 |% V, {
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);4 b5 D; A! l' H" J/ W) ^, D/ O
  42. & B2 W5 m0 u1 B+ c3 b- C
  43. /********************************************************************//**
    / N2 f% |! x0 B) a
  44. * @brief       从FIFO读取一个元素
    ' I5 Y% s/ m+ _: U9 F
  45. * @param[in]   pFIFO: FIFO指针
      A/ h$ X! |. b- c$ u7 {0 u$ o
  46. * @param[in]        pValue: 存放要读取的元素指针7 c& [; {- c  _6 A& W
  47. * @return      1-TRUE or 0-FALSE
    5 Q% ^" S% ~0 @& Y% @& V$ a
  48. *********************************************************************/
    , b" N3 o; B1 z$ W, W0 X. a; J
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);7 s+ [4 R4 t2 P& o5 |' }
  50. 1 `' z/ W5 V2 T  Y  @
  51. /********************************************************************//**+ [+ M& `3 S1 Q. D+ Y. u
  52. * @brief       从FIFO读取多个元素8 l! a! p/ t$ B
  53. * @param[in]   pFIFO: FIFO指针
    7 Z! v/ L7 E% T+ ^+ D
  54. * @param[out]        pValues: 存放要读取的元素指针% _, I4 |# `+ ]9 _
  55. * @param[in]        bytesToRead: 要读取的元素长度
    $ o9 q1 O* A  a# X9 S4 U5 O
  56. * @return      实际读取的元素个数
    8 q; {% V* n$ O
  57. *********************************************************************/
    0 ?! p* P% O4 j
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);1 ?# M# g& \5 C$ ]/ U! `! i' `3 N

  59. 1 n1 g) V8 ^! j$ j4 U) n* U
  60. & k- [' e: h3 W6 t$ `/ p% R3 \4 G+ F" O
  61. /********************************************************************//**
    * X) G6 n$ ]# z# M" L1 R' z) Y! U
  62. * @brief       清空FIFO* _3 @  p# Y. _  e$ r' H, [
  63. * @param[in]   pFIFO: FIFO指针
    7 e/ e2 o' g& O  o6 f- D
  64. * @return      None) _  O1 W5 P* s$ V
  65. *********************************************************************/* G( K  Q; n6 v, G9 l/ _6 Y7 v
  66. void FIFO_Clear(FIFO_Type *pFIFO);
    ) Q+ q* `: t  y; c- u9 K

  67. ' a% _5 s) \! ]# U8 g
  68. . R& \& Y. n  E/ c/ W0 J9 O, i
  69. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);
    # t; z! A6 w# k4 N5 V/ P
  70. 2 i5 \" ]- `) m# f% \
  71. #endif
复制代码
* t. p& }; K8 M# R. n, e1 ^5 Y
② fifo.c程序主体
' n: {/ Y: i, t9 j
2 p  E, ?8 n# u; c$ b, B
  1. #include <string.h>6 n% W, k4 T5 D1 @! D' c  d: Z
  2. #include "fifo.h"
    ; t3 I2 K$ C# z* T- A( v  I' F; N
  3. * m' L7 k% E1 J; o5 `; {

  4. 4 c+ @1 L/ z$ h" ?, w
  5. /********************************************************************//**  Q, N6 a/ z- t8 ?
  6. * @brief       FIFO初始化$ M+ f8 I2 m4 D! M: G+ Y6 p; U  s
  7. * @param[in]   pFIFO: FIFO指针
    6 z/ ~# d# D3 D, u
  8. * @param[in]        pBuff: FIFO中缓存, _# a3 p7 d* j
  9. * @param[in]        elementBytes:FIFO每个元素的字节数& l. g$ H) w( T8 P/ l: ~6 d7 z
  10. * @param[in]        depth: FIFO深度
    1 `: d" }3 r! g/ O1 n
  11. * @return      None
    . ?4 v4 K# r& S2 d6 N5 _6 A' L
  12. *********************************************************************/$ [7 p3 q7 _3 F' {0 C
  13. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)7 e$ {5 [+ C( a7 i; p8 @* j- l% n
  14. {
    : X: A5 ]4 z4 s) B. s
  15.         pFIFO->Buff = pBuff;8 J4 {& L0 \4 F. |1 A4 L
  16.         pFIFO->ElementBytes = elementBytes;
    : M: j% Q9 Z8 Q- v5 [
  17.         pFIFO->Depth = depth;
      @; J9 d- v( R7 l' i) n+ ~
  18.         pFIFO->Head = 0;
    9 }) @9 y4 o8 b. w9 w$ A$ P
  19.         pFIFO->Tail = 0;$ q- Q' P; O& |4 x% D8 |
  20.         pFIFO->Counter = 0;& x+ y0 `' D3 T% I3 Y
  21. }
    0 K* _1 E2 T! M% z. a$ n

  22. " y3 u8 A! j& Y9 f& a
  23. /********************************************************************//**0 }$ O2 _2 b" D- w6 t4 X
  24. * @brief       判断FIFO是否为空+ G& Q, y* p* Q; V1 N5 x: H
  25. * @param[in]   pFIFO: FIFO指针2 Z7 G1 M( t4 M8 `5 v9 {9 O, e: b+ ?
  26. * @return      1-TRUE or 0-FALSE5 A; q" i; J) q% Z( U  [+ I3 G
  27. *********************************************************************/
    4 G" N/ m8 T; p' o% @6 k1 Q6 E
  28. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)3 Q' w' w8 }3 ~
  29. {
    8 p7 l2 _( K( x+ i. b8 N: Z9 z
  30.         return (pFIFO->Counter == 0);, C3 l1 ?$ a( ]: i4 Q
  31. }
    : y& |3 Z6 z' s! H# w9 d4 N
  32. " ?3 O) n" ^$ y3 E: p3 t
  33. /********************************************************************//**+ N) z: q1 n. F. M% }4 I
  34. * @brief       判断FIFO是否已满/ t6 g/ e2 y3 _) u0 U
  35. * @param[in]   pFIFO: FIFO指针
    1 \; ^* }& B( ~* _* r
  36. * @return      TRUE or FALSE
    " s) d9 L& U" E' I" }
  37. *********************************************************************/
    . S$ p+ A$ o) |& D  \* l
  38. unsigned char FIFO_IsFull(FIFO_Type *pFIFO)2 `" s6 _6 P1 N5 G% I
  39. {
    - G3 t2 x4 E7 [& I# j4 K: M& e
  40.         return (pFIFO->Counter == pFIFO->Depth);
    9 s+ f9 g3 S0 C! ?9 Q2 M
  41. }
    ! M8 l+ H% M8 E7 p+ D" |: R4 @

  42. ! W7 i7 M( [2 e- C3 g
  43. /********************************************************************//**
    7 D( r# J+ K' p, q" K' R
  44. * @brief       向FIFO添加一个元素& L9 C# r( V1 b) p
  45. * @param[in]   pFIFO: FIFO指针/ B) R- D5 X+ H9 z& _
  46. * @param[in]        pValue: 要添加的元素& w2 p0 w9 z( X" h8 v
  47. * @return      1-TRUE or 0-FALSE! H+ X( f' z; t6 [( Q5 c! B$ t: V
  48. *********************************************************************/
    & D. R$ ?8 |( K9 I
  49. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
    5 C9 z! d! k: o4 }1 c4 B
  50. {
    - X) }0 V& `- J3 b! v3 n
  51.         unsigned char *p;: f1 f1 }+ u- q5 S7 F

  52. / y. t* Z4 p% A; C4 e
  53.         if (FIFO_IsFull(pFIFO))+ ?: v$ j2 D9 h7 d8 a$ p) f
  54.         {
    * `4 f1 g2 \& ]" m& [& E9 a# H( x8 ]# h
  55.                 return 0;
    5 J/ }; s$ I: w  ?2 R% k+ z
  56.         }' A3 d" d+ k- w0 }7 o3 N& D

  57. % u# |; x; m3 `
  58.         p = (unsigned char *)pFIFO->Buff;1 s4 l( q3 L! E1 n- C9 _9 ?! @
  59.         memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);7 [, ^! v1 K  c' {$ U( c# `
  60.         2 Z1 U, J/ v1 S; B# o6 S
  61.         pFIFO->Tail ++;
    7 S0 W$ U  I0 @% ]5 ~  q
  62.         if (pFIFO->Tail >= pFIFO->Depth)
    3 G: _6 R$ F# S9 L2 s: E- I+ v. ~
  63.         {; n/ {9 H9 {5 H
  64.                 pFIFO->Tail = 0;
    & H4 D+ F! p+ z. ]7 W5 J4 }
  65.         }
    6 @! F7 _' y; E: D- o% l4 {- i
  66.         pFIFO->Counter ++;
    ' F% K- E7 r- T4 J
  67.         return 1;# Y7 V- D9 x% T* O- ]
  68. }
    ( l" \- \5 v5 Q7 o0 S- u
  69. & |  ~  L: }+ M/ ]- v0 D4 K
  70. /********************************************************************//**. S% X: m" Q- J! V, E
  71. * @brief       向FIFO添加多个元素! F" X6 q" ]8 I7 T# S7 X
  72. * @param[in]   pFIFO: FIFO指针
    / z3 z. ?4 I# }8 W& y) [
  73. * @param[in]        pValues: 要添加的元素指针
    ) [( _: x9 e) p& x2 f" N
  74. * @param[in]        bytesToAdd: 要添加元素的长度* U6 I+ G( g0 R' R3 E* F3 m
  75. * @return      实际添加的元素个数
    * k: r+ s" c7 z) E3 H3 y
  76. *********************************************************************/3 u# c% h8 C5 h( ^7 P8 t% y$ L
  77. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)
    $ h- `, h8 |/ t: r& W, V/ [& b
  78. {
    ; I' m9 ~9 d0 `; R2 f9 s" q
  79.         unsigned char *p;
    * f  z  M# Y3 J. _; M
  80.         unsigned int cnt = 0;$ @7 y1 Y4 |7 {* u/ Y. r
  81. / M4 b! _2 o+ |5 P& K
  82.         p = (unsigned char *)pValues;6 B2 a2 W5 o6 M
  83.         while(bytesToAdd --)
    4 k0 E/ c- h$ E$ p% r! L  V% r: c- Q5 v
  84.         {7 ?. W* q) m; ]8 l
  85.                 if (FIFO_AddOne(pFIFO, p))' n" }& v2 w) a; b7 x# ~
  86.                 {2 y" i$ C9 \/ |" j, B- h8 X
  87.                         p += pFIFO->ElementBytes;% V, v! f* v/ m
  88.                         cnt++;7 U6 L3 a4 ~3 m2 \: ~+ m! _3 G' `
  89.                 }- G6 |( j  B7 j; `0 f. y9 @) U
  90.                 else) B9 R( u' j% C
  91.                 {
    $ J! l7 T1 s+ k: n
  92.                         break;6 U: Y! F% ^, K, L
  93.                 }7 `$ W# o2 n8 [( r
  94.         }! W2 |9 Y! K. Q- }0 P+ F

  95. & h4 V- N/ F0 h& R0 J7 L( p
  96.         return cnt;
    & m; \" P+ p, |( ?% D: i
  97. }
    * @9 D: `9 Z  n( O, D4 @
  98. & _* ?: G4 B2 C8 [4 z$ Q
  99. /********************************************************************//**
    2 E" ?- H3 Z* g" m
  100. * @brief       从FIFO读取一个元素$ b- |, Z& X9 d# ~, S0 _
  101. * @param[in]   pFIFO: FIFO指针8 ]6 V+ ~, ?( @* u8 z) @! c( I
  102. * @param[in]        pValue: 存放要读取的元素指针4 Z& F2 E+ g+ M( T* h
  103. * @return      1-TRUE or 0-FALSE
    ! ]1 n0 ?4 l# F. ~# |) g; t# {$ L
  104. *********************************************************************/
    3 w" X- c( s  R, c
  105. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)( X$ @9 }  F+ J7 i8 z
  106. {
    8 T. W: L" q+ h3 E
  107.         unsigned char *p;
    3 ?5 {$ b1 Y2 Q+ B
  108.         if (FIFO_IsEmpty(pFIFO))
    ' M2 O3 e* W# C& i, N9 ]8 N% }
  109.         {
    9 y3 M& V4 g1 ]
  110.                 return 0;  g/ J) o3 X) b; i
  111.         }$ g7 Q  H4 h: I8 ]5 P8 A; _

  112. - l% U" I- y5 [* y% H
  113.         p = (unsigned char *)pFIFO->Buff;; S! Q* m4 ?- F/ d. C' g% p6 R
  114.         memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);7 X9 ~. o; D* @" b  [- e

  115. & s9 X$ {8 v' _( K7 O6 y  j2 Q
  116.         pFIFO->Head ++;
    # N- Z2 W, G  L
  117.         if (pFIFO->Head >= pFIFO->Depth)
    5 a  r5 z3 j/ Y0 J" P
  118.         {! Z. a: @. l2 _, \
  119.                 pFIFO->Head = 0;
    , c3 j  p- ^" Y) B9 C4 J
  120.         }0 x. h! |$ \' p+ G; c
  121.         pFIFO->Counter --;
    3 N  k& y" |* k6 H6 b; ]4 o* H/ X

  122. ; {% y7 v* r1 B6 Q+ n
  123.         return 1;
    ! @  Y" w8 ]4 n0 R/ o2 T2 W& ^
  124. }
      F8 @6 i) L4 Z) f/ i8 z6 L

  125. ; R( ^; l3 P! N1 ?7 k" O
  126. /********************************************************************//**
    * l( |7 H( ]" C9 y6 e
  127. * @brief       从FIFO读取多个元素% L. @0 m% E1 O$ F4 t
  128. * @param[in]   pFIFO: FIFO指针
    2 C0 O3 p, p  B: R. a
  129. * @param[out]        pValues: 存放要读取的元素指针% C% |0 t' w' Q. ~8 p
  130. * @param[in]        bytesToRead: 要读取的元素长度5 _5 Q' o$ A, O
  131. * @return      实际读取的元素个数2 E; k) T: q: Q; i) T
  132. *********************************************************************/
    7 t" e; S4 o7 @! @
  133. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)* y0 U/ \. j% v3 e" i
  134. {
    # m& f4 d! ~6 b' Z$ _0 ]
  135.         unsigned int cnt = 0;! L: C7 {4 Z- n* t, i9 }
  136.         unsigned char *p;6 P( @4 h- F2 H- Q! d7 ]5 `5 G

  137. 3 i8 i5 U6 q! D" o
  138.         p = pValues;; L& ]) R' h! L
  139.         while(bytesToRead--)
    : Y8 c: s# k% C* f
  140.         {6 Q: K6 P+ W/ ^3 y* o
  141.                 if (FIFO_GetOne(pFIFO, p))% p7 F3 V2 \& ]6 b- O
  142.                 {
    , S4 t6 |4 J  u, C/ q6 _
  143.                         p += pFIFO->ElementBytes;
    " H* M/ h' j( o  m6 j/ B
  144.                         cnt++;* I2 x3 A! u; l0 |# z; b
  145.                 }
    * e, @9 l6 n7 ^/ u# J3 A' }! ?
  146.                 else
    3 m$ g) A' c% I8 N! T8 V
  147.                 {
    " B( o  [$ }+ d$ N( a
  148.                         break;
    ; m+ R5 H  A& {1 n& i# f
  149.                 }5 F- p" e/ A  H2 c# \6 I
  150.         }
    ; Z2 ~2 a7 `" |9 l7 \9 Z7 {
  151. 5 y- C5 g( G9 w1 O4 Z' j
  152.         return cnt;
    % ]- z& |2 C3 ^
  153. }' M( M3 ~2 _) h6 l" J/ Z
  154. $ j' f$ X" f, R. ~0 A, n
  155. /********************************************************************//**
    - x% i8 |0 N0 I2 D
  156. * @brief       清空FIFO+ t4 N* _/ Z% O2 D
  157. * @param[in]   pFIFO: FIFO指针8 o2 d0 }8 Y5 |; M  ^
  158. * @return      None
    5 D2 P5 E7 F$ N- Y4 o
  159. *********************************************************************/# H8 [; M6 e7 Q/ K& o* `* u
  160. void FIFO_Clear(FIFO_Type *pFIFO)
    9 j5 n( S- k3 y) G$ \
  161. {
    * H6 F+ I7 |, k4 ?3 c1 c2 ~
  162.         pFIFO->Counter = 0;
    - U/ v& g1 D( P  \. E% G
  163.         pFIFO->Head = 0;
    0 Z& y* ]% b, m2 O
  164.         pFIFO->Tail = 0;
    ' ^6 x. Z, ?) k! `2 m2 f! {) L
  165. }
复制代码
6 f4 H+ J7 |+ K
③ 串口初始化2 B+ ^8 z/ P0 S. g, P) h
  1. static void MX_USART1_UART_Init(void)
    ) C0 M! I/ V# p3 o0 f5 A2 q+ f, K! D. d
  2. {
    9 O7 `$ J* `  v$ K/ p) r" v
  3.   huart1.Instance = USART1;2 F( E6 l4 G( V" q$ M  s( E) B
  4.   huart1.Init.BaudRate = 9600;
    ! s/ x* x/ {  m, R  V, u% i" }* m+ u* x
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;# H) S  c7 B1 u- V( `/ y: _
  6.   huart1.Init.StopBits = UART_STOPBITS_1;# h3 e5 Q1 O7 @
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    ' U6 ~. k& U2 I# X$ z0 q
  8.   huart1.Init.Mode = UART_MODE_TX_RX;
    + ~$ m1 h% s5 T  N$ d0 E* d( \8 ?
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    3 T& N% f( f$ y8 g) q' ~$ Q" C
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;' [! E) H! e( C! }5 Q
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    3 T& n2 D4 e; Y+ [: K
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    $ Y5 B) \! ^( a( R5 a, t6 p, S; ]
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
      P' X7 a* C! `9 ^7 Y
  14.   {8 {5 s( M& P8 m+ K
  15.     Error_Handler();* v4 z4 S& W& g  Y! Q& T- _
  16.   }  
    # ~+ d6 _3 O% |, R" j
  17.         $ L  b/ b( q( Q9 l
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)
    9 ^$ F* j( _7 R+ n) u
  19.   {* s- t4 m- |" z
  20.     Error_Handler();' n# S# H8 ^: m' H2 r( ^! a7 H
  21.   }  t# l/ ^" A, T
  22.         8 x) X* q" u' v6 c/ v3 D
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); - s/ _& S. a$ R, Z. Y7 t1 u0 x
  24.   /* USER CODE BEGIN USART1_Init 2 */
    - k; p/ Z, V. Q1 a
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)" Q3 s& O+ E3 B* J: D; E5 S& E# f
  26.   {
    - J" b: n: k5 S- F
  27.     Error_Handler();
    1 _# c4 i. @$ r
  28.   }
    4 n0 V' C; k/ k. _6 g3 W) I
  29.         ; T! X9 g' Z# h+ ^% }
  30. }
复制代码
  v0 i8 w) l$ y! p/ V) e* L
④ 接收空闲中断4 t+ J7 Z6 K/ }0 {$ {) h/ [
  1. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)& |8 z6 |# p1 c6 V, l
  2. {8 ^: ]5 p$ |% v
  3.     HAL_UART_DMAStop(&huart1);. P' g' X! t: o7 O( ~$ G
  4. & i4 f7 {% `" E! x. ?( o  A1 e) ]/ |
  5.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    * a% L1 F# @0 J3 e) Q7 H
  6.           R! o5 D  k, O+ Q2 T% B8 N
  7.         FIFO_Add(pfifo, aRxBuffer, data_length);
    7 q9 x, W: l' M' z% A. d
  8.     data_length = 0;
    $ L9 E* `; o8 S- p8 f
  9.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);" Y, _4 t- R$ L( d* B" I3 ]
  10. }
    8 h8 s6 b  Z9 p+ r
  11. 1 ^5 ^0 {9 x# n, d4 v- U. \% t1 }% J
  12. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    9 o7 x1 n' j# V8 B
  13. {- j; z( O1 ?! ]
  14.     if(USART1 == huart1.Instance)
    + i: L2 P6 r+ \" g" L% s. Y% |" ?
  15.     {
    : f$ U" Y5 S2 q
  16.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)): X, f2 J3 h2 p6 }2 L
  17.         {
    & H/ {) z6 k$ J  E! q
  18.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    ; u2 E% i0 h$ m8 m" P
  19.             USAR_UART_IDLECallback(huart);0 {: I/ B7 y) G0 J) j* y5 Q5 x
  20.         }
    7 e0 k4 i( i. I0 k1 t% Q4 V
  21.     }
    ( I- _4 `# n: u
  22. }, H5 B/ d- P0 w
  23. 1 \  R0 {: O1 c( ^9 m3 |6 ~5 X% J6 b
  24. /**
    1 Q) d5 a9 @) o
  25.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
    # A9 [1 K9 [/ k. n! J9 p# x
  26.   */( t- C  v' G% c: D( h/ X  g
  27. void USART1_IRQHandler(void)
    + x- k1 G6 T9 F6 M0 E
  28. {
    : x* f) c' A1 @' W8 B
  29.   HAL_UART_IRQHandler(&huart1);
    1 u8 P- U7 A" E
  30.   USER_UART_IRQHandler(&huart1);
    & z) x% u* n* H5 p: ?
  31. }
复制代码

3 k  d, F7 m% ]* T5 v⑤ 主函数调用:. M6 A+ G1 ^& z+ t) Q; B
  1. #define TXBUFFERSIZE                    302 V4 o% Y: ]4 X4 X% O8 T  ?7 {+ Z
  2. /* Size of Reception buffer */9 r1 b6 ], u! K" H
  3. #define RXBUFFERSIZE                    TXBUFFERSIZE
    , Y) I0 e( f0 \' r
  4. #define RXFIFOBUFFERSIZE                TXBUFFERSIZE * 5
    2 j6 ^8 Z5 T& P
  5. # _9 j: x: V( t# a1 l
  6. ) ?( v4 I& X: }. `8 ~3 _% n
  7. uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";
    0 _$ `+ z7 p! Y  r% z
  8. 6 X4 C& S; d% w$ t
  9. /* Buffer used for reception */
    ; O$ H+ A, d+ j9 P0 x* V
  10. uint8_t aRxBuffer[RXBUFFERSIZE];
    8 x2 J  A! ^) V" |

  11. : J1 }  f. w% D; K, H7 o
  12. uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];
    * V, S! [+ \2 L# \& B! ?# R) r
  13. FIFO_Type        fifo;% u8 U8 w, e& b! n# a: y
  14. FIFO_Type        *pfifo;
    , G1 x- I% b! `

  15. ) V* ]5 g/ k5 q+ u4 r% e# u) d" @
  16. int main(void)8 J: a1 [0 K" u) u4 Y( L) w
  17. {& T7 `# f: {" a- c0 }% h: y
  18.   /*此处省略硬件初始化*/
    6 U: z8 c  S  G. ~
  19.   if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
      v) U1 e0 D' {# a" ~, V# l
  20.   {, r) ~( x/ e0 p
  21.     Error_Handler();
    - b  b8 U1 B4 U' a
  22.   }8 ?! }( e# |2 s2 ^3 x
  23.         / h" q8 z3 ]( V' h+ v
  24.   pfifo = &fifo;
    & e1 X, x3 t$ G+ H& ]+ F

  25. " X- V3 _4 \6 p
  26.   FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);: s  Z2 M) V; _$ G
  27. / Q0 {3 A+ H; P" d9 Q2 w, g
  28.   while (1)7 f" Y. P) l2 `; n/ M3 [; I& b
  29.   {
    3 ?7 z( u! `0 @8 [- @, n
  30.         /*一次接收的缓存,重新发送*/' Y9 I4 ~* D; {+ L/ |, P$ P
  31.                 if(!FIFO_IsEmpty(pfifo))7 G! r% ?3 c7 l( e
  32.                 {  m. n4 J/ W) @- v- t8 A
  33.                         uint8_t a[100]; //存放读取fifobuffer的数据& |9 X% ^$ ^. [9 O1 ?
  34.                         int i = pfifo->Counter;//先保存接收缓存的数据个数
    2 K. ?9 s2 A4 B* Y) Y, G5 F
  35.                         FIFO_Get(pfifo, &a, pfifo->Counter);3 c7 i1 B8 J0 E6 }+ b8 ^
  36.                         HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率
    , z0 _# v# M& [' w( G
  37.                 }6 d# ^( h2 M1 F  D
  38.   }
    : Y5 e: [0 ?4 o  x
  39. }
复制代码

  L+ p3 L* J3 d% `) E% l测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
  w) \/ e( U7 X9 c! Y6 w6 M* [) K  Y4 M# ^
202109031459585.png
: r; M% E) j) K3 i; ]
" \* R! D0 S( b; G& s
问:关于 stm32 HardFault_Handler问题处理?5 {2 B' n" O& C) V
! R$ L9 H3 E7 N5 ?- w
ANS:. Q5 b7 I6 b4 p, N# f* c

0 ~- X0 M" |- l: N        在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,
6 @7 W+ a+ T! q' i" a7 v1 K/ r
8 O2 a# C) b6 [; a( M% d. Y
20210903150306628.png
8 Y' Z. v- o, p" ^: i

: Q  v! U$ y; ?; h( R1 g6 h
20210903150316369.png

) ?( j7 E: ~5 x5 J: n
& `4 {# M: U6 e 最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!9 }* O$ q/ V4 n( j
  1. pfifo = &fifo;
复制代码

+ j$ b8 X8 ?1 G  s- a' y% E2 _' `' m1 y3 k) I
! x* F, j# z6 x, r1 X' R

3 h( E5 z. M) c' u( G
收藏 评论0 发布时间:2021-11-25 15:00

举报

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