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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
一、STM32CubeMX开发
5 s- S: f4 S' O1.1 新建工程
7 O6 ~. q, {# {& i& Hfile -> new project " x0 G$ j6 g3 q" \0 j( J: N

& |% o7 w8 i, H  H: F6 H选择芯片-> stm32 core内核         
' b7 Y& T) s0 j1 h$ E' i0 ^  b+ V
- `' C* y0 T; p! @' p                   stm32 series 系列
# U  Z+ K, X" y" t
. |! m$ `0 _) d8 l# t  E" @                   stm32  line
( _: D* t% A" X7 M1 Z8 `* h% F/ M1 ^5 C: ?
                   stm32  package
# d; W. ~' P  Q4 E! H# c
' |3 r6 J0 d# a0 f$ u9 ~9 k( _! j选择芯片根据自身需求去选择,目前该项目是stm32f0系列' I: c' D$ p! }# s, @3 L
+ n* l5 a3 ?; r& b7 e# t; k! E6 P: w
                    stm32 core内核         M0. f3 F3 u; I  @! E" X1 u$ a
8 g5 V" q/ l1 w$ d2 g2 n2 i& O6 W
                   stm32 series 系列      F0; Q! p8 v8 Q- t# t
! t" u6 m0 c1 u
                   stm32  line                 F0X12 a3 x  N/ F) {( p! n0 f
# }, i6 j; ]/ L# D9 F% R
                   stm32  package         TSSOP 20
$ [. k; a: P  g3 j
3 N$ A/ d) j2 y/ N) P5 p5 x& w 1.2 配置 USART1+ e4 K1 U0 D. H7 B
配置 USART1 的模式为 Asynchronous,即异步串口模式. \+ e) U0 t) k  a# W; V
$ ]6 [$ f$ b: r- n& ]) y+ l
20210827163252369.png
, j% n/ z2 @# a5 x" C7 ?& Y

, g# N5 C; I/ X5 ?- g$ V1.3 配置串口参数' R$ ?1 Z. {! P6 s/ r1 j5 S
根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,1
- ~3 ?! a: j/ Y  J- v9 F! Z# P
$ a5 D- H; ~3 g! u8 u/ P4 l+ h
20210827163448427.png
) a6 r2 K+ p2 P. J4 J3 Q  x- I" j* A

( S+ o8 o% n9 u 1.4 设置DMA
% q. o5 d( h6 ^
9 D' M: x. T' I5 k
20210827164240955.png

6 r6 M! a( C# `7 a1 I7 V
# n/ j2 ~9 k" z 1.5 添加串口中断% n& E& W6 g, p, c, w

/ ?; v0 }! z" V. e/ \
20210827164323729.png
4 Z# _/ U3 |! c4 ?" X

/ z8 P) k' b1 c8 H7 x7 n/ S7 y 1.6 生成源代码。
- L: N: O+ G" v  V5 h在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。
/ h- j# c% a7 L  C6 G9 R
2 V4 L4 \9 B! F( A& Z  x# D" z
20210827164544427.png
& G, m, U  _: }0 a# Y3 u# h1 \

# j0 _6 n, n# M( E6 m" U& i生成代码完成后可选择打开工程。 # V) F/ z* n! V) X2 o/ g

. V4 b9 P: b& \2 n2 s* Y
20210827164829635.png

6 X0 e5 E9 ~4 k& r2 A5 ~: M, @
二、代码部分
, d& M) b5 P, y8 i( @2.1  接收中断处理  b3 r! \1 c) k; V! _* F' W
2.1.1 接收固定长度:(舍弃): d% B7 N4 Q) }* j
只有接收缓存到固定长度才会触发中断! N# }( m6 i5 K# x9 J8 k' j" d
串口接收回调函数
6 N, V7 N9 e5 k9 _2 R0 z. {# @5 @
* S6 V; g) G5 i( Q  r  |; y
  1. uint8_t aRxBuffer[RXBUFFERSIZE];9 e: x; v: Y0 f6 e1 p! N
  2. /* Size of Reception buffer */
      }! X8 u2 `; k2 `$ _
  3. #define RXBUFFERSIZE                    10, m# H7 v) o& z8 q
  4. / f+ k/ l4 S+ O: k" R- F

  5. + a% e- U4 d/ X6 m- l) q. {
  6. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle): l- Q! F9 {, R8 U) K$ ^
  7. {; q/ A+ t7 y& ]) k) ?* t: d$ D
  8.   /* Set transmission flag: trasfer complete*/
    % s" k+ F$ U6 m
  9.   UartrxReady = SET;
    " g% y! G7 y4 I7 D
  10.         HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
    / x3 i9 l5 q+ k
  11.         HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
    * d  }" R- r+ Y% \2 l$ i8 h* I+ z* `! p- Y
  12.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);( S9 X* T& J8 J/ g3 {% D) Q

  13. # p9 r, z2 o) f8 J+ H7 o
  14. }6 ^, R% J# \; x9 o

  15. 3 p9 @. U' j- j0 M' B
  16. void USART1_IRQHandler(void)
    ; x9 x& Z0 a, U( L
  17. {
    * p( ]4 M" |/ ]& C! d. |8 {5 v
  18.   HAL_UART_IRQHandler(&huart1);" l- v8 d0 m# S& s
  19. }/ `' ^! p9 ?* ?, H
  20. / d/ a& u# W# M: H6 [

  21. 1 ^5 R/ c1 T4 z
  22. static void MX_USART1_UART_Init(void). K) |0 v/ T: C
  23. {
    ) m; j' F: o% x( d6 x+ A+ A
  24. 0 u; g( }9 `! l, K# r4 p4 l8 q
  25.   huart1.Instance = USART1;$ |! f2 {4 `* h, m$ e: G: E5 n3 c
  26.   huart1.Init.BaudRate = 9600;0 o: a9 ]& T6 }$ `) A# [
  27.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    + {' T; z* g% n" Q' g
  28.   huart1.Init.StopBits = UART_STOPBITS_1;
    6 D" G2 j! r' v$ ?: i6 F
  29.   huart1.Init.Parity = UART_PARITY_NONE;) o  H( H( h2 G! L" f$ @  ^
  30.   huart1.Init.Mode = UART_MODE_TX_RX;
    , |. U& b, x) b4 K/ G
  31.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;8 k1 V* z# t. k  O% W4 w
  32.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;* E; Y% S, Y* r1 F0 b  f: R: o( U" |
  33.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    + Z: F' }$ p% D; C1 p0 s
  34.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    : k6 h( v2 e4 l; H
  35.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    ; k& N% T& J! ^$ l
  36.   {
    6 e/ Y3 ^6 I2 \, [9 U* Z" [$ L
  37.     Error_Handler();
    2 D% g4 W) J1 Y! W! y; j( y
  38.   }  4 k& r  f1 U2 [& Z: }8 v
  39.         
    * u6 X% x! X. Y
  40.         if (HAL_UART_Init(&huart1) != HAL_OK)1 x6 j1 g8 W7 f: ~
  41.   {! c4 @0 V3 v) N% y, P
  42.     Error_Handler();& U- h4 T1 c7 d2 E6 k
  43.   }4 y& ^! w& M% X$ s2 T
  44.         6 ~; T) _! ?' J5 \  T; X3 D) `8 M
  45.         UartrxReady=RESET;9 q( A; o, J7 P1 O3 ~' A
  46.   /* USER CODE BEGIN USART1_Init 2 */
    5 _/ @9 D9 M- K$ d( v' ^# H3 d
  47.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK): p, }+ A; t9 f# Z9 S' m) {
  48.   {: I* W$ u' ^7 V* C
  49.     Error_Handler();. c( R1 u9 a; }  w) e
  50.   }# v9 G# \: A1 ^# b* w
  51.         
    * k9 n0 \) @" h
  52.   /* USER CODE END USART1_Init 2 */$ l8 M, Z6 s3 H5 @# {) \# ^
  53. }
复制代码
: m6 U( f) H- p, p! ?" p" `
从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。
" q* n( ?' q  d; E, i2 s' v7 E6 s4 j6 x. p
20210902164819116.png

$ D( |0 D# H1 H5 A- ?3 s  Q) X& M% g0 h1 l+ ?; \9 D# e: a
2.1.2 编写空闲中断函数接收不定长+ ]/ u! _8 w& P% P3 A/ m) E3 N
USART1初始化:
% }# p* T. W8 {2 z
  1. static void MX_USART1_UART_Init(void)
      V% {, @+ G1 D5 t# T
  2. {5 w& k% z! z/ `/ d; }0 C5 S
  3.   huart1.Instance = USART1;
    ! O4 T" Z7 r/ _
  4.   huart1.Init.BaudRate = 9600;
    * e9 V+ G1 [- D8 _- x' I
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    ( F; k. D+ _; \- N$ H
  6.   huart1.Init.StopBits = UART_STOPBITS_1;( C" l- o1 @. z8 t* D8 t
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    3 ]' L& L& P# H3 a5 A
  8.   huart1.Init.Mode = UART_MODE_TX_RX;2 @  z$ ^7 A( d8 d4 A# j" H
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;) X% b+ C0 x$ r
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    9 c1 `$ s7 |* R1 n0 h2 T) ^& k" w
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;* A% V6 ^- i" x6 ?4 A& e: c" Z
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;/ i4 D# p' o# K
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    ' N' n8 d  W# `9 c; S
  14.   {
    8 F: u. h9 T, i0 `5 x
  15.     Error_Handler();& ^; x8 y( t6 |0 w9 K) p! N. N
  16.   }  * {2 A4 D* i: c% G/ V; A3 Y( i
  17.         6 [3 Q: a' \' i- A+ ]
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)
    7 b* L6 j9 u0 r5 {! t1 S7 v
  19.   {  n2 p1 e3 s) [% g/ Q: {1 f. Y+ b
  20.     Error_Handler();( Q+ d6 M- q! \
  21.   }
    ' k9 @/ W1 k) V

  22. 3 U. b6 Z% W+ Y( b; }" H& `) v1 F
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    6 C* y- @: H! B1 K8 V: i. z, w
  24.   /* USER CODE BEGIN USART1_Init 2 */
    # \0 `2 r- n4 z/ p$ R2 Z
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)' |  v8 `( _0 {# z8 @. `' r1 s
  26.   {
    % |0 @9 |) Y5 C" T
  27.     Error_Handler();
    0 n2 q, V! i( i4 O, S; ~2 C' t7 {
  28.   }
    # {: X% \' X3 p" ?+ O1 v8 r; u( i; r
  29.         , E5 ]- `6 ^: ~6 w9 ^/ B. d: c
  30. }
复制代码

) i+ ]+ r6 f+ E空闲中断函数: ( l6 F4 K- p, R+ B  p+ m% N$ B
  1. #define TXBUFFERSIZE                    30; C/ B+ g" x5 E
  2. /* Size of Reception buffer *// q- G0 `% G8 e: d; h8 j
  3. #define RXBUFFERSIZE                    30
    : T; j/ f2 Z5 V6 i5 {5 U
  4. 2 `/ R, A/ z3 K; L( B
  5. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)8 }; b2 A+ j* v5 t5 x
  6. {1 }" ~3 }8 {- O. q
  7.     HAL_UART_DMAStop(&huart1);
    + c) h  T, Z2 d

  8. + s& r) ]  P7 Q$ J- I; V# F7 Q
  9.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    0 M) L' o$ \" [) x) V

  10. * f1 B- b2 d: A
  11. ) N% G: L, o* s+ }
  12.     HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);
    : F6 A$ w9 v3 W" [3 F

  13. 9 U, ~3 W8 O# T5 A6 y  r: p
  14.     memset(aRxBuffer,0x00,data_length);- o' M1 J0 J6 D; l1 j6 Z# v' X
  15.     data_length = 0;
    9 \1 T8 R* W$ |7 X9 r* s4 Z
  16.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);) x; x5 J7 s1 d6 i9 k3 O; X
  17. }
    " O* y9 a! [1 P+ X3 U4 f, {$ c
  18. & x6 S' q' v6 y5 j7 J4 C8 A$ U$ N
  19. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    + A# n* Z8 T! ?
  20. {
    . M( Q# R$ s8 z2 n/ P/ F& k" m
  21.     if(USART1 == huart1.Instance)( L# `+ k+ R; D% i
  22.     {( r! c5 f3 h# D! {+ w
  23.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))0 O) U% h8 c4 D1 p
  24.         {$ k5 c4 ?: U' C1 F& R4 F0 `: y- ?
  25.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);) X0 P8 i( L5 {/ O' X# J
  26.             USAR_UART_IDLECallback(huart);
    ; R! ~5 W1 V5 V# ?5 o3 H. E
  27.         }
    ( Y3 Y8 P; }  W+ K) P  E
  28.     }% e$ [6 H3 z6 y7 S5 f
  29. }7 B/ s4 ]; Q9 E, f' R& N

  30. 8 E$ R/ A! j9 j
  31. /**
    6 P$ F  m' d0 i+ I$ h) S
  32.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
    / G. S! z0 U4 D6 ~$ D2 E5 c" h& {
  33.   */: K1 k( H' z. h! @2 e9 }3 [) @4 J
  34. void USART1_IRQHandler(void)
    # ], c  w) y0 i
  35. {, k5 n& P* r% s' t: p# c
  36.     HAL_UART_IRQHandler(&huart1);2 H9 Y3 j' d8 `
  37.     USER_UART_IRQHandler(&huart1);
    5 [- z0 o0 s! B$ X( R
  38. }
复制代码
1 A+ T6 I1 b* h5 \! P5 t
可实现不定长的接收!
3 N- r" [9 Z/ z' h7 Q
. z" K+ d1 A4 M7 u* Y1 p
20210902171851390.png

8 X  C+ B2 K& _* S5 Y+ z# L
/ e+ p: C5 K$ q- t! h& \ 注意:
5 |# S9 M6 N. f; h$ b, E在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。
( o1 Q. _" ^* d2 O' t/ T1 S( n+ P" p
8 d" }# r9 H* U5 K1 B2 r3 U 三、使用ringbuffer实现任意数据类型的FIFO处理接收数据
4 t! N$ f7 {# i! O使用原因:; b# G. U. w; K6 U& a
6 `' N$ l" {- C" m- W9 U
        虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。& k: B4 H6 o: G$ Y3 H) o7 G) t7 D

# }6 F. g2 a7 V. m( ~/ S6 S        因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖2 ?1 n* U+ p' P

, Q3 d) {# G  m6 ]/ r8 j$ |  T① fifo头文件:; g6 P  |5 g7 m# G% }
  1. #ifndef        __FIFO_H_
    4 d' L6 Q0 M$ I
  2. #define        __FIFO_H_$ D: q% M( {+ x( {

  3. ' ]' P' l. M4 F( @9 I
  4. #pragma pack(4)
    6 H9 L0 T2 f. A
  5. typedef struct FIFO_Type_STRU. Q- @& u/ Z. m+ Y, q
  6. {
    ' i$ i; A' Y. C1 \: V# f  _3 W
  7.         unsigned int                        Depth;                        // Fifo深度
    7 n) b7 E& L5 M4 O+ }; W
  8.         volatile unsigned int        Head;                        // Head为起始元素
    ( r, R3 i0 ?3 Q
  9.         volatile unsigned int        Tail;                        // Tail-1为最后一个元素
    % Y# N* m% ^9 Z7 d; i
  10.         volatile unsigned int        Counter;                // 元素个数9 I3 K" T+ g! B3 K
  11.         unsigned int                        ElementBytes;        // 每个元素的字节数element. ~/ ]- t# p" [8 Q, ?" y2 ~- j3 u
  12.         void                                        *Buff;                        // 缓存区
    * H8 w: ~- g$ H
  13. }FIFO_Type;
    * T) {, X5 p5 o- L+ l. Y) R
  14. #pragma pack(), u9 @" X+ g& Z$ {5 i8 g# _# v
  15. . K; s& h% K5 s% ^+ F
  16. /********************************************************************//**: R5 L7 c& _9 P$ |6 @% u& ]7 t
  17. * @brief       FIFO初始化5 ?9 k5 `) i$ }. E: N. v/ ~6 Q; e
  18. * @param[in]   pFIFO: FIFO指针
    " [) X9 ^( v3 Z4 ~+ y+ T  ?( D  G
  19. * @param[in]        pBuff: FIFO中缓存2 ]1 G+ B9 y# f* e; d4 q! N8 C8 y
  20. * @param[in]        elementBytes:FIFO每个元素的字节数, q7 |3 N* V3 C; f' A; p
  21. * @param[in]        depth: FIFO深度0 c& {( D) d- V: F4 q) k
  22. * @return      None
    8 X: Z. p8 D+ t& ?
  23. *********************************************************************/8 u9 b0 [: s, J7 @0 @, \1 c* J
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);- |! ^, |8 h2 y' ^4 n) @4 J

  25. ! c* ?5 |  k' }  {
  26. /********************************************************************//**& @5 |. J- P+ ^' y! b& m, Y! L  B5 `
  27. * @brief       向FIFO添加一个元素
    " H* a- r2 S5 I) j+ L* L3 c
  28. * @param[in]   pFIFO: FIFO指针3 Z  s+ l; B+ |. S0 G: X
  29. * @param[in]        pValue: 要添加的元素
    ( O/ z# R3 V7 B9 z- ^
  30. * @return      1-TRUE or 0-FALSE
    * z9 i; q$ c, b
  31. *********************************************************************/
    6 b, G0 l! I9 }; z6 H
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);0 d; v% ~! h* B3 @
  33. 9 [" Z2 |; T4 B6 N) j& }) f
  34. /********************************************************************//**& _) E1 G8 U% e+ Q0 t$ J
  35. * @brief       向FIFO添加多个元素
    : G! n* B6 ^1 E% }/ j! ^
  36. * @param[in]   pFIFO: FIFO指针$ u$ O3 P9 d6 _: L* \3 w
  37. * @param[in]        pValues: 要添加的元素指针
    ( U0 t$ L- w7 O! z# P! [+ V
  38. * @param[in]        bytesToAdd: 要添加元素的长度
    + _) I1 c/ C1 D  ]$ X* N
  39. * @return      实际添加的元素个数  ~. N& }- V6 m0 M
  40. *********************************************************************/! J6 h0 ?- t) F, q
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);
    $ }- ~5 O. K+ @* D) [! v1 f; ~+ x

  42. 8 l$ P' F- V% `. L
  43. /********************************************************************//**
    # p+ R, X; ^/ N, |
  44. * @brief       从FIFO读取一个元素
    " E- I' `4 H" l6 A
  45. * @param[in]   pFIFO: FIFO指针
    ( a2 ?1 W% r# N, K  t& N
  46. * @param[in]        pValue: 存放要读取的元素指针
    0 ^: s" D" r- ~0 `4 b' k6 N
  47. * @return      1-TRUE or 0-FALSE
    # A. P- x2 f) r$ _+ U& `
  48. *********************************************************************/: [7 d" U- Z# m( Z+ B) Q5 g
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);# y+ i$ r  k8 ~; Q9 ?4 p
  50. 4 c1 p5 c: t) g- H+ O& P9 a
  51. /********************************************************************//**
    & U  o' Q  w+ e' `& ~9 ^5 _# o
  52. * @brief       从FIFO读取多个元素# T, ^4 |, ~5 f* ?
  53. * @param[in]   pFIFO: FIFO指针$ E& Y2 @3 P4 ~) p
  54. * @param[out]        pValues: 存放要读取的元素指针
    , n1 l# c  X+ b
  55. * @param[in]        bytesToRead: 要读取的元素长度
    ) X- E1 e8 L: }) T
  56. * @return      实际读取的元素个数
    ; M6 Q( b* w6 |- N( w
  57. *********************************************************************/4 w- ^/ n( c) \- F% s( P' l
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
    1 R7 `0 U7 w" ~3 A) I, d

  59. 3 E2 V% q& D+ e7 W

  60. 0 E) t3 p6 D" j' O: r
  61. /********************************************************************//**
    0 ?% [" X; |$ ?& g4 k$ O4 x& V
  62. * @brief       清空FIFO8 ~, W1 M; z! }3 ]* A
  63. * @param[in]   pFIFO: FIFO指针7 F* v6 I0 u& r5 ?) f4 Z
  64. * @return      None4 K8 L" u) R2 F( z! Z
  65. *********************************************************************/
    $ }; q0 L2 ]" e* H1 U+ s5 X
  66. void FIFO_Clear(FIFO_Type *pFIFO);
    ; i4 f+ B% I- d1 c2 y+ a" S3 p

  67. ' S5 a+ |; l3 n9 @; K

  68. # X0 @4 m1 Q5 o$ s7 {
  69. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);
    5 Q, }6 C' K* E7 [4 C6 {; N
  70. - M0 G$ R) C$ ^& }& ~# l& M
  71. #endif
复制代码

1 e6 e2 V: h5 Y. H! _9 t② fifo.c程序主体% W& ~$ J/ z5 K6 y
6 Z6 e0 U" _( i' x
  1. #include <string.h>
    + y% F9 P7 p+ S  i
  2. #include "fifo.h"2 q9 ]1 m8 F: M# H, j/ B3 L% X

  3. # u% c4 h' \4 a

  4. : T* A! z7 n$ z  v
  5. /********************************************************************//**1 e' e, _& x" G: x& \' g
  6. * @brief       FIFO初始化
    ) U3 H) T7 K/ g+ v
  7. * @param[in]   pFIFO: FIFO指针
    5 W3 H% K% c7 E7 T3 g
  8. * @param[in]        pBuff: FIFO中缓存
    1 |( r, V+ d' m
  9. * @param[in]        elementBytes:FIFO每个元素的字节数
    ) F; E. m5 J/ s" p. E1 Q
  10. * @param[in]        depth: FIFO深度4 T$ {$ K2 {' V/ f
  11. * @return      None" J; T: y- {. t( q
  12. *********************************************************************/
    7 H+ E5 B$ _3 B; @3 x2 _* _1 b
  13. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
    , j9 y/ o; @' G% J) Q" C
  14. {
    2 D) R! \2 E3 e  T! Q0 X
  15.         pFIFO->Buff = pBuff;
    9 k* r5 q4 W) ~* A& o
  16.         pFIFO->ElementBytes = elementBytes;
    , `& e% c7 R9 i: r3 @
  17.         pFIFO->Depth = depth;
    " f( J1 I& X5 F6 n9 v3 K  T. u9 u
  18.         pFIFO->Head = 0;
    8 K4 V3 C0 i7 T/ n( F1 D
  19.         pFIFO->Tail = 0;  ]/ p. K# \/ u' ~# i# L+ j: }
  20.         pFIFO->Counter = 0;
    - D  K" j1 o9 z5 v; n( [
  21. }
    . _+ H* L7 j% G
  22. 8 q, ~0 v# e1 ~& h+ N1 M  s
  23. /********************************************************************//**
    % Y+ O) D2 I3 Z
  24. * @brief       判断FIFO是否为空
    . L9 ?% a' n+ i; \* c
  25. * @param[in]   pFIFO: FIFO指针5 n' v& p: u  U1 }  t9 o! N2 T
  26. * @return      1-TRUE or 0-FALSE. A! ]+ d8 y& N2 l$ _  C
  27. *********************************************************************/% c& t2 q  ^2 V3 a. n6 G- h
  28. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO); g) I+ g, ~8 X* w& N9 u6 e( x2 e
  29. {
      H# b% o4 N" f, l) \, ]
  30.         return (pFIFO->Counter == 0);
    ( p# g* X! o0 U: J" b* X1 v+ C  l
  31. }2 Q  Z, p" `  m6 q  Q9 D1 S

  32. ( B0 H/ Z) E* l+ m' r" ~
  33. /********************************************************************//**; ^/ `2 e, d2 W/ a% Y* v/ a2 Y
  34. * @brief       判断FIFO是否已满
      m" A2 ], P- U1 {# w
  35. * @param[in]   pFIFO: FIFO指针
    " |8 e4 D! v" n3 W4 M" V/ p
  36. * @return      TRUE or FALSE4 C3 R4 H6 l3 C6 o0 M8 Q7 H* ^
  37. *********************************************************************/
    5 f! ^& h- `3 w, Z- p
  38. unsigned char FIFO_IsFull(FIFO_Type *pFIFO)! F3 V+ Z; G  G# x$ S, t
  39. {, o( }& Q7 N1 F5 ]0 @. `
  40.         return (pFIFO->Counter == pFIFO->Depth);) r5 [8 k( I) h! W6 Q$ C& O$ ]
  41. }
    9 g( w3 g6 ^$ b% d% q

  42. . O& k9 Q2 G6 k1 ^) A% f
  43. /********************************************************************//**
    ) l" I9 m( p! ]) r$ y# X5 b
  44. * @brief       向FIFO添加一个元素# G& Y* C2 _/ B
  45. * @param[in]   pFIFO: FIFO指针  @% A7 @% U) y( y: Z+ [; R$ b, c& J
  46. * @param[in]        pValue: 要添加的元素$ A* h5 [% t  G" _/ g9 N% M5 x
  47. * @return      1-TRUE or 0-FALSE! c- w! C5 C  M
  48. *********************************************************************/
    2 @, ^7 P& z7 _. u
  49. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)4 c' W  I$ Q3 r# E) e" J2 s0 @
  50. {" ~- j' z- c. u/ X7 @) r
  51.         unsigned char *p;
    / d; o( z' a, s9 L

  52. " @( N) @4 ?* m2 P* n  G. H
  53.         if (FIFO_IsFull(pFIFO))
    1 t! H! _' T* c
  54.         {# e, V* u( a3 w! v5 |
  55.                 return 0;' t% {. U, {6 k4 R9 ]; m* j) F0 g
  56.         }
    $ o) Y- N2 y$ ]6 K5 W$ s

  57. 9 W8 _8 e$ u( n* Q8 Z% y" l
  58.         p = (unsigned char *)pFIFO->Buff;
    6 S+ [# _: ?3 t6 X* {: P, B8 }  }
  59.         memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);! H2 N5 E0 E) ]- j3 ~! s. t
  60.         
    ' W+ j5 w! m4 j6 b6 }
  61.         pFIFO->Tail ++;
    , x. G  N) D. u6 Q+ W4 V% s
  62.         if (pFIFO->Tail >= pFIFO->Depth)
    . t$ s2 |" y) {2 ?9 s
  63.         {0 d" y* k3 e% x6 O5 U4 O: w
  64.                 pFIFO->Tail = 0;% k5 K$ x8 Q+ N$ n# A
  65.         }% C% K' Q& I2 v2 K
  66.         pFIFO->Counter ++;
    5 [; m% ~4 u6 Q3 m8 J9 }
  67.         return 1;7 D& V2 H2 g+ F; e2 c
  68. }3 w2 q0 w8 f* g; q7 t

  69. 8 p4 t& |0 p0 U2 e- G4 t
  70. /********************************************************************//**
    5 D6 \& g% S& l2 U4 \, z6 r
  71. * @brief       向FIFO添加多个元素- b! k" ~2 R. _' l8 S' E
  72. * @param[in]   pFIFO: FIFO指针& r5 I! d1 j5 u* i) L
  73. * @param[in]        pValues: 要添加的元素指针. Z1 I5 M4 X9 S
  74. * @param[in]        bytesToAdd: 要添加元素的长度
    9 s7 g, C8 p/ @7 Y9 n, C2 v
  75. * @return      实际添加的元素个数$ u4 E8 S- I' x5 `! J- w
  76. *********************************************************************/
    9 p4 t3 S8 w* w9 ^  M  |
  77. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)
    7 P. I7 ?5 l# K7 l# a
  78. {
    $ K3 T" f. b2 K0 ~
  79.         unsigned char *p;
    2 z* F# Z. Q' ~, Z, |# k0 n* |3 u% O
  80.         unsigned int cnt = 0;
    0 R$ H( P7 Z: M3 y
  81. 4 l2 w9 p- w. [5 `
  82.         p = (unsigned char *)pValues;
    / _, x/ d6 y: V8 @6 n+ V9 v
  83.         while(bytesToAdd --)
    2 i" ~% a) W1 ^
  84.         {
    1 P& v) Y! Q* s4 m0 e* S
  85.                 if (FIFO_AddOne(pFIFO, p))
    6 r5 @# n: [) @' X  H# ~
  86.                 {  O% L0 ]  [- z& Z" i
  87.                         p += pFIFO->ElementBytes;
    9 @& W$ I3 v# H4 O8 Z/ l
  88.                         cnt++;/ t8 l) H( b- H  _
  89.                 }
    ' c& n. R/ q& m& M
  90.                 else
    + l; K) X: g- \) \. j: D* a
  91.                 {
    9 H2 ]8 v+ _" K* X, P/ O
  92.                         break;
    ; x  n7 n! P! g0 B. {+ D8 N
  93.                 }
    4 Z9 K7 j5 |( W. @2 p
  94.         }
    ! j1 c3 m( _! P/ a( ~

  95. - I. B& G% U/ E* I, W6 i1 ]/ F4 c
  96.         return cnt;  Q& x3 q2 Y7 U: P1 D
  97. }! r1 x7 Y* R4 ~9 p
  98. 3 x4 a7 C2 x. j' P" h
  99. /********************************************************************//**& E, [, Y6 ?7 O
  100. * @brief       从FIFO读取一个元素
    - T+ F: K4 d  w; Y$ f0 e5 f
  101. * @param[in]   pFIFO: FIFO指针% a  P" S/ q+ z& p; S+ ^3 h  ?" e
  102. * @param[in]        pValue: 存放要读取的元素指针" c& u6 J; g! k2 v7 W
  103. * @return      1-TRUE or 0-FALSE
    7 f: X% a# G% I( B
  104. *********************************************************************/
    , R) C4 E- c: v( ^7 {4 U
  105. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)
    - ~; I8 g1 j0 p2 ]* a
  106. {+ n7 `7 l# X7 [& I+ B  @
  107.         unsigned char *p;, w4 i2 B+ L8 i2 ~- Z7 R8 @) Y
  108.         if (FIFO_IsEmpty(pFIFO))1 n3 S0 @. T) W) z; H3 u/ l
  109.         {" |6 a2 e' d0 b& F* S7 _- Z
  110.                 return 0;
    ; _  f) L5 D3 d1 r/ {( N
  111.         }( Q1 B2 v( M8 N' f+ R2 X/ H: _6 R6 K3 b
  112. 3 i8 M( a! {& I& W2 ?
  113.         p = (unsigned char *)pFIFO->Buff;* i# q9 C7 E* x+ K( K( r$ X
  114.         memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);- C& o6 b' U4 u. b  D, ^
  115. 2 g5 q3 J# J; J  m& R' B/ x7 O9 I
  116.         pFIFO->Head ++;# d3 Z" g  }5 |* z6 ^
  117.         if (pFIFO->Head >= pFIFO->Depth)
    1 H: B- F. b6 @# t8 @3 d, o! I
  118.         {7 C8 C6 k- q$ S  b- R. }6 m# o
  119.                 pFIFO->Head = 0;; A5 A/ T- k1 e) N+ ~1 \
  120.         }5 ]% M+ k( _1 @
  121.         pFIFO->Counter --;" N9 x( v4 E" m; I9 W

  122. . d: M6 b! Q$ ~* U6 j( P; J
  123.         return 1;# N9 y/ U9 k& R
  124. }$ \* J+ D! P& g' y

  125. 1 c* b( G! u/ M: {* ^1 W
  126. /********************************************************************//**2 x9 k. L$ G8 r: B
  127. * @brief       从FIFO读取多个元素2 h* G. X: O- ?+ s5 d
  128. * @param[in]   pFIFO: FIFO指针
    + s% \& X" D1 \0 z. a4 K& a- y
  129. * @param[out]        pValues: 存放要读取的元素指针0 G2 O3 j+ R5 |
  130. * @param[in]        bytesToRead: 要读取的元素长度
    5 X" e6 `9 {1 S+ q" v% Z0 S7 [5 k& k
  131. * @return      实际读取的元素个数! s, [% x" A6 }4 h+ q
  132. *********************************************************************/: v/ O/ ?" a5 a0 W& V2 f/ a
  133. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)  Z( x# J8 ^9 k, i" p) i# }
  134. {) D" ?6 w, V2 o9 H7 V: ?' R; |
  135.         unsigned int cnt = 0;
    & J  T" @) j- m0 @1 n+ ]/ q
  136.         unsigned char *p;. L: P/ h. \5 m! V- V
  137. 8 _/ X! K0 G2 E: @; ^- F
  138.         p = pValues;  N* Y- Y4 T! p/ w: K' o2 P
  139.         while(bytesToRead--)' C0 D" U# q' G0 g+ c6 c3 B
  140.         {
    4 u1 ~% U; z! l& g+ t8 X, w1 ?
  141.                 if (FIFO_GetOne(pFIFO, p))* B8 C6 X8 `# U6 X3 t8 y- a1 G) `
  142.                 {
    * i  E1 x5 k& O
  143.                         p += pFIFO->ElementBytes;
    5 V5 d# |1 U7 l
  144.                         cnt++;
    4 _+ ]- u* _% b. m3 R4 ?
  145.                 }
    ; c4 b# X0 h% ]$ I7 ~+ e3 m; P. \. d
  146.                 else
    ! E8 z$ _8 {1 t
  147.                 {
    , A1 y  u! d0 l/ A
  148.                         break;
    . i" v" d* d" l* o! x
  149.                 }  |( Q, ~& |2 k1 F+ a* o
  150.         }$ _% v" a' Z. r! ?7 |9 ]2 J/ P0 ^
  151. # y- B% i$ ^5 R+ N. W
  152.         return cnt;- O6 I; s: R2 D" i/ Y" ~
  153. }+ i- k7 m* I# S/ H2 X* r
  154. . H! Y" l# |5 Y' O' y* g
  155. /********************************************************************//**
    2 b) e. j3 ^3 D
  156. * @brief       清空FIFO8 C. ?; s* @* ?2 V& C7 S# \5 I2 V
  157. * @param[in]   pFIFO: FIFO指针  Z( D: y" L8 y* o( S$ O9 T& h0 U$ {
  158. * @return      None
    - ^4 Z* Y, I3 Q; n% F
  159. *********************************************************************/
    0 O2 h! @  {' X' W. }8 |" K
  160. void FIFO_Clear(FIFO_Type *pFIFO)
    ' H. `2 Z1 @+ ^* D* l! N2 ]7 M' ~
  161. {
    & [. c9 j) F6 i. d& H. T
  162.         pFIFO->Counter = 0;1 v- i) Y/ `# b8 p. `0 o* C
  163.         pFIFO->Head = 0;
    2 K8 v; `- f1 F5 }9 k! G8 T
  164.         pFIFO->Tail = 0;  r- A% h7 n3 e/ o: l. x
  165. }
复制代码
; C4 g3 n1 x: z7 Y" t
③ 串口初始化- `' M% y6 I$ ^* z. K
  1. static void MX_USART1_UART_Init(void)! |/ @; W9 G, c% `0 y5 K" D
  2. {
    7 q- g  Z  A4 Z: Q
  3.   huart1.Instance = USART1;
    4 O1 |! y" a8 ]. o9 f, K
  4.   huart1.Init.BaudRate = 9600;: u0 S/ Z0 ^  u3 S" M
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;) b- f0 M( r" Z6 Y% R$ b
  6.   huart1.Init.StopBits = UART_STOPBITS_1;
    8 ~2 ~) c9 m" H6 G% F6 w
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    ; w; p" q& d2 _$ V% J  O
  8.   huart1.Init.Mode = UART_MODE_TX_RX;4 D* G2 I- F8 V! {+ \
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;6 z* ^9 @( q$ x- u. k
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    0 x6 x( y, ^6 F6 H5 ]2 c
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
      C1 P1 @0 D- m
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    / w5 r# ]$ h9 m& }( h! {
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)3 H9 t, m: k* w1 ~
  14.   {+ W+ m, M  r1 H2 h' f
  15.     Error_Handler();
    ' t; o; v! |/ e# `: U; y
  16.   }  
    # s2 W: ?3 j" G
  17.         
    6 Z# Z, q; O/ J7 K3 T
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)! L* |  K, s% I/ K# Q/ @$ l4 b8 ]6 n$ L
  19.   {
    / x, l* p3 J7 J
  20.     Error_Handler();
    , \' l0 u# H# }* c3 S
  21.   }# s# m* u! e0 K5 x+ c
  22.         
    5 e) P$ c/ [" U( u: P5 N8 P
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); " h4 q: b0 s) b; G7 M1 s# B0 n
  24.   /* USER CODE BEGIN USART1_Init 2 */5 t5 D( {0 h- m( h/ P4 q6 Z. p6 U/ n
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    3 d3 ~* ]' A* m1 o
  26.   {
    $ J! D$ M3 |( Y: u7 B0 n0 D* B5 g
  27.     Error_Handler();
    + u' Q" u; I/ ?
  28.   }
    3 s( s0 T! g5 h# O2 v
  29.         
    " L0 _* r' n4 U
  30. }
复制代码
+ Q4 I3 C3 K# X1 _$ y
④ 接收空闲中断
# c0 K9 u$ m' W9 b5 {. f# d
  1. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
    4 L/ h5 ]2 P/ @# K. L7 ?! v$ `( q" f& I
  2. {3 ?7 W% [: F) ~* u
  3.     HAL_UART_DMAStop(&huart1);
    ( O' m, M' w3 z
  4. " m# w' v# H5 N1 ]5 U# }$ B0 _" e
  5.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    3 }! Z, Y2 v! P, A
  6.         
    # c5 j' L6 B/ c: |% z
  7.         FIFO_Add(pfifo, aRxBuffer, data_length);. p% P) h- U8 a$ d* \* e7 Z
  8.     data_length = 0;1 k9 q9 u8 f4 t" U& F/ s
  9.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);$ X/ W1 ], O7 r% v3 P
  10. }9 }3 D) ]0 d/ }7 w& {
  11.   _* g6 ~! R/ }
  12. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    " V. I$ e. e% T8 s% }  @. g
  13. {
      r# }' J+ Y  M3 e  t, E" I
  14.     if(USART1 == huart1.Instance)
    3 X+ j/ O( t  X7 T
  15.     {
    8 {1 k; w5 z. @- c( B
  16.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    / P) j$ a8 ?  H! A7 q& |
  17.         {
    8 L) E. o$ |' P4 T6 v! a0 m- H
  18.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    + h6 ~0 _! u+ w. ]# `
  19.             USAR_UART_IDLECallback(huart);( Q  q4 t: t9 D8 ^
  20.         }8 N& c& N7 {& e- n4 V$ O$ Y. W
  21.     }
    9 {1 I) b0 q( Y8 z) d2 i
  22. }
    $ E0 R2 C# l. T

  23. - d) I1 W0 g" J6 _. F6 M
  24. /**
    : T0 k! \8 T0 M3 _, O. n
  25.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
    0 d' A, m+ l3 m, u2 C* c' p( i( U6 t
  26.   */
    2 z" P, M# i) R# J( [
  27. void USART1_IRQHandler(void)3 k0 J0 j5 Z2 e
  28. {
    4 u( c% V; m+ J
  29.   HAL_UART_IRQHandler(&huart1);/ j/ r! G& a5 |; |( y$ ]
  30.   USER_UART_IRQHandler(&huart1);
    2 ]: H$ J) s# e) T
  31. }
复制代码

5 ]( b6 q. g7 {4 [( Z- D⑤ 主函数调用:
+ n7 Z2 T2 V" ~  L9 y
  1. #define TXBUFFERSIZE                    30
    # v3 n  M" k; k0 A  [1 v* w  L$ m
  2. /* Size of Reception buffer */
    " R, n3 H0 P- w7 O6 H
  3. #define RXBUFFERSIZE                    TXBUFFERSIZE
    " _- E* G8 h9 v1 t4 N/ |7 k
  4. #define RXFIFOBUFFERSIZE                TXBUFFERSIZE * 5  |# t1 r+ z/ n) b3 V4 Y
  5. - R$ @1 Y' \* g* S% t! g/ \1 s: m5 s
  6. 8 f2 r" k# [* n; ~
  7. uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";/ P9 E# j2 A. y
  8. - ^5 |, E% i- E+ k/ \! g
  9. /* Buffer used for reception */3 A4 b0 w7 L8 f. ~% v5 p3 R; X$ }+ Z
  10. uint8_t aRxBuffer[RXBUFFERSIZE];
    * o0 `3 Q; ~0 z

  11. $ P( o, y( ~5 g4 O0 v
  12. uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];! k$ ?  m) b4 i
  13. FIFO_Type        fifo;1 H: h' P) V  ?! y; b4 \% g( r# f
  14. FIFO_Type        *pfifo;
    & k. [: h7 D+ l/ g" V2 E! t

  15. / S9 B# g" T3 i  u, V
  16. int main(void)
    . a$ a* Q5 S/ W6 H5 C: [) V, e9 M
  17. {
    * Q. f, P3 m3 \, ?9 C
  18.   /*此处省略硬件初始化*/
    . {, t$ L+ a3 m$ ~& Y0 p' u# G" O
  19.   if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)2 S, r9 f8 V0 [7 B
  20.   {
    ( R8 s6 m! L2 n$ B
  21.     Error_Handler();7 e8 Q. P& P1 F
  22.   }
    % ^" r8 \3 F# N0 A% \4 f
  23.         
    " S5 k3 L3 L# r6 E
  24.   pfifo = &fifo;
    7 V+ [( p1 o) a" A3 U$ J( R

  25. 2 ]4 d/ U& p. @8 m  v+ `/ P! c
  26.   FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
      c* G. o0 f1 I' W  ^8 Q* Q& [
  27. ' \( w+ i* z+ @9 \
  28.   while (1)* `' z# J& a, U3 A
  29.   {/ `* P0 J3 t2 X. V2 m
  30.         /*一次接收的缓存,重新发送*/
    & j& B/ s9 o& H) u' r9 W  z
  31.                 if(!FIFO_IsEmpty(pfifo))
    3 q" r( i+ t6 i
  32.                 {
    * t$ ]& P4 `& {9 n
  33.                         uint8_t a[100]; //存放读取fifobuffer的数据
      d: E6 x# \7 J/ t
  34.                         int i = pfifo->Counter;//先保存接收缓存的数据个数
    : g! k3 `2 U# @. i
  35.                         FIFO_Get(pfifo, &a, pfifo->Counter);
    3 S0 K2 O% [. `4 d; f* k
  36.                         HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率+ X: q8 O5 t; z7 Q* Y
  37.                 }5 y6 _& G& N1 U  q( h& [# R
  38.   }
    ! {& a0 L/ m- c# F
  39. }
复制代码

# `2 w0 A, y9 M  ^5 J* z测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
3 q4 ?- f% a# m- V
( M+ B, H. r0 l) ]! p5 X
202109031459585.png

. E7 n8 @9 O7 O7 }. d
9 ], X& Y# t* M8 T% h问:关于 stm32 HardFault_Handler问题处理?
7 q: |7 ?+ K( n- U6 F0 [. _5 B
$ R$ |4 k: V8 m% ~5 ~1 w; h  ~ANS:( D2 |# _7 u7 m$ B: {* K
- e, {0 z2 j9 ?
        在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,
. x. m& V( e/ y2 Q
! t7 ]( X% G8 m6 [& S, w8 q
20210903150306628.png

3 d2 ?6 f3 e* q, v
  \9 l" f, ]0 j6 e& f! |3 ~
20210903150316369.png
8 e4 Z# @1 [- l* S: [; e( O9 H. K4 v
4 {& q+ y( b' E8 B
最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!/ k6 n5 E5 }) i1 |  H( o% ]
  1. pfifo = &fifo;
复制代码
# @: N& R0 P: ~5 k  s0 K2 m

* p6 C/ \4 y" V. {# d9 R2 \/ h5 {
6 C  O) w5 j4 O& {) ^6 Z, h9 t
! w5 O, ]4 R2 I$ n
收藏 评论0 发布时间:2021-11-25 15:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版