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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
一、STM32CubeMX开发
3 \; ^+ ]# Z9 w  p3 F1.1 新建工程. i: f9 h: q* X1 S/ K
file -> new project $ v0 S( l' [4 g+ I
# o. N* H6 |& h4 S& a$ l3 _, o" C
选择芯片-> stm32 core内核         
$ N- l3 b. o* p/ S( U
1 f% r3 P0 T$ `) _2 N7 W3 }                   stm32 series 系列, \3 R+ o" X$ K! }) ?% b

" U  a  v  G+ o- {* ?0 C' `$ _                   stm32  line6 h8 }  w) d& T+ f
# _7 c; t. d! H, K7 |2 H' M, P* S
                   stm32  package
: C6 `. k' A5 o; `3 V) D# J3 I1 M
  |3 ~  }2 t$ ~选择芯片根据自身需求去选择,目前该项目是stm32f0系列
0 f- F( ?* q" ?8 Y( A5 `7 M: Z1 B- T/ W
                    stm32 core内核         M0
' S4 U! ?& @+ o' \
  _' g) _* _, v                   stm32 series 系列      F0# o; N; z( M2 g

  F' `. Q& v* Q4 e! v/ N                   stm32  line                 F0X1
  }% q: L, }* b8 [( f6 p
, }2 I. s* @- ]# {; d  _) b                   stm32  package         TSSOP 20
4 F. X& }1 f: Q7 o+ O5 S2 y. @& G- n  B3 l7 m& p
1.2 配置 USART1$ t" Z! u9 k1 C2 K2 J( f$ `2 u  _8 A
配置 USART1 的模式为 Asynchronous,即异步串口模式; a" |  \& C7 u; O4 p+ g" V, }

4 v& l. _% k3 Z
20210827163252369.png
- `" t* B. q. `' W) {. J+ p4 o
1 Y& |9 t3 ?' }0 q' N% [
1.3 配置串口参数
  I' ]/ ~( g) ^/ b& f 根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,12 b, ~0 W- ?8 U& {

. m! L- c8 `" a& W8 E
20210827163448427.png

+ i0 `$ N, m' q$ j3 T$ _" j% \( w' o3 }: M8 J
1.4 设置DMA" N) U7 B( h$ M6 U' V% @

& F0 [( S' `3 `# A
20210827164240955.png

" K" v4 P( ~* s7 T: Q4 n
2 M- Y3 X$ F( ^$ Z2 E 1.5 添加串口中断) B! Z' Z- N1 N2 F- b& `1 G: A
: r( c: M9 R) Q+ T
20210827164323729.png
5 h4 N% S; X' @' g
3 S# |$ B5 z/ E  K7 n9 m
1.6 生成源代码。$ v1 f. X9 w% J. c; V  x9 n6 g
在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。; r# A: Z$ }7 e# Q

& _- \, M7 [9 n% L9 B) W2 g; t
20210827164544427.png

2 k) @' }" y" U5 r
- \( q  E( p- h6 K: V( T生成代码完成后可选择打开工程。 3 o, k7 [& b$ \4 b! G3 t

- L' N* M+ z1 \/ {
20210827164829635.png

, {: U; H6 g! x
; R* T' t' d- {* v5 u二、代码部分
) ~, r6 N6 Z- |" r8 `9 D2.1  接收中断处理
: {7 A. x! j- F) P% M. D2.1.1 接收固定长度:(舍弃)
+ {/ @6 J  Z4 V& b2 R只有接收缓存到固定长度才会触发中断/ r& r! c9 s, Y
串口接收回调函数& `7 q4 q& Y# O! l
) D% ~) c3 o# y! M. D  w" B+ Q$ s
  1. uint8_t aRxBuffer[RXBUFFERSIZE];: ?0 ?, }+ _& w" _* N2 F
  2. /* Size of Reception buffer */9 D) b0 u; L. d8 V% a
  3. #define RXBUFFERSIZE                    10$ P/ C: _+ a) T1 {% \* a

  4. 5 p9 s1 _" O6 [% X* c

  5. & W, R4 @1 p  ?6 t! T- f3 R" p
  6. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle): T5 d! Y/ e7 p- [7 l2 ?& N7 i
  7. {! }% }1 e" h. R' Z( N: O
  8.   /* Set transmission flag: trasfer complete*/9 k$ s9 F/ a1 T* V+ ?+ v
  9.   UartrxReady = SET;
    * M$ i- ^2 P( e: n1 j
  10.         HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
    1 y* h# W3 ^( m; ?" e% E
  11.         HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);0 R9 [1 d( q( |
  12.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
    + \! Z7 k7 a1 ]; b, x
  13. 2 w/ V: W' b$ e& ~8 J1 N
  14. }" t+ y8 Y9 `. Z" i# z" v- O

  15. + X4 Z, S3 L! P6 {$ T9 I+ I+ C0 J
  16. void USART1_IRQHandler(void)
    ) x" J8 z: q; A/ N
  17. {
    # M# m' z6 n  u2 t3 O
  18.   HAL_UART_IRQHandler(&huart1);
    6 H7 f/ u( }* e4 {( k
  19. }- K+ W2 k2 ?4 G
  20. ' j% ]& E( p1 g

  21.   N2 m& E( r  m5 O- C4 _
  22. static void MX_USART1_UART_Init(void)* t, Z, l( P; c/ h, o+ o5 Q) P
  23. {& a5 p& ~1 ]+ V$ J" x
  24. # H+ n* y6 P9 [3 L3 e! Q
  25.   huart1.Instance = USART1;: @, M1 d0 m. ^# |/ H1 ?. m
  26.   huart1.Init.BaudRate = 9600;
    & w* P# X; h& z: u4 c( i
  27.   huart1.Init.WordLength = UART_WORDLENGTH_8B;+ V# |0 ~' d; P% f, q9 z. D
  28.   huart1.Init.StopBits = UART_STOPBITS_1;
    , l# u( q: C0 k3 [) d
  29.   huart1.Init.Parity = UART_PARITY_NONE;  k2 Z1 P9 s4 l
  30.   huart1.Init.Mode = UART_MODE_TX_RX;  D  w* Y6 F2 {# T
  31.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    6 s, ^3 V* A2 w
  32.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;$ M3 a* F* [; }: P' _4 C7 ?/ M
  33.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    + g. l' E7 V" S! S$ K
  34.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;) n* K, A+ I8 p4 K9 X3 ^; o7 T
  35.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    9 J% w6 [2 y% R5 a" g, R
  36.   {
    & w8 B+ c( f; [, B
  37.     Error_Handler();
    4 J. B# Q( h) D9 D) m( R+ i
  38.   }  
    ! N/ I2 F# R* I# j2 P+ F6 Z6 f9 b
  39.         
    3 E( |7 q; o% ^) v+ O; M- [% q
  40.         if (HAL_UART_Init(&huart1) != HAL_OK)* W8 S3 I% R' U" C2 z
  41.   {4 M; _2 O9 Y1 S) b/ v2 o; r
  42.     Error_Handler();
    . W, z( O/ Y' a7 C" ]
  43.   }
    # c2 ^5 W( o8 z7 s" L
  44.         
    ' f6 x! {. f4 @' A2 h- }; c" t3 C. ^
  45.         UartrxReady=RESET;
    % r* p- n5 _" w" S, N$ U
  46.   /* USER CODE BEGIN USART1_Init 2 */6 J* m; w% n/ I
  47.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    . Z' O, b2 z. O
  48.   {$ |1 r7 g4 W) z3 P
  49.     Error_Handler();
    % J, y, X' }) K2 f/ H5 j
  50.   }/ X0 h! T5 w2 B/ c1 D( E* p
  51.         * z" \! \/ w6 w, O' i, M& C. H! `
  52.   /* USER CODE END USART1_Init 2 */
    5 \. S; I/ F& w+ P) n
  53. }
复制代码

. i  f7 j) b6 N" p4 n4 Y7 l从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。* Q) t3 A, L7 o9 A8 _
( L9 w0 x4 D; s+ y: d7 v. \
20210902164819116.png

' }' e4 U6 e- d/ d* Q$ q
7 n. p+ U& O2 P/ i* x2.1.2 编写空闲中断函数接收不定长
4 A2 \1 ^( t: D; F  sUSART1初始化:
* L7 f$ F9 c  Y1 M1 Z: X5 k. t* I* P
  1. static void MX_USART1_UART_Init(void)
    5 c4 n* e0 d1 R
  2. {
    6 n5 \4 B0 K* m' k; r6 v& R
  3.   huart1.Instance = USART1;) M- J3 S  S8 j5 U5 O
  4.   huart1.Init.BaudRate = 9600;# p; o: G& O  z: @! M8 F7 a% b
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    # C2 l5 `) ~$ ^/ x% o( T
  6.   huart1.Init.StopBits = UART_STOPBITS_1;  c6 L, p9 d  m/ |- K
  7.   huart1.Init.Parity = UART_PARITY_NONE;  q) r0 {9 U$ D8 i
  8.   huart1.Init.Mode = UART_MODE_TX_RX;+ J. ?$ H' O& s6 Q
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    $ V! U1 O- {8 x$ F
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;; e: L% o. e/ Q- @( k4 K  s1 A  Q; J; F
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;1 ]: O/ z$ [& M; X7 S& W
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;# m, S" Q; @) n  e+ X
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    , a. I/ u' ~* a6 y
  14.   {
    ( D5 k3 i2 S1 X# J0 g8 ^
  15.     Error_Handler();# m8 i- G2 ?+ a. Q
  16.   }  
    - d: |& ?0 H- i; w' l
  17.           n& V) @8 B: O) K* [* ]
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)
    7 X/ W: n' S, S) B
  19.   {
    & V/ n6 _; n1 n
  20.     Error_Handler();
    $ A5 i8 m2 q, Z- b  j$ W- v' R+ L7 T% |
  21.   }& Q, {- |; P8 @9 p% D* M0 L9 w. d5 @

  22. 5 }1 ]. a) e1 F. H1 P5 }5 p
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
      v5 ^7 F: |/ [7 ?: x
  24.   /* USER CODE BEGIN USART1_Init 2 */
    . T9 W5 F2 U6 b6 Z/ N6 m0 t
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)( D5 P. U- C; e, k; S7 c
  26.   {
    / R8 e, m& J" D( b" n' ?: w9 U- ]
  27.     Error_Handler();
    9 R% `2 S6 Z2 ^7 N; C: a6 t6 w
  28.   }
    . g) O3 }  y+ R) y" c* o
  29.         ( t& f4 w, X/ b& S% d5 Y
  30. }
复制代码

7 `. ^# Q3 {7 ?" A  i空闲中断函数: . Y( j! x/ v1 K' _- D2 y0 W
  1. #define TXBUFFERSIZE                    30' D% `; [' G6 V4 ~. y5 Y9 k6 L& t
  2. /* Size of Reception buffer */
    9 m) H$ Y! R* y9 O
  3. #define RXBUFFERSIZE                    30
    , V( _: y( L, g  g
  4. ! t) k: P4 j& Y3 w# X+ b
  5. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)9 L: l; z/ f, A. |$ E
  6. {
      y4 q2 p) L' T5 w
  7.     HAL_UART_DMAStop(&huart1);% _) U  i' ^: m6 ^  ^

  8. - p0 k; M  A- Z4 N" G
  9.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    8 P) Z% |+ l# M4 z4 b6 s

  10. 5 ]3 M) G# |3 h: ]4 M' y$ e

  11. 7 x/ c  x+ {! y: _7 d! B( J# ^5 o
  12.     HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);+ u& v3 s; [$ c3 k2 E
  13. # a0 ^& m5 q2 C2 h* ~" i; g
  14.     memset(aRxBuffer,0x00,data_length);' J" V. u0 B: T" s/ L
  15.     data_length = 0;! b2 @- t0 A+ O) e5 \- i
  16.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    1 T2 k8 D* A& k0 ?& f5 e
  17. }- B! ~( A7 g) Q* J. e1 P
  18. - ]9 b( Q9 o! j4 C
  19. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    3 o5 H  y0 G3 a6 ~) C  H, C
  20. {
    : t0 F6 c; _# Y
  21.     if(USART1 == huart1.Instance)
    5 T8 O# G# J3 o2 r$ J* f
  22.     {
    ' J( J: k) d3 g% p
  23.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))+ k9 L% P1 s. O! Y# m
  24.         {+ C2 q6 z) t9 ~6 v/ D. N! C
  25.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    ! i" L& ^; ]3 H2 E! W' i4 A. p
  26.             USAR_UART_IDLECallback(huart);8 G* W9 u+ ^- u( ~9 q/ u1 `
  27.         }, W( f' b! H9 R* r: F: k; c
  28.     }' C  Q" F5 _5 L8 R( y) _7 Y. J( Z
  29. }# V7 T; g( Z4 q3 G( `
  30. 3 }* n6 u. v0 x* K
  31. /**6 i# w) A1 {& ?1 y& u0 e
  32.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
    ' _+ y- t. e+ X5 F5 Q8 u8 z$ t) r
  33.   */6 U) N2 j% n! j. y! s- k
  34. void USART1_IRQHandler(void)
    # J0 {8 O9 N2 J* W; i
  35. {  G0 t; Y, s1 s
  36.     HAL_UART_IRQHandler(&huart1);/ A* k: ~: S, w# k- J' i
  37.     USER_UART_IRQHandler(&huart1);- N: {, U$ c. o* p7 t. ?+ [7 o
  38. }
复制代码

: k0 L7 S/ ~6 Y1 \6 e6 b! R3 _8 {可实现不定长的接收!
+ z! z% h) [3 z8 P  t
# s2 V& t/ X! K) o6 ?' d
20210902171851390.png
; ~. t' {) a. x! j3 \

0 b. z& z' x9 m 注意:+ W. [, p( P. S9 h# b/ S) C4 d2 z
在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。( N# [) B* t! p% y: C' V3 ?. R
- h% @- w& N* I/ w" q8 D
三、使用ringbuffer实现任意数据类型的FIFO处理接收数据
# W! Y0 `  _) ^) N; k$ t使用原因:# }+ z: g2 B1 J& Z
) t* a/ B0 ]2 i, L) S
        虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。) T0 d: t4 r3 G9 j5 G* }
% B4 }  }9 ?7 ]) c! s6 `
        因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖& B' U% j" I6 \: G8 E: D

$ {6 a) u/ d" y( G+ v+ B& g① fifo头文件:% n7 y, y  Z, n
  1. #ifndef        __FIFO_H_1 P) \2 F  ~! B) V, z# q
  2. #define        __FIFO_H_% S2 J' o# X, o( u( K+ }

  3. 7 z3 o% {( T4 g) i0 v1 y9 b
  4. #pragma pack(4)* T- p) g# H7 v- G1 J) p) j9 W
  5. typedef struct FIFO_Type_STRU' B' L8 d" N, }4 A: g. _# o  P
  6. {
    " r4 P: z: R7 a  s' u8 u
  7.         unsigned int                        Depth;                        // Fifo深度) }3 [; W6 W, ?$ ?9 a6 W
  8.         volatile unsigned int        Head;                        // Head为起始元素
    9 z+ ^$ _9 w( D/ E3 B0 S
  9.         volatile unsigned int        Tail;                        // Tail-1为最后一个元素  S1 B% v' n  X3 H6 h% A$ v) ]
  10.         volatile unsigned int        Counter;                // 元素个数0 `% C! f! I. X4 h6 I! f
  11.         unsigned int                        ElementBytes;        // 每个元素的字节数element
    7 G9 h& d' S9 A. M6 ~
  12.         void                                        *Buff;                        // 缓存区
    6 E5 Q' [) Y+ V7 V0 |
  13. }FIFO_Type;7 p/ }0 n+ _1 r* T! ~4 d5 P
  14. #pragma pack(). k; E+ x% N- o7 j6 y- |" r8 ^
  15. ; i" F2 y  F" e9 ~* k2 l
  16. /********************************************************************//**
    * L: C5 s& I& ~6 f& r
  17. * @brief       FIFO初始化& T& `/ f% J9 U4 j
  18. * @param[in]   pFIFO: FIFO指针
    ( P% L- b8 p2 v3 {+ N) o* d+ t
  19. * @param[in]        pBuff: FIFO中缓存! q" p$ h$ i7 C# c" U, G
  20. * @param[in]        elementBytes:FIFO每个元素的字节数
    / I9 P8 |3 e2 u# R1 c0 v
  21. * @param[in]        depth: FIFO深度$ D- G3 y! r. I/ s+ k: ]8 j; B9 L% s; ^
  22. * @return      None0 {2 a/ ?3 z" `5 y+ `
  23. *********************************************************************/
    ' w  W. P) ~7 |% h/ u) f
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);. q0 W2 a9 K8 |
  25. . I9 W6 Y$ ^7 j3 n5 g4 T$ r
  26. /********************************************************************//**
    + I; n0 n3 R" J  k7 o
  27. * @brief       向FIFO添加一个元素$ Y6 ?9 @- L9 W
  28. * @param[in]   pFIFO: FIFO指针- x: L) k- Y' Z3 E- a
  29. * @param[in]        pValue: 要添加的元素/ Z7 c1 A$ G) N  d6 ~
  30. * @return      1-TRUE or 0-FALSE
    3 Z* o7 W9 M( A2 M
  31. *********************************************************************/
    . W+ r; O0 z' ]7 p7 a
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
    " U  K9 ^1 h* d3 B4 E) m, p) i, i

  33. 0 w3 l% {1 I  f7 o
  34. /********************************************************************//**" M9 |3 j# W/ O" X" e
  35. * @brief       向FIFO添加多个元素7 R6 Q& y" D$ p* i; d
  36. * @param[in]   pFIFO: FIFO指针
    & g3 D/ Y* a& F9 ]9 {% d
  37. * @param[in]        pValues: 要添加的元素指针+ N) ?6 \  ]9 z; f
  38. * @param[in]        bytesToAdd: 要添加元素的长度
    $ w/ a1 r& \! X/ p7 N
  39. * @return      实际添加的元素个数' F/ `$ c' H9 W& ~% m3 q2 u
  40. *********************************************************************/
    & @5 `, l$ k8 t
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);6 z' P' A; Y8 @$ b. G

  42. ! K3 n* X1 j. \; `8 Q
  43. /********************************************************************//**' ^7 W8 l9 Q/ x3 S+ \% `* ~
  44. * @brief       从FIFO读取一个元素% U3 b& i. d2 T, g
  45. * @param[in]   pFIFO: FIFO指针/ I6 {, u: O3 E: p5 y7 ?6 W
  46. * @param[in]        pValue: 存放要读取的元素指针
    ; I8 K! B+ C5 G
  47. * @return      1-TRUE or 0-FALSE
    6 I& f; K4 m: I0 S1 `+ a
  48. *********************************************************************/
    + F3 V* v9 j  [% g& J" Y5 d6 T
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);
    4 k6 l' i. |  Q. P. v

  50. # Q# @! U) y9 y
  51. /********************************************************************//**+ }: q: U1 b. |3 T7 H* w; n
  52. * @brief       从FIFO读取多个元素
    6 m& h" D/ ^. {
  53. * @param[in]   pFIFO: FIFO指针
    ! F: J$ ~+ ^  J; c: w( v" V
  54. * @param[out]        pValues: 存放要读取的元素指针
    8 X/ E# `( R& n( }. v
  55. * @param[in]        bytesToRead: 要读取的元素长度
    7 q$ @  h. l, r1 x" M
  56. * @return      实际读取的元素个数* m% Y) O2 T3 I* s9 u% k
  57. *********************************************************************/
    $ `+ t  I9 v% z4 Z
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
    ; ^/ m; p4 s; C" w  v8 j, k5 ]' ?

  59. 4 t  p  }4 H; \8 S7 m% \( ~

  60. 4 N$ @3 v/ _5 y; K9 g
  61. /********************************************************************//**
    & p4 z7 b" a, @1 _7 I( W
  62. * @brief       清空FIFO+ j' f5 x2 H3 X! H
  63. * @param[in]   pFIFO: FIFO指针' J2 W/ P1 p5 |& O6 m/ O, o. G. P
  64. * @return      None
    4 x+ T/ a& c  a3 t% G! s: h) s
  65. *********************************************************************/
    + O1 n& t4 H0 L: [9 F7 `3 @- L
  66. void FIFO_Clear(FIFO_Type *pFIFO);/ L) s9 \' s) J/ F, F8 o% F

  67. : ]+ B3 T0 K% ]' I' [7 C
  68. 8 J- F% T7 u9 M/ R9 F* ?0 I
  69. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);5 h* }2 }& B! J  j3 I' m# u
  70. 4 h" ?& l) }% {$ P9 u
  71. #endif
复制代码
* ]! |- E7 Q& E, h9 U+ Z: N9 h- w
② fifo.c程序主体
( [" e* u7 A) \" z4 U5 T$ J+ D3 x$ s0 i. Z" _
  1. #include <string.h>7 k4 i( o9 C9 p2 J; y; u
  2. #include "fifo.h"3 t" k- ]: \% M8 j- g+ V& }# l8 ]
  3. * t; b' j2 j) H) E0 J, U4 l

  4. $ f5 |+ A* X% x8 `! l
  5. /********************************************************************//**/ ]! J( y# o. ?( g* B
  6. * @brief       FIFO初始化! G, g$ s  @( t- n1 U
  7. * @param[in]   pFIFO: FIFO指针
    % m1 j, d6 J2 i$ t. I
  8. * @param[in]        pBuff: FIFO中缓存
    7 K  g6 A- }2 F0 c5 }
  9. * @param[in]        elementBytes:FIFO每个元素的字节数& a7 Q4 p" v+ `9 v4 f4 ]5 r
  10. * @param[in]        depth: FIFO深度) D- W- t# l# |
  11. * @return      None$ `: E5 v- r9 m2 P& l& V
  12. *********************************************************************/
    / ?" ^- z. }4 f
  13. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
    1 |7 z' C7 G2 O
  14. {
    ( {- T' u) A2 g3 b0 I1 \
  15.         pFIFO->Buff = pBuff;# \) M+ [8 R8 ]
  16.         pFIFO->ElementBytes = elementBytes;
    & ^# x* j8 Q, O# W2 |
  17.         pFIFO->Depth = depth;) c* K3 R5 R. U3 D5 p; {: G5 s
  18.         pFIFO->Head = 0;
    - r' u5 U) `+ O$ J' }. ]/ Y
  19.         pFIFO->Tail = 0;
    4 o* [2 k/ L. O' b/ i. a4 @
  20.         pFIFO->Counter = 0;* s( h, A- y; V6 D% M* h1 x$ C& p' \
  21. }
    ' @7 {+ D) S" m8 r8 y0 i

  22. 5 a, d' G/ O& p3 V) x6 n9 B3 E
  23. /********************************************************************//**
    1 E: n  m7 Z2 n0 b8 b8 E
  24. * @brief       判断FIFO是否为空4 R1 j; b, i/ ]+ x
  25. * @param[in]   pFIFO: FIFO指针
    $ z" \( G9 j2 P. E  ]& L% X
  26. * @return      1-TRUE or 0-FALSE
    + _9 u6 X5 b! Y9 d  l0 V% Q. D4 b0 s
  27. *********************************************************************/
    ) a0 g. f" i* G" b
  28. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
    ; T+ |' h$ R7 I  g
  29. {
    4 f7 k+ e4 L! X, x8 e
  30.         return (pFIFO->Counter == 0);: M- F1 p8 R- |9 G
  31. }
    0 N! s7 e9 }& a, C8 i3 W+ V! ~
  32. ) U5 t" \  O, t* p! x7 S, b
  33. /********************************************************************//**
    3 }# g; a$ F6 P
  34. * @brief       判断FIFO是否已满) E* k+ v2 @0 D' Q+ o& u" t
  35. * @param[in]   pFIFO: FIFO指针' N. c; C( K9 ]
  36. * @return      TRUE or FALSE  I/ N: ?# }- [" H; Y4 H. B$ Q
  37. *********************************************************************/$ |; n$ `, [! k' ]1 I# g, O
  38. unsigned char FIFO_IsFull(FIFO_Type *pFIFO)3 P! Q2 y: q/ U. c: @
  39. {6 e5 T7 t3 r. E& b
  40.         return (pFIFO->Counter == pFIFO->Depth);
      x7 c' G' \# ^' @/ D4 \; N7 S
  41. }
    2 q9 ^0 w0 g% `" T* N, C: i, {
  42. ) x! C1 q* x' z6 t9 L. I( Z/ t
  43. /********************************************************************//**& ?1 P2 |+ e* @
  44. * @brief       向FIFO添加一个元素8 _2 `, A* n7 P, \$ `8 S; W8 o  I
  45. * @param[in]   pFIFO: FIFO指针
    . E, \+ u# x: `
  46. * @param[in]        pValue: 要添加的元素
    - C' ?% B( E  V! c9 G# [- b
  47. * @return      1-TRUE or 0-FALSE' @; c8 `' d2 `6 \. b( z
  48. *********************************************************************/
    1 x3 \: W& @& N/ V+ H( @
  49. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
    ! u2 g4 }7 |* ?  N4 s( I: e  S- P
  50. {
    ! u" b* Z( {( j; c0 |
  51.         unsigned char *p;1 A: _& N, D/ s" ?6 E+ M
  52. " L* \( c0 ]) g# m3 m# e* y3 r
  53.         if (FIFO_IsFull(pFIFO))# g) \6 W0 g' T' [% O) L( S/ w
  54.         {
    $ M8 ~1 H" g1 e/ J! [8 _( z, N
  55.                 return 0;2 s2 \" u. f  D% r- c
  56.         }7 l" L  }" Q0 ^! ^

  57. / j$ a' c6 P. v  a
  58.         p = (unsigned char *)pFIFO->Buff;4 `" x  K6 d- u& V
  59.         memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);
    ! P  \  o, m- f" c1 X7 V; n8 Q! k
  60.         2 w2 p, [6 X+ @, b$ j; q" Z3 a
  61.         pFIFO->Tail ++;6 N( V, G. c6 s% f- j
  62.         if (pFIFO->Tail >= pFIFO->Depth)
    ! o* E+ J+ C; a3 L" A  y; ^# K  N: L
  63.         {
    * Y5 h' Y! D1 P
  64.                 pFIFO->Tail = 0;2 w) a! |- \( P1 j! _" m
  65.         }7 K3 `' f2 I4 o4 z' ]
  66.         pFIFO->Counter ++;/ e8 t7 E5 J! Y/ ]) q* H3 s
  67.         return 1;9 w3 ?; y8 u- C2 q# a
  68. }4 q9 @$ s% g- N: C, I
  69. " ~! ^% \% M9 d0 f+ K% e6 _, X
  70. /********************************************************************//**% s3 ~, u) {0 }, k: w' T) N/ t: H6 H8 s
  71. * @brief       向FIFO添加多个元素
    3 a- J0 @3 e6 k, N0 f/ V
  72. * @param[in]   pFIFO: FIFO指针
    $ T# x( `7 [3 d/ e3 V+ \  U! {
  73. * @param[in]        pValues: 要添加的元素指针
    . n; R% e% I# Z
  74. * @param[in]        bytesToAdd: 要添加元素的长度! ~6 O) D* @  g, T& F, X
  75. * @return      实际添加的元素个数7 c- ~' _5 D$ c
  76. *********************************************************************/
    8 U, l! W3 ^$ h' b8 U
  77. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)- x. t1 g+ `2 D4 d$ n+ K4 h1 X
  78. {
    6 d/ R( `' m0 C, I) v. w+ X
  79.         unsigned char *p;% C! w& W+ D+ }$ C3 I! X1 k
  80.         unsigned int cnt = 0;
    6 g+ m% A( T2 n
  81. " i% y6 ]3 u: T+ u8 m$ d# s4 c
  82.         p = (unsigned char *)pValues;, T( M5 t" n5 A! S+ B$ S
  83.         while(bytesToAdd --)8 @9 q# A9 L& I4 W& o: U
  84.         {
    6 x( |2 E4 }0 H/ c/ s
  85.                 if (FIFO_AddOne(pFIFO, p))
    + o" |7 Y; G4 O8 b
  86.                 {% l5 ~  U! C0 s5 z
  87.                         p += pFIFO->ElementBytes;
    & ]- h; ]; s- ?* L. z* X/ P
  88.                         cnt++;! m( e) ^$ M6 U$ n
  89.                 }
    2 o+ B$ `! _5 }! p9 H
  90.                 else$ g2 G5 W" w6 y0 D
  91.                 {
    . k! v9 U& a6 g$ [3 k( C
  92.                         break;9 G7 ]9 c' w1 _; f) f9 K
  93.                 }" O) R' S+ ~3 E& K- x. {  n
  94.         }
    & U% z3 n$ _/ M# l+ n0 x' s: n. C

  95. * T7 v7 ^; V1 l
  96.         return cnt;; ?' o% p: g/ b- m% f
  97. }
    + ~& I& {$ v+ V* l" E
  98.   `7 Y% ^- D$ h, p
  99. /********************************************************************//**
    / r. U- F+ b2 F$ S
  100. * @brief       从FIFO读取一个元素
    / c3 f& W: g; `6 G( @% X- _) g" D
  101. * @param[in]   pFIFO: FIFO指针
    ) }# M3 @9 q4 q% E
  102. * @param[in]        pValue: 存放要读取的元素指针
    / V5 Q4 r6 y1 d
  103. * @return      1-TRUE or 0-FALSE" ~) L; k* w  ^' r' C
  104. *********************************************************************/# p& N2 z8 u: ]* n  H3 c0 k
  105. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)! @2 a" O6 z! ^% d  o
  106. {
    ! j8 B. Z- R3 C* @$ o. F, d
  107.         unsigned char *p;
    / D; E5 P7 y: m
  108.         if (FIFO_IsEmpty(pFIFO))
    4 c+ Y  N- r# I% M# Q9 o
  109.         {: h5 l! Q0 ~4 x- G! L" n
  110.                 return 0;7 i& R' K: @1 g5 O% F9 Y
  111.         }3 P4 o$ J( z0 z3 N. y7 r% i9 C( \; r

  112. $ X) J4 G) }- s" S  X
  113.         p = (unsigned char *)pFIFO->Buff;
    & `6 R* c. S7 e0 Z( F% w* b6 x
  114.         memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);( M6 J& E  D' \

  115. - g& V+ n! f/ @6 n4 D
  116.         pFIFO->Head ++;& p1 G; C+ Q) Z& B+ L# b; U2 F
  117.         if (pFIFO->Head >= pFIFO->Depth)
    2 c' E: Q, p* F" }: b# m* ^  s
  118.         {
    1 @! x: s/ u9 s/ e1 |; H8 y
  119.                 pFIFO->Head = 0;- o( q6 e7 J, m) I: i* j% B5 W2 k
  120.         }  F7 ~6 z  \" K, Q0 y; {
  121.         pFIFO->Counter --;
    ) J% w, R( Z! |& i0 e9 j' r7 F  g
  122. + c- L' E7 }6 c1 P
  123.         return 1;5 g; r( f8 s! d9 A8 v9 T
  124. }
    4 \9 C$ y7 N7 }5 A) f# q2 c

  125. & k, z2 W0 B1 K/ X# z( a& a
  126. /********************************************************************//**$ Q2 `) P6 U1 a' t$ ~' T
  127. * @brief       从FIFO读取多个元素% p6 t  t3 r) F! D' `, ?/ o
  128. * @param[in]   pFIFO: FIFO指针  H% T9 o7 g. `# t1 `
  129. * @param[out]        pValues: 存放要读取的元素指针+ R, ?/ X, f) s+ v6 y
  130. * @param[in]        bytesToRead: 要读取的元素长度
    ! w$ I/ R7 g8 R$ Q
  131. * @return      实际读取的元素个数6 ^7 w7 m$ A5 W& B$ C" |
  132. *********************************************************************/
    & B/ A- x7 N* Q5 N. u7 b) h
  133. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)# i. Q6 X/ ]! ?: p* N
  134. {9 ]; }6 t4 r" ~( I6 i; Y/ o
  135.         unsigned int cnt = 0;
    9 n6 L& }. n4 X1 Q9 [9 J5 D
  136.         unsigned char *p;! }# C, y- e) a. Q, }5 o5 j

  137. 4 g4 L( y- ]  K6 Z+ ]
  138.         p = pValues;( n/ a: p1 M& ~7 i( i
  139.         while(bytesToRead--)
    ! w3 g$ {! {& N' a6 @3 I1 N' B# {
  140.         {. ]' p4 h. e+ F, l) a" u/ o4 m9 i
  141.                 if (FIFO_GetOne(pFIFO, p))' e) ]  c8 X( ?. D# {( D2 P' Z0 I
  142.                 {
      W5 E4 P, t$ G% c; q% F. ]
  143.                         p += pFIFO->ElementBytes;
    5 R- r, s3 d. d% @: T
  144.                         cnt++;' x" {( W5 V) ]
  145.                 }
    7 a2 a% F( n6 h5 T2 d% C) u% H( h
  146.                 else
    ) h8 e/ z& U! {1 `6 u
  147.                 {
    5 h' ^; @3 i+ @/ p4 D: e3 i8 V8 E
  148.                         break;
    : N0 E( P4 n- d$ {  y" k# X7 a' ~0 }
  149.                 }
    ! s5 D9 U: i* i* ~
  150.         }* f" C6 G4 l  f) @9 q

  151. : I) I& D, S+ m& u2 E
  152.         return cnt;
    # w- @1 B: q8 y; W% g
  153. }  R" _) r6 M  V
  154. / c! u8 Q, _1 s( G( v8 t
  155. /********************************************************************//**; a/ d# o' ]% y1 E, w
  156. * @brief       清空FIFO& s# K8 w+ k8 K; n, e
  157. * @param[in]   pFIFO: FIFO指针# W; v; x/ G* K2 c+ `5 Z
  158. * @return      None. h9 g5 a1 k, E3 r6 X" K
  159. *********************************************************************/
    3 Y% |0 q& f# [5 ^; b) k
  160. void FIFO_Clear(FIFO_Type *pFIFO)
    1 G, Y* B6 [( H7 ?' ^) O
  161. {) F% e# v3 D% d0 W& R6 @
  162.         pFIFO->Counter = 0;
    3 T1 A$ H  H& {7 D
  163.         pFIFO->Head = 0;& D0 A/ ?5 y$ w  ^$ I/ p; g7 q( ]* l
  164.         pFIFO->Tail = 0;
    ) I/ |( P  e% H1 b4 h' m, J3 ?* \: A
  165. }
复制代码

5 |- E! [0 J' A4 U  I ③ 串口初始化
  y! `/ M9 \/ A7 J5 y
  1. static void MX_USART1_UART_Init(void)
    * X2 ~) o5 K# k  _6 |5 X
  2. {- {) B2 l% \% ~  G5 K/ v
  3.   huart1.Instance = USART1;
    + {: B* c- r) w: Z
  4.   huart1.Init.BaudRate = 9600;0 b1 e: J. Q- P8 B; q9 s/ t
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    " G  c$ T+ E$ h: y8 r- n  e
  6.   huart1.Init.StopBits = UART_STOPBITS_1;' L6 j7 l# O* t! m( j
  7.   huart1.Init.Parity = UART_PARITY_NONE;: Y% |) n1 u, K2 u
  8.   huart1.Init.Mode = UART_MODE_TX_RX;  c' K' Z' ?0 [2 U( k" H1 b' ~; a* R. ^0 I
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;5 J# g$ Z6 F! G: U& |$ P
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
      g) X9 w  t- V( Z4 J. Y6 F. i
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    . P' d2 I* Y# ~- c( P! F6 n; u
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;/ T. v; |: p, A3 o  M0 h8 h! `4 Y
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK); m5 `: L' H( S
  14.   {4 X" z$ z9 [; E2 a/ a& Q! ?* _
  15.     Error_Handler();
    + W- C+ d6 W, v! N
  16.   }  
    & z  P' H( t0 K' F, l
  17.         % G- n, t( M* o5 o
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)
    $ m5 K  o$ }+ ~. i
  19.   {
    " |' H6 _& w  V
  20.     Error_Handler();
    ' x$ e) L, d( j
  21.   }1 O$ O5 h  y$ B
  22.         6 p5 Y3 Y' L% _6 q
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 0 e7 @4 o( I  L2 d" ~+ N
  24.   /* USER CODE BEGIN USART1_Init 2 */
    : E' q2 U5 l3 D5 R
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)1 J8 w; ^5 c4 A# s
  26.   {
      |0 e/ }4 C  x* t# n2 s
  27.     Error_Handler();1 k4 E- S7 G" D8 n# K, B- a% B) q. J
  28.   }1 T  h2 H& \% o5 l% H
  29.         
    8 g4 d! l8 K4 y& ]
  30. }
复制代码

7 c: w8 {/ e  Q& O ④ 接收空闲中断- z: U5 U" b6 `2 O# ?8 ^! T( W/ f
  1. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)( M1 b9 D+ o. h2 m  m/ @, z
  2. {
    ! V' Z4 A; h; ^8 Y5 y1 j& F3 I5 C
  3.     HAL_UART_DMAStop(&huart1);
    7 X( w, @4 k# Q! P2 G) k
  4. 5 I' N; R3 g  P/ T: |% Z
  5.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    " M! J$ d, E& m$ C5 y. N, S& I
  6.         
    . }/ Y1 s6 A1 M* s! F. D
  7.         FIFO_Add(pfifo, aRxBuffer, data_length);; y. L5 {  K" i& l& J
  8.     data_length = 0;
    2 a" Z( {  I. A  V1 v) C( M
  9.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    8 c( |' a! O$ r2 {+ f9 i0 z  t
  10. }* y: p& i+ Q0 j" j% ?

  11. 8 K, P" ]4 a  F# Y! ~0 _0 u
  12. void USER_UART_IRQHandler(UART_HandleTypeDef *huart): w/ P; m& f! B& L
  13. {
    ( Z* |8 L/ I' i- S7 {" \
  14.     if(USART1 == huart1.Instance)
      }( X3 f5 Q" ?5 W* S# q. X% r
  15.     {
      g! O3 P* o. z# l. i% h/ Z
  16.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    - r" T2 }9 j7 C; W8 I9 `$ C: {
  17.         {
    9 P" A4 n& Y  s, K
  18.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);% G1 K; J& V# l- x2 `+ V
  19.             USAR_UART_IDLECallback(huart);
    6 G/ {; D4 ?; e3 c
  20.         }
    ! M: L: G6 k6 Q* t
  21.     }
    3 I" f! s9 @* k+ t2 y- H2 Q
  22. }
    ) H2 u4 I3 S. F# P/ X( R
  23. 0 Q: Q' b2 H4 X5 r% f' r
  24. /**' p5 F" I+ }' \% R' h* Z( n
  25.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.$ i) b6 c. Y0 K7 |7 \
  26.   */: D6 t6 O2 i/ S% m: K* G/ B# Q' D6 p
  27. void USART1_IRQHandler(void)
    ) R- C8 p1 A: u" V
  28. {$ C. V; q8 k1 i6 d" k0 `
  29.   HAL_UART_IRQHandler(&huart1);5 A6 g' D1 [- I
  30.   USER_UART_IRQHandler(&huart1);; G- [! [5 Y, K3 B( i) C" `& S
  31. }
复制代码
( i% R$ K; `; D1 a; g7 w. \
⑤ 主函数调用:
: H9 s+ T2 c* h4 Z" T
  1. #define TXBUFFERSIZE                    302 ?' f" C6 l" ^" b
  2. /* Size of Reception buffer */
    - O# W. X0 ~$ N% D' u# {; b# J
  3. #define RXBUFFERSIZE                    TXBUFFERSIZE
    5 a% V& A0 C$ i+ E
  4. #define RXFIFOBUFFERSIZE                TXBUFFERSIZE * 5
    8 l- S1 p& u9 ?  }: s: V2 r

  5. " J" j- z: o  W- ^; e% r- x

  6. ; ~7 }/ u* ]  a+ M* a* }. T
  7. uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";
    3 f( t1 g2 r' t0 K

  8. . _3 z* r' X* R/ V9 R% T7 a
  9. /* Buffer used for reception */5 W8 F/ t( b! M
  10. uint8_t aRxBuffer[RXBUFFERSIZE];) V; s3 I8 u9 @
  11. 4 w, J0 h& ?, ^
  12. uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];' S5 V5 m1 p+ k8 C: O
  13. FIFO_Type        fifo;
    - h& k) R# V/ P3 B9 S' }
  14. FIFO_Type        *pfifo;- ?" w6 S/ r( p* e% v( b: Y# \' j
  15. 5 N4 k+ K9 H4 `) B
  16. int main(void)3 B* ~& b1 P# _  W' w) S
  17. {3 j' d% d' `( F3 g! X5 {
  18.   /*此处省略硬件初始化*/
    + A# v( I2 U; m' D: R' Z4 c
  19.   if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
    # p- s6 P, V  A- D/ C5 m
  20.   {
    $ W( h6 O# z5 q& E# Y* I8 u
  21.     Error_Handler();3 R  w3 s, l+ ~  }6 Q# u" H4 W' g  a
  22.   }
    ( I4 q, f# Y/ \1 Y7 l
  23.         
    # l2 X' A+ b! O7 J% \
  24.   pfifo = &fifo;6 v8 @# T: V' [
  25. 0 G0 B5 Y3 R7 T% ?$ c$ ^
  26.   FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
    - ?  m/ e7 |) M7 Y* r# R2 r! i
  27. : S& F8 u2 t3 X
  28.   while (1)
    ( f% q2 g4 C& `4 b  h7 {
  29.   {
    5 T, I7 z% T( U- n9 Q$ O
  30.         /*一次接收的缓存,重新发送*/
    $ t7 c; {" O( O3 l' O+ p
  31.                 if(!FIFO_IsEmpty(pfifo))
    , [# M+ L! j  \+ {- J
  32.                 {( y2 m9 d! U. Y" ~( M0 n
  33.                         uint8_t a[100]; //存放读取fifobuffer的数据0 ^+ n9 z+ U* E: q4 J3 ]! t( R5 n
  34.                         int i = pfifo->Counter;//先保存接收缓存的数据个数
    3 P" k- Z4 a+ Z6 w
  35.                         FIFO_Get(pfifo, &a, pfifo->Counter);
    + Z5 Z3 K- [$ J. X& U  H
  36.                         HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率
    # _( w: W1 C  |7 H9 h$ D
  37.                 }
    % {5 v0 l0 n8 u& |) Q  g2 k
  38.   }
    ) O2 E5 M9 `  R/ p3 b
  39. }
复制代码

# R5 y% q5 @2 _! K' n9 S测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
* a. G% s& d+ h2 x/ b) r! Y- Y$ G9 O
7 X9 v. F+ Z" U- p/ u$ Y
202109031459585.png
& Y' R9 E, |; [6 J; P3 g

* F4 s  Z! A( g' T6 q) M8 Q问:关于 stm32 HardFault_Handler问题处理?
0 y1 K( m& m6 `3 }; N+ h. \" F6 \5 A
% r* c/ ?4 E; I2 Y0 r) k$ ^; UANS:
3 K3 h1 c, v: Y2 P% Q. Y3 f8 X- c: n4 u$ t; n* Y
        在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,
- W& b* f$ b$ I' ]- N+ C6 q- a; P: Q# [! x4 r2 J
20210903150306628.png

; U/ J5 Y6 o! V" i: f" b' m2 O4 J: N
20210903150316369.png
3 J4 e9 ?% L2 Q( ?

1 A( ^1 B0 v8 [$ B( v  C' f 最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!
8 o$ X3 R8 K! p9 {( l
  1. pfifo = &fifo;
复制代码
# I- V* B3 E, r2 ^6 [

% C5 y- {6 U' O" s6 @' [. S
. x1 W/ C, \  m& M4 k. E
  F, }, V3 `( F, ^' \
收藏 评论0 发布时间:2021-11-25 15:00

举报

0个回答

所属标签

相似技术帖

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