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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
一、STM32CubeMX开发5 S9 D/ Q& g8 H, K  U2 ?8 _" b' a4 C
1.1 新建工程
! L6 o% F& n6 l  ], [" Tfile -> new project
2 K% L# E6 j6 f* f! X9 H# E
$ D. P% x3 g+ r& Z4 b4 c# u* P选择芯片-> stm32 core内核         . o( h9 m6 [, ]
5 f) m* }7 z( R! D. O
                   stm32 series 系列$ g. N% h! r# w, R* f9 b4 M+ y
( C( f! K8 U( D  J% \7 C1 \  l
                   stm32  line
! P5 W) B& I* G: k+ M& }* O; Q( u: E# |8 K+ z' z
                   stm32  package
& Q8 P: g. @& x$ s) A: Y" U, B- w  c" f, s# S- k
选择芯片根据自身需求去选择,目前该项目是stm32f0系列
5 x! T% J; l1 a# \, q. e# h% ^! T  T& R9 A8 L  d
                    stm32 core内核         M0
) b- V0 w6 w" Q
( Q7 t+ D; G$ Q) d1 V/ w                   stm32 series 系列      F0
' U& K, J- A1 U- ^  \; f9 _% K) Q
* o4 u0 n; v: w) y2 g! ~5 m( B                   stm32  line                 F0X12 P: P4 K& ^6 S. p9 m6 e. }
1 j) [2 g* P+ b, ~& f
                   stm32  package         TSSOP 20: ?: Z1 ?% X! J. G
7 w% b& e: A3 w
1.2 配置 USART1
  q9 k% T8 i; ?& [3 @配置 USART1 的模式为 Asynchronous,即异步串口模式
( Z' w4 t8 c0 ?* v5 c) a5 f; ]+ w
5 f) a9 z6 R( M! `) Q- p! X
20210827163252369.png

$ F. n$ M8 \3 W" y! ^9 b! z0 G8 x/ n+ f1 r& m" A8 |  ~, K
1.3 配置串口参数
7 u# X: B: @7 m* @8 G, y2 T! d 根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,19 P; N: ^$ t( Z' L

8 z7 Z- g, O. G/ T( {
20210827163448427.png
8 h$ h, @' ~& o3 _5 Y7 N

7 b- r, [* Y( o' T, | 1.4 设置DMA
- B1 _7 Z% f5 f7 F& ]# K2 ?9 D( F: o8 d6 _1 t# }
20210827164240955.png

2 m  d- k8 T& S% y8 |! q6 Q- i1 q6 r  b6 f
1.5 添加串口中断
1 V' M& j8 z5 ]. K" W  _* U6 v2 K; L, j* E; X; p- g* h
20210827164323729.png

) G8 g8 Z# J+ X# O4 ?) D" f0 A; K5 q$ g  I! v5 D6 H
1.6 生成源代码。: B: ^0 b6 P: D' ]' f1 c3 R
在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。
' h2 z5 e- D- ], T5 n  f
3 m: i0 O- q* Z% {
20210827164544427.png
- \' S  }$ G* l% W7 K
. J& r+ b6 _# _
生成代码完成后可选择打开工程。 : |3 `% G" ~4 U4 W8 q
/ D2 }! s( ~6 n" f- R
20210827164829635.png

3 Y) P0 t1 k- @$ i' ^: M2 s0 x; p0 C# R6 q; m
二、代码部分
5 h0 ?8 w& H( {8 m- y2.1  接收中断处理
5 e3 w! G. C+ k- F! [2.1.1 接收固定长度:(舍弃)
1 E- E; Z8 [& Z7 V1 V9 J只有接收缓存到固定长度才会触发中断
* s) |, ]: d) R: e7 c+ u串口接收回调函数
  [- M& s! O* ?6 ?1 n: Z1 o. ?% h0 ^' \/ D$ P* z% p
  1. uint8_t aRxBuffer[RXBUFFERSIZE];8 I. M# p" U, V7 Z6 ?/ Z" L4 |8 s
  2. /* Size of Reception buffer */
    ( P- x! N( c" e: o1 Z. {
  3. #define RXBUFFERSIZE                    10
    + _+ T8 k# z: t, b3 q

  4. ; f# L, s2 |: G; m; q
  5. " _2 p' _5 J% t' x1 l3 z" b, c
  6. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)- L" M" y' D9 }
  7. {
    ; ]9 H" `1 n9 `3 `  q! G4 F
  8.   /* Set transmission flag: trasfer complete*/9 ?2 Q: D* m2 l' ~4 }, A$ e/ G
  9.   UartrxReady = SET;( \# q+ V0 s6 \- @
  10.         HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);' [( w6 l4 {, h5 h* X8 H
  11.         HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
    9 _3 t0 z0 T4 N3 E
  12.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
    4 y6 ?- d5 m* k5 b* c; j
  13. 6 Y( Z/ O* y% |+ O1 n( y
  14. }. [6 C" P/ w9 G, V

  15. 4 ?5 @3 }$ j9 g' h: {/ S
  16. void USART1_IRQHandler(void): b# M; z! z6 B( ~2 y( }& V
  17. {
    ! s( q5 `; p  H8 ^
  18.   HAL_UART_IRQHandler(&huart1);
      i0 H" V$ l7 J5 \5 V) d1 i7 K+ W
  19. }
    6 i3 w5 \( J5 V# g
  20. * s' z; b1 y6 t( M% [

  21. . V1 u% V) a7 v  R2 X1 ~
  22. static void MX_USART1_UART_Init(void)
    7 `7 O, Z2 o6 v4 z5 G8 E
  23. {! I+ z! v2 K8 x$ Q* E6 J
  24. * h$ _- Q  y! g# T( e* R
  25.   huart1.Instance = USART1;
    % ~) \2 L2 a; f9 |3 `
  26.   huart1.Init.BaudRate = 9600;3 c' n7 W" Q0 N
  27.   huart1.Init.WordLength = UART_WORDLENGTH_8B;3 a; l+ L" j! X) B5 i  ^
  28.   huart1.Init.StopBits = UART_STOPBITS_1;* v! {. W" G0 K9 f. N! z
  29.   huart1.Init.Parity = UART_PARITY_NONE;
    , G) p: ]$ x* S
  30.   huart1.Init.Mode = UART_MODE_TX_RX;
    ) x3 C8 b' w! K! a6 x: I1 D
  31.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;  P, w! ]. o6 r- S! O
  32.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    ; ]( W: f+ U. S& d- i
  33.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;& {9 @& c* }' @
  34.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;) h' }$ U# R' P6 \
  35.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    ! o) }  R# \- A( H* j) M& ]1 [+ ^
  36.   {  i& ^% O& }) D3 J" D# b% ^* w
  37.     Error_Handler();. E2 J# F, j8 L& {/ N
  38.   }  ' M# f; d6 Y2 |3 U( L8 A: o
  39.         $ i: o0 j2 ~0 H" R0 }
  40.         if (HAL_UART_Init(&huart1) != HAL_OK)
    2 o: [5 O- a$ Y- Y$ B& h4 e
  41.   {/ d. @( [4 G5 S1 I8 v- e: K& g
  42.     Error_Handler();# H  C) T( |! a6 z0 K  W$ \
  43.   }
    . R1 J0 J) \2 ~6 O3 h) ]$ a
  44.         
    ; Q+ y4 J6 @4 i; Q* W
  45.         UartrxReady=RESET;
      Y& O3 X  S- a* n
  46.   /* USER CODE BEGIN USART1_Init 2 */
    8 ^7 h* [  Q% ?  z
  47.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)! W( A0 O$ }3 o+ T$ j4 \  Y4 n
  48.   {! o, e8 M" R* l$ Z
  49.     Error_Handler();% H1 m0 g% m, f/ T6 K6 z/ c
  50.   }- M- C' Q$ [7 t* f# G& [& _
  51.         * x- G  Q2 v4 Q: q/ y9 q5 ^* D
  52.   /* USER CODE END USART1_Init 2 */
    8 X4 n# y- X2 E2 j% D- y
  53. }
复制代码
+ P- M8 j8 p: H. U' u: [
从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。2 E2 B  E7 Y" G! _/ d

( P; w3 n5 K  i; Q2 ]
20210902164819116.png
+ P. y$ }, q$ W

) k$ H2 U4 X9 ^3 s2.1.2 编写空闲中断函数接收不定长
. f4 h3 C& `% w, wUSART1初始化:
3 s+ |# Q. {1 d. Y/ t- g4 P
  1. static void MX_USART1_UART_Init(void)6 [5 T+ P9 T9 d6 g
  2. {' l2 ]  `: F9 I6 x
  3.   huart1.Instance = USART1;
    # Q# K! i4 o' u2 a; b9 r
  4.   huart1.Init.BaudRate = 9600;
    8 c3 W, Y5 `: H0 x
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    - U6 R1 ?. }- O% r' U# S
  6.   huart1.Init.StopBits = UART_STOPBITS_1;+ t$ S' M: ^8 o: e- Z
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    # G) k. R4 p- F& c
  8.   huart1.Init.Mode = UART_MODE_TX_RX;
    + p* t' z0 ^6 Q
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;( U  y* r8 C! T* Z: v
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;1 L. s' I) h! t4 z6 p; o+ U3 N
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;2 D7 u9 Q, e$ x1 ~
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    7 L8 q! Q- }  R$ G* z3 E! \
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    - Z' U3 U# A9 u, i. G+ M. x! R( l5 i
  14.   {" i! L/ i2 W8 r; _. U5 @" ]& S, ^
  15.     Error_Handler();; t* N" T. U$ d0 o
  16.   }  ( ?+ d, `/ a$ C- M$ T
  17.         5 ^6 B) Y# ?) {: X# u- W) j/ k
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)* ^' m2 O8 _/ P' g6 v* R
  19.   {0 ?1 S# s5 d5 Z& M4 w/ |7 q& H
  20.     Error_Handler();( W, D: c$ [/ c5 `
  21.   }3 w! y+ s7 ]/ Q0 M; Q

  22. 6 N, H0 r, }7 s/ D- ]  p$ Q
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 8 X* f+ k! b  H
  24.   /* USER CODE BEGIN USART1_Init 2 */
    0 k4 R4 H) p0 A
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    9 o& n" d; b- {( A$ ]/ V" d6 ~& ?
  26.   {( {; y+ d. I% o
  27.     Error_Handler();: E3 u5 I% g* K  }! S+ U
  28.   }" l9 L! ]! A6 A* ]
  29.         1 s6 @1 B' }* {
  30. }
复制代码

3 m* F( \: ?- z7 |  ^4 d, H& m1 B空闲中断函数:
8 ]2 b8 ?. v/ N3 A4 k* [
  1. #define TXBUFFERSIZE                    30+ X# E9 R+ h+ {  T5 I8 S4 t9 S
  2. /* Size of Reception buffer */- \% z0 S. F$ G; x; o
  3. #define RXBUFFERSIZE                    30
    & L& a2 J- f( m1 s
  4. , j9 K  Q$ N' u( E$ ?) Z* p6 J/ h$ ?
  5. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)& K+ N6 S' i* s, {. O: _1 B- n) {
  6. {0 j/ S( P( c; I4 l7 \
  7.     HAL_UART_DMAStop(&huart1);7 ?! q" j3 t8 M+ K/ S# ^- v1 ]
  8. . L" I1 t; i: P
  9.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    8 K" g0 k( W- m, ^. {$ i) ]& |  ~4 `

  10. 4 P2 Y5 q8 J; f5 \0 L% @6 G
  11. % E! f/ L. ^1 r/ h/ \7 @
  12.     HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);
    6 A! h+ S# ?  Q: r
  13. 3 M1 Z+ v3 G2 Q. [4 s( E
  14.     memset(aRxBuffer,0x00,data_length);
    2 {7 o0 P# L" J. f! K& j
  15.     data_length = 0;
    2 {( M/ }/ m1 P7 q9 |
  16.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    ( f: N, w! B# _
  17. }' i' u+ ~. W0 m

  18. , N( L, {8 r, Q3 l* w' L
  19. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    0 u/ I, [* [( m
  20. {6 \- K: N, i0 ]& r) B
  21.     if(USART1 == huart1.Instance)
    ! c: R4 t+ `. g+ o( k; ?( E
  22.     {
    - }4 D& {7 l2 Q
  23.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    ) g5 V9 P, W* }
  24.         {, D4 _* H" B. Q$ I7 @6 k
  25.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);" p% l1 o( E) g& W
  26.             USAR_UART_IDLECallback(huart);
    4 T' U! L# m8 Q1 z
  27.         }
    ; \8 d) t" B" D  \/ L
  28.     }  Q7 S* L0 m8 L
  29. }8 U& n$ ~- p) ?! o: D, a; S
  30. * X: f) R! ]" u: f  y% C
  31. /**
    ; x8 x+ E* y, [
  32.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25." \5 U& z, X1 R
  33.   */
    . G0 g5 S% `  M* V
  34. void USART1_IRQHandler(void)# F, r) K# r1 s2 p7 n3 u
  35. {
    & u* G. @) J& ^. W: s2 E
  36.     HAL_UART_IRQHandler(&huart1);
    ) n9 x+ J$ s9 a4 k& U! o( |1 t
  37.     USER_UART_IRQHandler(&huart1);
    : {' n' S/ j0 c5 I$ P9 \/ D
  38. }
复制代码
* z& p* q4 }, `" T7 u. A8 i
可实现不定长的接收!
* q; E* E, b5 J
+ K* y8 e- M3 k4 E  |
20210902171851390.png

! ^; E% U. a3 B, h; ?/ T! x4 y" ?  X4 S6 C2 R2 N
注意:
2 Q9 @% @* v7 l, \! K在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。
% l! g0 O$ V' V+ ?1 L$ j5 ~3 ?. V
) D5 E0 [  |, J7 g 三、使用ringbuffer实现任意数据类型的FIFO处理接收数据5 ^2 Z7 m6 z# S0 W/ ?* b0 I
使用原因:' I% H9 ]- i5 H8 W; @

; a1 g$ m) M- Z* S/ K        虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。
0 ?4 {7 t$ O& }3 c2 i) |8 X2 _+ Y
# ?/ K9 Y! ]1 S6 ]) L* q        因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖
* X6 G$ c4 R, R/ {& n9 N
; Y  u) z; g! r* }' m" t① fifo头文件:. q5 s& H/ \6 G' ^8 @" @
  1. #ifndef        __FIFO_H_
    6 s+ j" t& o+ Z  t! J+ x# I$ q; Q- B8 Q
  2. #define        __FIFO_H_4 s7 c2 F3 }- H3 l

  3. ) O- i9 @9 h6 F
  4. #pragma pack(4)
    7 r4 p" S4 I6 ^' y$ U! A6 X0 O+ c
  5. typedef struct FIFO_Type_STRU
    # s# U1 w% W: U. H; h2 c
  6. {0 m+ X7 z/ F  O% D0 N# y) o2 s
  7.         unsigned int                        Depth;                        // Fifo深度
    + J8 L9 k/ m* M" G3 [" P, w2 W
  8.         volatile unsigned int        Head;                        // Head为起始元素
    2 x; U& [' e8 \& Q) D0 Q2 X- ^
  9.         volatile unsigned int        Tail;                        // Tail-1为最后一个元素+ f, y# A2 S& E4 b8 {
  10.         volatile unsigned int        Counter;                // 元素个数
    + \& s7 J! [. r0 D
  11.         unsigned int                        ElementBytes;        // 每个元素的字节数element
    ) ^* B0 Q" k/ x4 g+ J: |+ J
  12.         void                                        *Buff;                        // 缓存区( f) j- v, q8 k! g( J
  13. }FIFO_Type;! k# C5 y  C$ R7 {2 G' G
  14. #pragma pack()& l/ a% S  M" u

  15. % T1 `0 L/ d5 e7 X- S$ `% d
  16. /********************************************************************//**" h* ^0 f7 \! I" K( l+ q6 P
  17. * @brief       FIFO初始化
    $ a; {2 s& }( ~0 O1 F
  18. * @param[in]   pFIFO: FIFO指针
    . r, K* K% g8 J- ]) p4 Y4 U
  19. * @param[in]        pBuff: FIFO中缓存" M/ B1 o3 Z6 y' u8 [' i
  20. * @param[in]        elementBytes:FIFO每个元素的字节数/ v. A3 W+ B0 t  {
  21. * @param[in]        depth: FIFO深度8 l# z/ m2 C$ A
  22. * @return      None
    3 E5 S7 @+ n& l8 J$ Z9 K
  23. *********************************************************************/5 s4 f; A: [: n# X7 _" R  _& m/ e
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);3 C" N( n  K7 Z/ ~8 g
  25. # u( |! ?( L1 r, M
  26. /********************************************************************//**
    / I& R. f4 e* m  C1 Z& y3 A( j. K
  27. * @brief       向FIFO添加一个元素
    5 S/ t' a0 `! l& k
  28. * @param[in]   pFIFO: FIFO指针! k# e2 ?9 \  H; M& G
  29. * @param[in]        pValue: 要添加的元素
    # v" I& f. @( }1 M
  30. * @return      1-TRUE or 0-FALSE
    - F" z, M, Y, j1 Z
  31. *********************************************************************/
    0 V) F% _, H" K4 m5 f6 z
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
    & K2 u" U& d& }% g& W7 o$ P  a
  33. ' `, _3 X. l5 ~: H5 j) A
  34. /********************************************************************//**
    9 k- Q# q; l  u0 [9 @( H3 a+ I
  35. * @brief       向FIFO添加多个元素( ~8 x' ?' O' E, ^5 ^# T
  36. * @param[in]   pFIFO: FIFO指针( ^2 \  m6 i/ b& {0 {* O% R
  37. * @param[in]        pValues: 要添加的元素指针
      p) p% T# i0 c3 y) `! @/ c1 B
  38. * @param[in]        bytesToAdd: 要添加元素的长度
      W! g/ d! K4 P) }2 v, l0 a( Y' n
  39. * @return      实际添加的元素个数
    % _/ `4 m, N, |+ K: X7 J
  40. *********************************************************************/
      c: ~* \/ `; A& J
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);! _* K* ~: _: v, d& ~* V

  42. % c" V( @& |* y2 i% g
  43. /********************************************************************//**5 G/ n; U% z% \
  44. * @brief       从FIFO读取一个元素; z7 }. O6 [( W0 S9 S
  45. * @param[in]   pFIFO: FIFO指针
    + j, M# ^6 [! A
  46. * @param[in]        pValue: 存放要读取的元素指针
    ) n0 x3 k2 k4 Q& ]2 i; C7 N9 i
  47. * @return      1-TRUE or 0-FALSE8 T! W: R% T  k! F5 W3 p7 a( c
  48. *********************************************************************/5 Y; n6 i( H; g
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);5 B" z5 r: r$ x* R+ S8 b( u4 N

  50. 0 K  A- C2 k' M( @- A) w1 f, |
  51. /********************************************************************//**
    1 P# W4 U+ j: }. k3 T0 F
  52. * @brief       从FIFO读取多个元素
    ! J7 `9 u5 r0 [4 |7 z! J! ^! l
  53. * @param[in]   pFIFO: FIFO指针2 W7 J, u% }. T8 [3 i
  54. * @param[out]        pValues: 存放要读取的元素指针. G" @# m$ p5 F. o/ I
  55. * @param[in]        bytesToRead: 要读取的元素长度
    , q: u- K/ d% E, _+ W
  56. * @return      实际读取的元素个数4 d1 h6 |" n: E( W% i" j4 W' m' z  f
  57. *********************************************************************/0 q$ s5 C8 w5 e8 q  N
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);& d, y0 h" D) L# F0 \$ h+ z

  59. . U; o" X2 p/ P" ?( Z  E' R

  60. # p3 @( ^6 h9 g- u% @: i) L" p
  61. /********************************************************************//**- R4 e- `  d$ ^( }' q/ t! o& j
  62. * @brief       清空FIFO
    2 U/ P' |. ^# M; K# ^0 f
  63. * @param[in]   pFIFO: FIFO指针
    9 G9 w- S, i5 A& ]' n
  64. * @return      None4 A9 c1 T1 o$ T. G. i. B
  65. *********************************************************************/
    % j9 i2 v  l" A1 G% K9 n
  66. void FIFO_Clear(FIFO_Type *pFIFO);
    6 Y  g9 V' S$ [5 S% ?& z& ~
  67. 2 a0 g' }  G, k' x% U

  68. # j4 E. ^! H2 O4 r% a! w8 F
  69. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);
    . B0 Y  E) Q" }6 C

  70. ; Q+ v# F* S1 `. w; n
  71. #endif
复制代码

, e8 i& t, T3 p1 l( o1 ~② fifo.c程序主体
) H5 V+ ?: w$ ~0 p& o, f* p; H0 M' J8 N# Z% R2 k4 Y& y0 W
  1. #include <string.h># m" V# ~& y- r7 s' W! [
  2. #include "fifo.h"
    7 a. `8 m5 w8 B4 e/ C) t8 `" @
  3.   V' _$ A0 S* k' `) T

  4. 5 y4 T4 l  l0 b" ]8 o# ?
  5. /********************************************************************//**9 m. H! c! w- K& B3 l
  6. * @brief       FIFO初始化
    ; c, k5 w8 T" I! J$ F0 a
  7. * @param[in]   pFIFO: FIFO指针( m; a& j- i' Y7 A
  8. * @param[in]        pBuff: FIFO中缓存
    ; E: T9 m6 u6 b' M
  9. * @param[in]        elementBytes:FIFO每个元素的字节数3 j  {$ L' o7 Y; q5 H2 h0 \8 K* a2 o
  10. * @param[in]        depth: FIFO深度
    : I) _9 ^: D5 L
  11. * @return      None
    , h$ t' N3 L8 C  r  O
  12. *********************************************************************/: p: P* @4 M/ \5 e. P5 \# J
  13. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)1 b2 K' M* p8 `
  14. {' x) p  ], r& A
  15.         pFIFO->Buff = pBuff;* \3 ?6 v0 n" p6 t3 k% C$ O) {) ?5 l
  16.         pFIFO->ElementBytes = elementBytes;1 ]" ~: h* C$ n6 m
  17.         pFIFO->Depth = depth;0 D6 I; I5 a2 `8 b
  18.         pFIFO->Head = 0;
    5 u8 N3 b) J, D
  19.         pFIFO->Tail = 0;
    # F. A# z, P6 |9 a
  20.         pFIFO->Counter = 0;
    0 I" l% B/ W! z, u5 B0 Z0 W
  21. }/ @- W; T8 O5 {6 Z1 I! {3 L

  22. ; \5 o. w  Q! g" w8 ~
  23. /********************************************************************//**
    8 E5 t$ B" x; c$ J* O
  24. * @brief       判断FIFO是否为空& o6 V) D: b5 Q
  25. * @param[in]   pFIFO: FIFO指针
    7 x) b3 o( q8 o
  26. * @return      1-TRUE or 0-FALSE7 u1 D2 Q: G: \! e3 j/ p3 T
  27. *********************************************************************/
    4 X" G/ I. i( N! c& P; V  h+ T
  28. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
    & a/ w7 A, Z" m
  29. {
    ' y9 G" S  [/ B
  30.         return (pFIFO->Counter == 0);. i/ V; N% W5 ~% Z& H
  31. }
    8 e7 u  k. I! A" ^; {

  32. & k: F2 a& l$ l8 [
  33. /********************************************************************//**' E# u, N+ j& G$ T9 Y, k
  34. * @brief       判断FIFO是否已满) ~, j: [/ Y3 _2 z/ i& B( v
  35. * @param[in]   pFIFO: FIFO指针; T6 m1 u5 K! a" a. S
  36. * @return      TRUE or FALSE! b# n( p8 Y8 p, a2 [9 u
  37. *********************************************************************/
    . D7 u6 @- `- s
  38. unsigned char FIFO_IsFull(FIFO_Type *pFIFO)
    , D' f' a* a( I  \+ w
  39. {& e) O9 r& a$ c& X
  40.         return (pFIFO->Counter == pFIFO->Depth);
    : n# _" T) u& n5 n* k5 q
  41. }1 Z2 R: x+ f9 r1 Z$ z1 t! d1 O, e

  42. " ?! ]+ T) c5 x9 L
  43. /********************************************************************//**
    $ D9 W3 Q" G: Z7 N) v$ a" G. D
  44. * @brief       向FIFO添加一个元素
    1 l3 O. ]& y3 a" j& }, }, B2 u
  45. * @param[in]   pFIFO: FIFO指针
    + s5 y6 l  B; @( N8 ^6 l
  46. * @param[in]        pValue: 要添加的元素; ^3 w4 A# ?  m+ `
  47. * @return      1-TRUE or 0-FALSE$ o$ o7 b0 A: K' s; }8 H5 R4 S
  48. *********************************************************************/
    7 \7 _) r+ u" ^1 l5 R$ Y; _
  49. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)0 u; m( J# Z4 C1 }8 B4 \5 F
  50. {$ Z9 b" X' T% b3 h
  51.         unsigned char *p;
    7 y+ J- V$ M' H% _# V
  52. 7 g4 n8 d) u; L
  53.         if (FIFO_IsFull(pFIFO))
    5 @& h1 `2 {3 k# k
  54.         {! Q3 W1 o8 E& X: p( l: n" D
  55.                 return 0;0 w- p8 M/ U4 T3 L, y3 L0 d
  56.         }
    5 C2 @' F2 f7 _* H5 }0 f
  57. ) K, Q) ~, j1 }: E+ z1 U) m
  58.         p = (unsigned char *)pFIFO->Buff;& X& Z$ O3 Q, q6 i
  59.         memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);
    9 n5 K2 [: B: c& S- U* N4 d
  60.         - R* h0 C: T* a9 a3 m$ E& v* f0 t
  61.         pFIFO->Tail ++;; a! l3 e7 ~& n9 J8 g4 d$ o
  62.         if (pFIFO->Tail >= pFIFO->Depth)7 d- B/ c" K4 M. k3 G- _/ m
  63.         {
    # f; W) b! R* Y7 m+ a2 d6 N
  64.                 pFIFO->Tail = 0;) T8 U3 Z. ~# H0 g% n
  65.         }' P: o' M/ G8 q
  66.         pFIFO->Counter ++;
    3 J  Y& L7 x. V4 _3 ~
  67.         return 1;
    + k2 D! k2 @2 `0 f. ]3 M
  68. }
    ; L" z% S4 V" A7 v) e' {
  69. * Z+ Y; J1 x; j3 i, i  Z- |
  70. /********************************************************************//**" ]+ Y9 V1 L2 l& _
  71. * @brief       向FIFO添加多个元素
    % C1 w3 N" U# K9 J8 R' Z; \
  72. * @param[in]   pFIFO: FIFO指针
    ) L1 [' x, |/ {0 Z& E0 v% S2 `
  73. * @param[in]        pValues: 要添加的元素指针& {% [) W* T, i  e6 F: S
  74. * @param[in]        bytesToAdd: 要添加元素的长度$ Y) H8 ~! J) E' ]& J. t9 W
  75. * @return      实际添加的元素个数
    1 v% R% w* r* X3 P
  76. *********************************************************************/* ~- m  e/ D  c' _5 t# g/ U
  77. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)& B0 T- E8 W$ S
  78. {3 ?0 f; e& T6 m9 Z% m
  79.         unsigned char *p;4 ~: H/ z- l& }0 G8 j* A% ]. O
  80.         unsigned int cnt = 0;
    5 j3 ^, L2 _% p! ^; H
  81. 3 Q7 G& |/ W, i$ K$ b* u0 C
  82.         p = (unsigned char *)pValues;
    ' I$ G$ n: C1 Z% d/ t7 z% T
  83.         while(bytesToAdd --)
    - z* b. o5 ^  J4 c
  84.         {: J$ X/ w) ?. X2 ^$ r; N+ E
  85.                 if (FIFO_AddOne(pFIFO, p))$ a& n" b* h* K" M8 L
  86.                 {
    + |0 j$ y3 v  [" u0 Z5 q4 {
  87.                         p += pFIFO->ElementBytes;
    ) h4 G' J2 z" E! f
  88.                         cnt++;; A1 V- h0 N3 X
  89.                 }! d* x0 K$ P) ^" z8 m
  90.                 else
    7 j0 K2 H( ^0 s3 Y
  91.                 {. y7 a" o* \  f- L( z+ ^  T& R8 ~
  92.                         break;
    0 w" c8 M" E  l5 L
  93.                 }, y, I( r9 N" G& e# e
  94.         }
    : U$ ?/ e& h9 z3 ~* u% K! a% @3 X& a- `

  95. & j, y+ c( d; j8 `1 ]: ?1 N5 l
  96.         return cnt;
    1 I1 {6 D4 Q6 |" R5 S
  97. }
      ?4 K. X. f: H' h+ T1 }# L" c
  98. * T5 x3 V' j' p
  99. /********************************************************************//**5 v$ {- |. f0 T; x7 p* ~
  100. * @brief       从FIFO读取一个元素! ]) m1 _! @& t4 \0 o
  101. * @param[in]   pFIFO: FIFO指针
    ( n8 t: l8 L) Q
  102. * @param[in]        pValue: 存放要读取的元素指针& |& A* d1 Z! r5 e& T9 m
  103. * @return      1-TRUE or 0-FALSE
    ' \0 O- a: H1 G, O& s
  104. *********************************************************************/
    ; a  F# r* h9 n- H/ U0 Q/ T
  105. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)
    0 K2 p: }5 I. c& j; T9 j; P
  106. {
    - ?1 t9 T, C& k+ P8 Z5 `& L5 A
  107.         unsigned char *p;! Z/ |  k3 C: i: j: F; L0 Q6 @% U
  108.         if (FIFO_IsEmpty(pFIFO))' n9 W; o1 B9 _  k2 Z
  109.         {8 F# f4 M1 m+ ^# |2 B6 B2 k/ p4 o
  110.                 return 0;
    - W+ R; t- L* B. i: F* {& t# G
  111.         }' Y* v  x1 a  k  [& ?3 e

  112. 0 O3 _. I( [0 x
  113.         p = (unsigned char *)pFIFO->Buff;' K+ r- g' I, H/ L
  114.         memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);
    - k! h% N' K% |9 l

  115. 3 {( o/ f( ?5 R( g, W
  116.         pFIFO->Head ++;% e' ?6 H. ~7 r( C
  117.         if (pFIFO->Head >= pFIFO->Depth)6 j9 I: M! R3 F# s, }2 t. U
  118.         {
    5 U$ Z% ?8 i0 G5 L7 A& A/ E/ I
  119.                 pFIFO->Head = 0;. B1 ?/ @9 D6 }  {- w  ?2 O
  120.         }1 R, [" m% M4 Z4 |$ |  @& D" Z$ v
  121.         pFIFO->Counter --;
    ! p- }) C% t9 R: m) u( e
  122. 8 W. x. }. n& |6 m, B' U6 A2 |
  123.         return 1;
    , g- N6 b3 Z* g8 I/ f( W5 ^
  124. }
    - K( p$ b- G! m, h' z' M7 v* n, _
  125. 7 [# K2 m, l( G; t5 \9 P3 v
  126. /********************************************************************//**
    4 X  ]! d' z2 ?/ z, I
  127. * @brief       从FIFO读取多个元素
    ' \; n% q6 V. ]$ P, l( C, I( b
  128. * @param[in]   pFIFO: FIFO指针! a4 E) d4 j; K( z3 R
  129. * @param[out]        pValues: 存放要读取的元素指针
    , u$ N' a2 G0 W& S
  130. * @param[in]        bytesToRead: 要读取的元素长度( Q6 J% Z/ U4 S) E  G" I
  131. * @return      实际读取的元素个数. x( U4 y2 W6 B# i
  132. *********************************************************************/. i$ P8 n' V8 y1 I+ N) p6 D
  133. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)$ p) l- V7 D# n$ S: Z, R0 r
  134. {0 P. C9 _- f/ C
  135.         unsigned int cnt = 0;
    # J/ W" ^# M# H( F* h- A5 Y' |0 E
  136.         unsigned char *p;  l2 R& ^4 q% y8 h* x2 j$ F$ g. I
  137. 0 l# ^' F# W. U' X2 q" ?6 o
  138.         p = pValues;
    - _& e  k7 |- S
  139.         while(bytesToRead--)! H8 T0 v. \, v( ]5 X
  140.         {
    * F4 Z6 H' C, H3 N: G, R. g3 c
  141.                 if (FIFO_GetOne(pFIFO, p))' F; N  Y, S" w6 m2 c/ W5 A
  142.                 {# _  U9 g( [/ x
  143.                         p += pFIFO->ElementBytes;
    7 Z+ S8 g7 R$ Q8 A3 t  Q4 M
  144.                         cnt++;
    0 o* \* n2 P7 t" Q
  145.                 }4 z5 C% l/ g  m
  146.                 else
    % X3 [; ~9 Z* ~% h+ V% d
  147.                 {
    9 `1 T' q% U+ b+ q
  148.                         break;
    ! _$ ~5 `5 @. f& D
  149.                 }
    1 D8 Z' h6 X  C8 O$ @8 d7 i. a; w- d6 \/ W
  150.         }& H, |+ r4 ^; X! t+ E

  151. ; {" R; K. U( \% f: f+ {" S! M
  152.         return cnt;
    3 @$ A) S5 q% {
  153. }
      Q6 r9 E4 h9 m+ _! l" `
  154. * O, {# u- q) v0 X
  155. /********************************************************************//**
    + r" l- r2 R/ q% c7 _$ E$ @
  156. * @brief       清空FIFO0 f5 ?! T& g( q; H5 N7 A
  157. * @param[in]   pFIFO: FIFO指针1 K( A& K  d' E" F' f" j; ~
  158. * @return      None
    3 I7 B* C# d; w- L
  159. *********************************************************************/; Q) t" H% W! x' I
  160. void FIFO_Clear(FIFO_Type *pFIFO)
    * ?" ^# F' w9 M: i. L
  161. {
    , V- |  Z% ~& i* I7 ?
  162.         pFIFO->Counter = 0;, x: h; @- u4 x# c6 B) i, B
  163.         pFIFO->Head = 0;
    / P7 e& v; h+ Y6 O1 f5 u- |& w5 m- \
  164.         pFIFO->Tail = 0;
    ' a" J. b6 e8 }; Z( H
  165. }
复制代码
/ {9 L# e: @; z1 M+ A& e% D- a
③ 串口初始化. \% b1 M4 M- q/ m5 A. G, J
  1. static void MX_USART1_UART_Init(void)6 r" Y5 y) G% \' R( f+ L9 O" U
  2. {
    " O: C7 S- Q# b" ^
  3.   huart1.Instance = USART1;, l& p5 r2 O5 @; y8 w5 v
  4.   huart1.Init.BaudRate = 9600;
    ! D# o3 _3 @, p
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;5 r# {* O/ E% z+ ^
  6.   huart1.Init.StopBits = UART_STOPBITS_1;
    , p* }% ]8 p( o- N4 n
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    1 i1 X8 Q: ]) c2 \8 L6 o
  8.   huart1.Init.Mode = UART_MODE_TX_RX;
    + H3 J$ I7 D2 F5 k* x) f0 P9 b9 i
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    2 m  A' r, f. {  q' h% t
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;; h/ v* n5 {, v0 b
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    6 _  S  L! H0 O
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;! a/ w) R& M& w/ F# `+ f5 M
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)3 m2 `/ E2 [* i+ v$ T
  14.   {
    6 p, N; M. w' u1 i- Z
  15.     Error_Handler();
    8 _3 d! V, }8 m3 Z. I- z; Q% f6 E# L
  16.   }  - g: ]5 I$ A" O; L" [( R2 O. l
  17.         
    ' O2 G  i, T1 G. {. k0 w  `
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)7 W, l2 ~8 t4 ?# h3 N
  19.   {. F" A$ ]- Y9 p' J; e# y$ ^* |
  20.     Error_Handler();: L2 w$ e; h6 `+ o
  21.   }
    + S8 ?8 h8 R/ _& X
  22.         
    + W* Q3 u3 M2 L2 v, ^+ @
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); ) n+ V  e; g6 M- o+ R( g
  24.   /* USER CODE BEGIN USART1_Init 2 */) @! U1 F& J/ o6 F4 u  Y4 e9 @' |
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    3 I  _' q' h) R2 n' q1 j
  26.   {- y0 |2 f' ?/ q3 D
  27.     Error_Handler();/ ]; i+ B$ V- c4 A
  28.   }
    ) B6 T. {/ X2 W8 r
  29.         4 Y) _5 c1 N# Z$ \
  30. }
复制代码

$ P; k5 g/ J1 M8 W& g. \ ④ 接收空闲中断
1 T+ J% W) s! N  |1 Q/ X9 e* Y# \4 Z6 v
  1. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart), r% D3 Z2 u- f( q* ^6 t* P* l' N
  2. {0 Z; B1 _& ?( E4 S' {8 i9 `; H
  3.     HAL_UART_DMAStop(&huart1);
    ) d7 Y6 a: l' S/ \9 v* Z, p

  4. + E0 F2 ~5 ?/ S" H8 W2 x: J
  5.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    % u$ T3 D4 \( {! w  N6 s
  6.         $ O& S5 C% u2 o! \. R% o, Z* l
  7.         FIFO_Add(pfifo, aRxBuffer, data_length);
    0 c. N3 t# m7 s6 R
  8.     data_length = 0;
    ; J3 {7 C: q4 `6 R9 t9 w! W2 _* g
  9.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);, ]8 Q) e9 v# p1 H5 y5 j% H4 [: s: H1 p
  10. }( Q* U# g7 c% j/ \

  11. ( _/ B. A% O# X% t! {0 ~
  12. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)- s2 e  b! d. ~5 u1 V  \
  13. {
    8 n6 k' C( ]  P1 \  J: r4 X
  14.     if(USART1 == huart1.Instance)
    * {5 T" {, P' S7 r6 K5 d# O, |5 R
  15.     {# |7 `# W* i7 B8 I8 L3 k5 I- x
  16.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    & O  z  w! @$ t7 d- S5 G
  17.         {( ?8 C- I( O- M+ O( x4 |
  18.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    : Z/ V4 m. \& L- k
  19.             USAR_UART_IDLECallback(huart);
    2 r) M' g& s- g& A9 c
  20.         }9 p$ c( m* [5 P5 C# N& i
  21.     }  o( c. }- G( F, q( f# q
  22. }
    + R: j$ f2 n5 x% H

  23. ( o# y  X. n: g, ]  g0 b+ E$ u
  24. /**
    1 Q) O* j: x; a
  25.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.  D# D0 O' Y) y, _" U
  26.   */2 P7 t$ C- `6 O, E$ u
  27. void USART1_IRQHandler(void)
    / V& t% H4 Z* U9 x5 Y8 d5 u
  28. {
    $ p# F7 G; w3 z
  29.   HAL_UART_IRQHandler(&huart1);
    3 \. M, Z: ?/ Z/ l8 b( t5 J
  30.   USER_UART_IRQHandler(&huart1);* [) b7 t* W7 h7 a2 ^% c; A: x4 b
  31. }
复制代码
; T7 [# o5 U* e' Q
⑤ 主函数调用:
" v" @* ?) ]6 F! j' E+ s; H
  1. #define TXBUFFERSIZE                    30
      d7 a; w8 X0 f" y1 r
  2. /* Size of Reception buffer */" S( z! o" d: f
  3. #define RXBUFFERSIZE                    TXBUFFERSIZE2 L& M3 t; j- q7 g; \
  4. #define RXFIFOBUFFERSIZE                TXBUFFERSIZE * 56 H5 c8 w  {; |  ^

  5. 2 m) u: k4 _/ T# F2 e: t0 x
  6. ) v* q+ A- T- h9 |+ ?
  7. uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";. o: H) Q. x) d  e% g; g* H! g

  8. . ]( ^# m7 {" X- D2 a
  9. /* Buffer used for reception */
    2 t0 k# [6 Y( R4 h5 E# G: i- ?
  10. uint8_t aRxBuffer[RXBUFFERSIZE];0 V/ M9 [5 [! ~! N6 a, R& R
  11. : }4 H* p* p/ O
  12. uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];8 p2 _5 |* e5 ^, n
  13. FIFO_Type        fifo;2 @6 O+ ?7 i2 O) K6 l
  14. FIFO_Type        *pfifo;. k  f, ?; C9 U

  15. 7 z! I' A3 l2 _+ O: X" K. l* h2 ?
  16. int main(void)
    " q$ t" n% J" \% S1 @7 G
  17. {# Q. p* T& N6 \2 m; c8 k
  18.   /*此处省略硬件初始化*/" R7 r# Q! ]9 `- }/ o
  19.   if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
    ' U! Z' r2 e0 z9 h
  20.   {" X  P: C: G1 ]$ q' a( ~" j6 ?) j
  21.     Error_Handler();
    8 G% i3 R& ?  i. k  F, u/ @
  22.   }2 X6 [: @5 F2 j! {& d/ c" x
  23.         & I! ^' O2 g$ W. o
  24.   pfifo = &fifo;7 m, G0 v( B# @+ b* S
  25. ( P+ K) l& ~- M0 P* r, z
  26.   FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);3 Z' A$ b; V( x% w$ ?' r
  27. 5 p9 l4 g" A: _' a! E3 A5 `8 Z
  28.   while (1). |* j% H" ^- G. b, ?; |9 I6 n
  29.   {" Z' J; N! }  H  ]
  30.         /*一次接收的缓存,重新发送*/' J# F3 ^/ T5 X) a  ]
  31.                 if(!FIFO_IsEmpty(pfifo))
    $ b+ `! F9 s4 g) h2 @3 w
  32.                 {
    4 z. |1 `3 b) Q  T
  33.                         uint8_t a[100]; //存放读取fifobuffer的数据' F4 U6 D( Q* C9 k
  34.                         int i = pfifo->Counter;//先保存接收缓存的数据个数
    / D; d% d* V. C; N
  35.                         FIFO_Get(pfifo, &a, pfifo->Counter);
    . |7 @/ |# u2 q( y
  36.                         HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率: L% O" v  n2 k! Y
  37.                 }& P- E/ L& o( c* X
  38.   }
    ) o4 T; z7 z1 P: M" P" l
  39. }
复制代码
( z: e9 ?. _; B
测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
( H, L$ @7 b4 {, b5 T% |& R( L" R5 V  V6 I& |$ w: v) B3 l4 q4 H
202109031459585.png

" B; I: S( F* j+ e$ y! c" Y
. B* b% F# k3 e) E- `问:关于 stm32 HardFault_Handler问题处理?- o9 O0 K' F7 w7 a1 T0 j6 f$ F
! Y" z7 P1 S" O2 y6 w8 [1 V& m0 n7 }" Z% X
ANS:) o; `+ P) J) W. r* @6 ^

1 @- p* ^0 }8 c" ^* l2 m' t) E        在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,# A* n! l: s: X5 G
- a1 |( G4 S. z0 W+ B0 ]1 Y
20210903150306628.png
- _* K2 _8 w( B3 y

4 s$ C6 T3 j. r1 X6 ~  j8 A
20210903150316369.png
1 J! p% I: |  y  \- }+ X/ q1 D. W
# E5 V, j" J4 c( Z
最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!. L2 a+ A+ R) y  U9 ~0 j& f
  1. pfifo = &fifo;
复制代码
2 l0 j: A( V5 x. y) R+ v
( x3 |$ l3 C# g% k* i& k

& o; i" f5 r- C; a$ q6 ^% ]0 W8 N- l9 r: b' w0 @; u: T
赞 收藏 评论0 发布时间:2021-11-25 15:00

举报

0个回答

所属标签

相似技术帖

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