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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
一、STM32CubeMX开发" h" K( w- ?* f) L
1.1 新建工程
- A& i4 U5 `* {: Ifile -> new project
1 t0 Q5 h5 L4 J: J' n
' J, W! }1 f9 a3 i  |选择芯片-> stm32 core内核         
" y: a5 [$ o0 m- x( @4 i$ M( O# f/ Q8 i# c
                   stm32 series 系列
( i4 Z1 _, P' Z9 U6 A3 w+ `. \7 a7 V& v5 q
                   stm32  line. S# k( C8 N1 V/ X4 Q% l9 ^
# {( R1 e5 {& Q* |7 I5 f
                   stm32  package
+ n7 l- o( c  g/ j) z
. z/ y: {4 V; j. J& J, _选择芯片根据自身需求去选择,目前该项目是stm32f0系列
! J2 ^1 Z& r/ M  s9 _
/ b  c/ |( _/ T5 R                    stm32 core内核         M0
/ E; T$ k% j) o
8 G  `! }9 O+ a                   stm32 series 系列      F0
; f. a. V6 h- m5 `! i7 C# V, M
) |1 e# U- w3 w                   stm32  line                 F0X1
/ ~( K- e6 Y9 {0 p
2 F1 T# t( q3 L9 l; p, @( X7 G                   stm32  package         TSSOP 20
  Q: D8 h  z% M6 G' ?7 A. ^6 z5 H( a1 b+ Y: V
1.2 配置 USART1
1 k) N2 _( }# K5 t配置 USART1 的模式为 Asynchronous,即异步串口模式
" o3 O& |: x2 w$ R; x' \' \* g6 d. Z* K
20210827163252369.png
! S, F$ J6 m- x. t* n, t& Q6 J
% K6 O3 ~" F  z9 C# X- n
1.3 配置串口参数
/ ^; S& N3 z- ^" J/ S 根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,1
1 y4 S, o6 X3 D% ?
% P% }+ z2 r2 k$ h+ f
20210827163448427.png

1 E" `  G9 e* U- D: g9 v7 ?0 I% V* l3 T3 `
1.4 设置DMA. F, B& D" P% X' N
7 c+ }" ~' q" e  e% ~
20210827164240955.png
4 t/ v0 |9 u, y/ c

% p* b& }, E0 c. \ 1.5 添加串口中断: l$ J; H2 n: _
8 H3 a& T2 z: l+ ?: G6 e
20210827164323729.png

4 ]3 r" }% w; c6 U1 `+ B: h
2 R+ ]9 V* ~) L 1.6 生成源代码。0 z$ _6 z( i6 i% A4 u- f
在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。0 v9 U6 M9 H) Z5 I7 @% V5 v9 z) ~9 g& r% q
% V7 D. b6 }& s0 @, E- o/ W# q
20210827164544427.png

: i7 J# J3 S! e9 A. M: c9 A0 X3 F+ _7 {2 ?! u( p9 o  K
生成代码完成后可选择打开工程。
% c: b$ p0 Y3 Z( U3 U, X- o9 x1 f5 T( [! i( _7 t6 d$ J! D" m
20210827164829635.png

" O, k0 r# Q4 y1 D4 s$ H7 g! t% l' v) P# U7 I& O
二、代码部分
1 z4 h. P' y% r2.1  接收中断处理8 w5 X' l9 T: H& v
2.1.1 接收固定长度:(舍弃)
5 {* f/ {8 x. [  x* c* k- ^7 {只有接收缓存到固定长度才会触发中断
+ O) v' f$ L& F; v6 |* _, O8 r( N/ Z串口接收回调函数6 z1 c4 }* y* W% A

( H9 Y0 w. K/ ^1 v/ `
  1. uint8_t aRxBuffer[RXBUFFERSIZE];
    * J  }3 V4 L2 }% _1 T3 |6 h
  2. /* Size of Reception buffer */
    + B$ @5 g; h  E1 X  g  z
  3. #define RXBUFFERSIZE                    10
    5 x8 \  K5 K* i4 S5 ?+ ?2 c
  4. 5 u& h( ]. k* [6 p) [8 B
  5. 5 |! Q6 @3 x3 g. ]
  6. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)" U( w, D9 n7 v  x3 C# O
  7. {
    - O" k; y$ p1 W! @  F) F9 {% ]* E
  8.   /* Set transmission flag: trasfer complete*/
    % S: Y+ }9 i) _3 W! {
  9.   UartrxReady = SET;8 b% Z* b$ ~: c0 f5 d5 s8 B: V7 X
  10.         HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
    5 E0 H$ M  Y& K7 x- v% W0 i
  11.         HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);4 c' X" _) z$ ]# b3 l: e6 ~" |
  12.   HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
    3 Y4 S4 ]  X3 s: K# M/ V/ U

  13. ! y& u8 `2 G! W
  14. }& ?* d5 X2 ?7 z9 x; o

  15. - A: v% W& o+ p- b
  16. void USART1_IRQHandler(void)7 n9 r, u+ u1 ~* s# {- A
  17. {2 d& S6 }  F4 w2 T6 w! ?0 N8 i
  18.   HAL_UART_IRQHandler(&huart1);' W3 r: u$ _3 ?) l5 n
  19. }
    % e% [- z! X! ^! j6 ?& a' y
  20. . `& k9 V( x; i1 b( ]! A1 l

  21. 3 O% `* m& a' }/ I8 m  Q: `( c
  22. static void MX_USART1_UART_Init(void)) Y/ _! j. I1 _- G
  23. {
    + e  K: l8 {7 W0 H. V+ ]4 ~% x1 R' e
  24. ( Z2 m7 s7 M) V8 X7 @( A: t
  25.   huart1.Instance = USART1;
    $ d( c$ C9 v& A
  26.   huart1.Init.BaudRate = 9600;
    " L1 [+ C0 s: F# q$ A
  27.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    1 Y9 p& \; G9 N4 c6 B) N1 v8 E* m+ M
  28.   huart1.Init.StopBits = UART_STOPBITS_1;
    0 O7 u9 |  ~0 O# }4 d
  29.   huart1.Init.Parity = UART_PARITY_NONE;2 D" F) K2 }, `/ M. [; p4 f
  30.   huart1.Init.Mode = UART_MODE_TX_RX;
      G- S& ?8 K. g6 r1 Y8 s
  31.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;9 Q$ |; R" J; T) s* Z
  32.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    ( P( [/ W* q" B9 y
  33.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;( u4 G# B1 Q# h& V' p3 C
  34.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    % G  \+ W3 F* p; V. {2 Y
  35.   if(HAL_UART_DeInit(&huart1) != HAL_OK)
    0 i2 c# E; B4 j5 o# D
  36.   {! w' O. t2 P/ J# |
  37.     Error_Handler();
    / Q" k% v& {) D+ Y8 `
  38.   }  8 Y& z2 w/ u- x& f- V
  39.         " o3 `; w+ w& x9 _1 n3 ^' ]
  40.         if (HAL_UART_Init(&huart1) != HAL_OK)9 p. g2 E8 c( T! a6 X
  41.   {
    4 s0 l7 y9 j( q2 s$ l
  42.     Error_Handler();$ M, q- C2 m, e
  43.   }
    0 @1 b1 G8 H" A4 R3 A
  44.         
    8 v8 m9 u$ y, K& ^0 x, O
  45.         UartrxReady=RESET;
    ; h0 q5 Z) u2 j& u
  46.   /* USER CODE BEGIN USART1_Init 2 */
    . A# T0 @: O# S0 q+ Z
  47.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    6 y- d( ~4 g0 `" K) l
  48.   {' p1 ]9 p$ J: ?, P% D, g0 C- L
  49.     Error_Handler();1 r2 t# n2 I" y
  50.   }
    * d1 L8 J1 l1 n
  51.         
    2 N( ^4 O0 E5 }- S) Y4 S" }- t+ Y5 W
  52.   /* USER CODE END USART1_Init 2 */
    3 c7 ?* a4 M' R$ u' y9 a
  53. }
复制代码
4 ]  J9 k8 X$ F& M
从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。' Q2 L/ Z" ~" u- p

3 n' _$ u0 R3 K9 D
20210902164819116.png
* |, E+ ]2 ], \. E4 p) h
  O. u% h3 W4 d: X$ B* }
2.1.2 编写空闲中断函数接收不定长
4 ?0 R/ R- h1 OUSART1初始化:1 D% t) x. n2 `
  1. static void MX_USART1_UART_Init(void)* C( |9 M* `8 r) n6 i; t
  2. {; o+ m+ z+ \1 t6 t0 B4 B: {
  3.   huart1.Instance = USART1;
    % A2 ^2 ^2 M7 g" @
  4.   huart1.Init.BaudRate = 9600;
    9 P! z* N* V8 n5 F( `. L% V
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    5 a9 V. i) o9 y1 ]
  6.   huart1.Init.StopBits = UART_STOPBITS_1;
    / o8 X0 L$ ?2 B' Y; G
  7.   huart1.Init.Parity = UART_PARITY_NONE;- v! X) c9 W4 N
  8.   huart1.Init.Mode = UART_MODE_TX_RX;
    7 W+ X3 D! T3 Q( w/ Q) q" o
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;+ n% _8 y) [$ b7 C
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;, j+ x7 L9 E5 I" h% {1 M1 {
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;% O: \" G. L4 ]$ z( j. l; w
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    : I" {  i) p. O+ X; s: ]- \
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)4 N3 p2 q& e/ N* v
  14.   {3 b, C/ a" x$ @: d! c* u7 J% J
  15.     Error_Handler();
      ?8 ]( {% @# I/ c' Q! V
  16.   }  
    . I0 J5 k1 e( \" g$ x
  17.         
    1 `% s" y7 [" {* Y8 X% q; C
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)
    6 z* G% V3 x  q
  19.   {
    + e8 @1 [' y9 Z% e0 h" B6 t
  20.     Error_Handler();
    & l1 t& v2 B- C6 h* K! j
  21.   }
      g' A) c$ a! W$ [  @" B% [: B

  22. & H2 y4 N7 m9 I* v. A7 [$ h
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 8 P8 Q: U, X+ s
  24.   /* USER CODE BEGIN USART1_Init 2 */
    9 m  L1 u' L. c* D: H9 ~! w
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
    ! q$ S( ]( W: K; N3 {
  26.   {* m( U4 j5 b% @5 ^  p
  27.     Error_Handler();9 g) u/ F4 v9 S
  28.   }
    2 \7 ]1 q( M/ b7 {) L4 e* r2 j
  29.         
    7 R8 t) o# F9 s4 f" m/ ]& ^2 s
  30. }
复制代码
4 ~% B' q3 \) v" F
空闲中断函数: ! A/ X# A0 V6 d# p7 o
  1. #define TXBUFFERSIZE                    30
    . d2 i! v/ U+ x% L
  2. /* Size of Reception buffer */" C" P' H4 U! D& N" U
  3. #define RXBUFFERSIZE                    30$ M' u; A! @1 V; \7 H
  4. * V! C$ O4 s4 j9 j
  5. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
    6 ~1 K$ m/ ~7 `3 i
  6. {
    8 t6 W4 j, h0 d3 }6 A' x
  7.     HAL_UART_DMAStop(&huart1);& m4 P" ~, G% `! n" Z6 a
  8. + ?/ C  a7 ~& Q6 j" z
  9.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    8 K, g3 p1 a5 n% g3 A" J
  10. 1 F" v  ~. i0 |2 Y. k6 ]2 m1 [

  11. $ }* K/ \9 s7 |; {7 l
  12.     HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);
    - X3 z/ a1 V7 D! m6 G" d

  13. & G4 K  l# F  ^0 _% l+ o
  14.     memset(aRxBuffer,0x00,data_length);3 Y& a' t2 |; N6 r9 k
  15.     data_length = 0;7 S( b: o' g" _# H0 X9 Q
  16.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    5 ], I# A9 S5 ^# l! ]( c2 f9 b
  17. }
    5 p& b# a$ f* p3 ]& V  _: P3 X" F' l

  18. 5 l3 V% ~0 [; ^0 L3 ^9 e5 c! u  J
  19. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)* @  z% F0 e, B8 S% a! n
  20. {/ N: [/ a& c4 L" v* v( \2 ^% |
  21.     if(USART1 == huart1.Instance)
    * S4 K" J! G! E/ |0 U8 G' M
  22.     {( ^3 s: Q+ v" j. d% h
  23.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))! `$ p+ R: M2 j% I$ ?2 ]8 n+ W
  24.         {
    - U+ |4 ?# {6 p4 |
  25.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    6 l8 [9 k0 m1 r: i0 G
  26.             USAR_UART_IDLECallback(huart);
    3 Q% A( A9 c& r& e+ Y4 t* D0 `
  27.         }+ t5 ]! o; t9 \$ Y* v* B! ^& t- ]
  28.     }
    0 ?. p2 ]4 g; A: A$ E  _5 h
  29. }& `2 t  G( T9 _% P+ E
  30. 9 [8 N: e) H; R! W' ?9 L* B$ X- @
  31. /**+ |- k+ u: X" ^) X" g3 i, H3 {
  32.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25./ J/ U. L0 Y2 P3 I, O: B) t' x
  33.   */8 h" D$ E1 R6 T+ j/ x
  34. void USART1_IRQHandler(void)
    5 P4 N. U/ X9 o) n
  35. {
    1 a, q( ^% z# F5 q! u
  36.     HAL_UART_IRQHandler(&huart1);8 l) O; }; ~# l+ h
  37.     USER_UART_IRQHandler(&huart1);
    2 g6 D6 Y4 }% n1 c$ t
  38. }
复制代码

, V; {/ y7 V+ T- a) b7 G& B可实现不定长的接收! 7 g. d0 W. N( B& h
  }8 ^2 L7 N9 T" j" S* J* L5 |
20210902171851390.png
( j: X& z: S9 X# r

1 ?6 w4 a$ H4 y" d7 O 注意:5 L/ o7 b# s2 \0 o
在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。  j/ P& V% ]7 S6 i( Y1 k$ r+ [
2 u4 A( f* C+ c) _7 s: [) Z, k
三、使用ringbuffer实现任意数据类型的FIFO处理接收数据0 h" c! S5 N3 O  }. W
使用原因:
) n! F9 l- ^3 e" ~6 t- u* U8 T  l! M! p
        虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。
5 @) o6 }6 l6 ~3 n4 E8 M) C- K  p, D1 [. Z
        因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖4 Z/ w- r  Y8 a9 |' R- s+ \

* I/ d! R( r  j2 ]6 ?- X4 {① fifo头文件:
% H6 p! Y0 O' x, y9 i
  1. #ifndef        __FIFO_H_' D- t* F+ [- K0 [9 M) ?8 V6 `9 c
  2. #define        __FIFO_H_" O7 ^9 T5 g$ C) B$ h* Y0 p$ J

  3. 7 [* n7 q2 H/ x& P! }) ?2 n
  4. #pragma pack(4)
    4 ?4 S+ Q/ J* s3 n4 U
  5. typedef struct FIFO_Type_STRU# p- ^' @" p4 O+ c
  6. {- c9 r& N9 G9 G# l% j: M6 ?
  7.         unsigned int                        Depth;                        // Fifo深度
    1 u; Q) b3 @- V" N) {4 m+ q9 U& l
  8.         volatile unsigned int        Head;                        // Head为起始元素
    ! ~* T, i6 b3 Z3 }7 G1 z
  9.         volatile unsigned int        Tail;                        // Tail-1为最后一个元素. t# B0 G, |% ?+ }' \( b) t
  10.         volatile unsigned int        Counter;                // 元素个数6 m, p* d0 E& G9 h2 B9 l5 x
  11.         unsigned int                        ElementBytes;        // 每个元素的字节数element
    0 K# f+ }4 x  F$ x5 c6 M
  12.         void                                        *Buff;                        // 缓存区% C$ q. o, V2 k' {
  13. }FIFO_Type;4 Y# Y9 T7 v& H+ L1 C( {) n
  14. #pragma pack(): L  P# z, ]8 I
  15. ' x& @. n0 O, ^8 @' X/ q( i
  16. /********************************************************************//**
    1 w  z% F% h* n! f" ]
  17. * @brief       FIFO初始化
    0 K% }6 X7 T0 z# @, G0 W
  18. * @param[in]   pFIFO: FIFO指针: s8 j$ u0 m1 H$ {" M
  19. * @param[in]        pBuff: FIFO中缓存
    - X+ r' P# X+ u8 x) y! O3 b8 X
  20. * @param[in]        elementBytes:FIFO每个元素的字节数+ a& s( ~$ S8 k" x( J' H
  21. * @param[in]        depth: FIFO深度9 i. ^2 q, j3 G8 w' G
  22. * @return      None# J4 D2 r' R1 S+ N2 _6 a
  23. *********************************************************************/; ]6 M$ T) ?, z
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);
    ; l& z5 \/ d3 |
  25. 5 O! K4 \; P- f0 z
  26. /********************************************************************//**
    ! ]$ ]7 @% l( w7 [3 C. p
  27. * @brief       向FIFO添加一个元素2 L  W0 T8 J7 ~$ O( T- ~- E
  28. * @param[in]   pFIFO: FIFO指针2 g% Y7 |; L( [$ s
  29. * @param[in]        pValue: 要添加的元素
    , @# `& E# a1 ?) Y* D5 X' {" F
  30. * @return      1-TRUE or 0-FALSE5 ~$ |6 `0 m# _8 T- P* j/ l  L3 v& ?
  31. *********************************************************************/. [% X, T: L, b. Q- o( d0 b
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
    1 }9 X1 K$ O9 t

  33. & V5 t$ v! Z8 E6 q; T) Z. }
  34. /********************************************************************//*** X/ u1 J# E7 t5 m9 x. V) p
  35. * @brief       向FIFO添加多个元素7 G6 e* u9 h1 D! W+ t6 \8 e
  36. * @param[in]   pFIFO: FIFO指针
    7 |" ]- x3 T' h& @: z
  37. * @param[in]        pValues: 要添加的元素指针
    ' o. I1 A' N. b8 R
  38. * @param[in]        bytesToAdd: 要添加元素的长度+ I( D5 @1 Y+ k' F
  39. * @return      实际添加的元素个数
    / b, ^' z/ Y" @4 a
  40. *********************************************************************/
    + s. H4 d- F) D3 V8 Y) g( Y
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);
    , O% @. s) F! @9 n

  42. : D9 u! i: l9 ]# Z
  43. /********************************************************************//**
    ) @; n/ v. T3 J$ Y! _6 A6 ?
  44. * @brief       从FIFO读取一个元素
    ( K% s& _( y1 F+ U6 J& f
  45. * @param[in]   pFIFO: FIFO指针
    % q' O/ J) p' O; {7 Y4 ?
  46. * @param[in]        pValue: 存放要读取的元素指针
    8 g7 o. U) |9 e8 u, ~& Z$ |
  47. * @return      1-TRUE or 0-FALSE1 n* v0 s+ M% T' L0 f% r  v* c
  48. *********************************************************************/
    / \/ }0 P9 _  o& k( T$ `+ f
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);9 c; T  S! S6 y7 R
  50. , X+ V. `0 D+ ?8 s' Z1 |
  51. /********************************************************************//**
    0 C6 y) b# u/ `5 X
  52. * @brief       从FIFO读取多个元素2 l+ H; K+ \* H9 `2 k. e
  53. * @param[in]   pFIFO: FIFO指针6 B7 i8 _' P* O; D3 T; Q; ?
  54. * @param[out]        pValues: 存放要读取的元素指针; L) N8 ^* P3 X1 F( [
  55. * @param[in]        bytesToRead: 要读取的元素长度
    3 A# c8 u2 s. r' F, i
  56. * @return      实际读取的元素个数
    ; u8 B$ s* P3 E! k! W  t
  57. *********************************************************************/6 D7 i8 X! M, `) h" v; G% x0 W
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
    0 d; v2 w& _& J: H

  59. " b  S1 {# w4 b, t

  60. ! L* y$ C8 r) ?
  61. /********************************************************************//**. |5 S& i  X9 A  X* x& S; |& D
  62. * @brief       清空FIFO( g' S: ?, _* _: v
  63. * @param[in]   pFIFO: FIFO指针
    9 J5 M$ Y' H  H0 @  L
  64. * @return      None8 ?1 h8 P% {# k% B7 N; P3 W
  65. *********************************************************************/
    2 S1 V7 H6 \& _1 X9 L5 u. H& a" ^& P+ Z
  66. void FIFO_Clear(FIFO_Type *pFIFO);
    ; g; U" C6 g. S; N$ d+ x+ l! g

  67. - i8 v$ k8 p: o/ p9 Q

  68. " x+ b9 q0 y- P, m- \
  69. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);
    1 @% P# c% i' u) Z

  70. $ H* S) Q/ K- n  }* Q2 n, M% Z
  71. #endif
复制代码

; G% n  d: `! u! D② fifo.c程序主体
; {; O3 i( ~- U% O* @- L: u0 o- ?7 k5 z0 D5 o' r# m
  1. #include <string.h>3 |# O/ X/ Q4 o: ?4 p. O% J- C! Y
  2. #include "fifo.h"% t" t& I! `2 f2 Y. e& C

  3. % ]+ l4 q. W" v7 B

  4. : ]9 I. c" L# c% n& h: [
  5. /********************************************************************//**8 Y- |/ Q- D/ `# g+ b! @1 s; M0 Z
  6. * @brief       FIFO初始化
    3 p0 y7 u! l* _6 u3 f
  7. * @param[in]   pFIFO: FIFO指针5 T" r5 r' X2 [; Q
  8. * @param[in]        pBuff: FIFO中缓存
    6 U! c/ b3 ?! p' @/ v* H' x
  9. * @param[in]        elementBytes:FIFO每个元素的字节数
    2 i2 \5 P- F* y: V) ^
  10. * @param[in]        depth: FIFO深度& F, O1 ]' R3 L% u! E
  11. * @return      None
    ' a' ]' V0 j3 s
  12. *********************************************************************/" w3 S  ?# x" P
  13. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
    $ n; y; u: n+ W" O5 I" [
  14. {! m, T, d/ v  K
  15.         pFIFO->Buff = pBuff;
    + @6 I; D8 ~' E/ M
  16.         pFIFO->ElementBytes = elementBytes;+ w% Y* a, m3 g9 H& s/ c
  17.         pFIFO->Depth = depth;6 G, J/ l/ @3 Q& @
  18.         pFIFO->Head = 0;
    1 S* n0 o& ^' F! _' A
  19.         pFIFO->Tail = 0;
    ( {* @& ]  S0 D8 G* {* x
  20.         pFIFO->Counter = 0;1 p! K! m/ V# a5 Z  x1 k/ E
  21. }
      E& Y' j! q8 h. ]; P0 A

  22. 7 u7 V1 p: G  w1 y+ U
  23. /********************************************************************//**" o+ |9 Q9 U# Q: y( N5 b
  24. * @brief       判断FIFO是否为空
      q0 I3 s7 B9 P, G7 b
  25. * @param[in]   pFIFO: FIFO指针4 f& r+ T: K: G" G9 M0 ]
  26. * @return      1-TRUE or 0-FALSE
    ! ]' i9 b; `( q, D- o9 Q3 y
  27. *********************************************************************/
    8 M! D0 Z6 [, ^! x; {' v% P$ l
  28. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
    # H* b5 \7 E* J% Y1 `% v
  29. {' ]: v) S# [3 y( f& g
  30.         return (pFIFO->Counter == 0);5 Z7 S' [4 [' v5 v3 P
  31. }
    ) }4 m7 z' b0 Y, @) u% N
  32. ; d/ M! G# R# m& d2 ?3 x
  33. /********************************************************************//**
    $ s8 |4 c+ s, \% T3 n; ?
  34. * @brief       判断FIFO是否已满. \1 W( X$ _! A* g
  35. * @param[in]   pFIFO: FIFO指针) A7 X2 G& y0 m8 _' ]6 S
  36. * @return      TRUE or FALSE# t: G1 M* i# s! U  ?8 t
  37. *********************************************************************/
    ' n6 {" P6 `0 h
  38. unsigned char FIFO_IsFull(FIFO_Type *pFIFO), P' N. p# f6 W% q; h$ `1 [
  39. {) [! k1 o0 z& s. M. z) y( ?
  40.         return (pFIFO->Counter == pFIFO->Depth);. k& ^, M6 N( d8 E0 ~( }! j
  41. }
    ; g7 r4 W" U/ m& y: o9 N' c4 v

  42. ' ^9 o1 U! j3 a- `
  43. /********************************************************************//**
    4 J2 O  K: Y! N; N3 V/ Q( c
  44. * @brief       向FIFO添加一个元素6 x! L. `: m, q
  45. * @param[in]   pFIFO: FIFO指针
    : ]' g% x7 W$ a  Q+ k, f. E
  46. * @param[in]        pValue: 要添加的元素
    1 V% q- k! j7 X
  47. * @return      1-TRUE or 0-FALSE
    5 ?: n: F6 C( b% N5 w: w& d: a1 n
  48. *********************************************************************/
    ; m, j$ R+ ~" r; ~. j
  49. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
      E& o; h0 E5 j* b6 o
  50. {
    , q: U+ N  n5 e; P
  51.         unsigned char *p;' b4 X) A% u0 }+ b6 i4 n

  52. 9 l! H' N2 o" V% a" Q7 D& n
  53.         if (FIFO_IsFull(pFIFO))
    2 |: O1 o8 m$ e8 A6 @
  54.         {! y5 j/ V" ~# V" M3 y1 |7 u
  55.                 return 0;
      Y( R' S& Q+ ?) N3 k
  56.         }4 ~. }' e, x; K9 X

  57. # o5 ~# t8 ^0 V, ^0 D
  58.         p = (unsigned char *)pFIFO->Buff;4 U8 ^0 Q  Q) i8 n5 W0 _
  59.         memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);8 L: R9 ]4 N" M% j# O
  60.         4 ]2 t  d9 }) J7 y0 S7 A
  61.         pFIFO->Tail ++;- W5 P* J/ h; P8 A* R( C- N( o
  62.         if (pFIFO->Tail >= pFIFO->Depth)
    : p* g/ {9 ?( S/ X5 O
  63.         {8 k4 ?& Q2 f% h$ \1 W( K
  64.                 pFIFO->Tail = 0;$ L$ R3 N4 a2 p5 f
  65.         }7 }* l* v/ s. B2 p% v+ V
  66.         pFIFO->Counter ++;
    7 [5 |" w$ a1 H7 Z4 I) M, Y: f
  67.         return 1;
    " Y) ?2 b) _( i
  68. }
    ! N; l) h7 S) s  X0 ?4 n2 x/ X$ u
  69. * }/ w- m  W/ {. |
  70. /********************************************************************//**
    - e; w( ^9 P: d" s
  71. * @brief       向FIFO添加多个元素
    5 k6 V) d5 f8 @1 ]: Z% O
  72. * @param[in]   pFIFO: FIFO指针. l7 p4 d6 T2 U8 f  Q/ L
  73. * @param[in]        pValues: 要添加的元素指针
    ! ^1 n0 G" ]/ k5 |
  74. * @param[in]        bytesToAdd: 要添加元素的长度
      z& v5 V4 w" U5 d4 g8 D( M4 _1 T
  75. * @return      实际添加的元素个数
    8 W( j1 F  ^# E# K
  76. *********************************************************************/0 M  @& W- x& U6 F
  77. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)# K3 V+ l, ]! e
  78. {
    ; X6 G( @% v7 I( `/ s+ q
  79.         unsigned char *p;- W/ [0 i- e* b! q" R* D4 H5 i
  80.         unsigned int cnt = 0;
    ! R! C* U; \+ @' y% i
  81. . ]) i. N* y3 @" m3 T/ x
  82.         p = (unsigned char *)pValues;  y6 S- e" I7 b2 I0 y
  83.         while(bytesToAdd --)
    ' y* ?2 f1 e: X' u; ]# O9 r
  84.         {
    # j1 n; p9 W# J( K' U% N6 g
  85.                 if (FIFO_AddOne(pFIFO, p))9 m# J. @) N& s5 `% m: s4 P  i
  86.                 {
    6 i) J+ R) T$ C2 [8 i5 E1 J
  87.                         p += pFIFO->ElementBytes;
    : a1 z# B, |6 G/ Y: W3 C3 U1 p
  88.                         cnt++;7 O) j( \/ e" O$ r/ U% B2 v
  89.                 }6 q- d! C  a8 i
  90.                 else! Q$ e! T7 @5 V7 i, ~4 Z
  91.                 {
    % O) ~2 S, A' g- X. Z
  92.                         break;, ?4 g( C# k+ h  b% J7 }# P8 n' E
  93.                 }* j2 x- L2 m7 e# p. ^  o2 C0 p
  94.         }
    5 D) ^+ W, E. u. i- h
  95. 6 h+ S" R7 i2 y" _  c( ~5 L- Y
  96.         return cnt;
    / a# q& g& S4 r
  97. }
    $ l7 v9 {* G- `

  98. ) S& `* C3 v8 _6 V6 N
  99. /********************************************************************//**$ D& C6 ], m$ V' \* |
  100. * @brief       从FIFO读取一个元素
    $ [# R$ S" r- ^: s
  101. * @param[in]   pFIFO: FIFO指针
    : N. b! j% y& f5 W: W0 B$ g+ M/ A
  102. * @param[in]        pValue: 存放要读取的元素指针
    4 u$ N& u3 y( H
  103. * @return      1-TRUE or 0-FALSE
    6 o4 v# g, \' d3 L. C( C0 S
  104. *********************************************************************/2 \4 U: h! {) e; d. q: s
  105. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)
    4 W5 F+ b  B4 Z0 o7 N. z
  106. {
    - E. ~) o* v  s2 d! r
  107.         unsigned char *p;% \' L) p' D+ K1 y0 \- ^4 r
  108.         if (FIFO_IsEmpty(pFIFO))
    8 l1 i) d; U7 z; h8 F1 F
  109.         {9 g$ h+ w5 a1 Y7 ]9 x% n
  110.                 return 0;
    / w2 \& K) b+ a/ F( Y# m$ e
  111.         }. T1 _- a* r; D5 K# ?1 n" f- p
  112. 1 {$ N8 l( _! M, U, j# p& _
  113.         p = (unsigned char *)pFIFO->Buff;
    3 ^% |" N# b% }8 g. |5 E4 [
  114.         memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);
    5 q5 C8 f+ N2 H& w' z

  115. / W% w! n8 U# W& Q& [
  116.         pFIFO->Head ++;
    ' C, Q: k9 v! n5 f2 p% b7 u; u
  117.         if (pFIFO->Head >= pFIFO->Depth)" v( V# @4 {0 d( `
  118.         {
    9 d7 G$ F$ @5 j$ L2 a
  119.                 pFIFO->Head = 0;9 {, {0 B+ [- V2 ^) v7 f
  120.         }6 }& Z! H/ L$ S1 s6 y  m
  121.         pFIFO->Counter --;5 B" S1 C" i8 Q  Q6 u- u9 _

  122. " ^2 R+ A2 ^4 K( j! K+ E: e- H
  123.         return 1;
    8 i# b9 N1 f3 L9 |
  124. }& p  w! A, x0 @. ~2 b* R

  125. 4 F/ q- c8 ?5 |7 o
  126. /********************************************************************//**& k. t3 w: X! s
  127. * @brief       从FIFO读取多个元素
    / ]4 `7 h: i* a; W, p
  128. * @param[in]   pFIFO: FIFO指针
    ) \, N/ Q- c5 F
  129. * @param[out]        pValues: 存放要读取的元素指针' b/ o/ M4 ^- ?! N8 U9 D
  130. * @param[in]        bytesToRead: 要读取的元素长度7 |. |) s, `) v4 D  J8 a: s; }
  131. * @return      实际读取的元素个数, c" L* \7 r2 Z; t) t9 u- M
  132. *********************************************************************/
    3 _- U7 M; V4 o- s
  133. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)# u( H6 |3 g- i- z; U/ v: I8 `( l+ \
  134. {% V5 e( M+ y" R6 N( a
  135.         unsigned int cnt = 0;8 z8 h7 Z9 C: ^4 m
  136.         unsigned char *p;
    4 _7 G. R4 \5 G. t
  137. + }4 k; U9 F2 H" b$ H
  138.         p = pValues;
    $ w7 J3 S, L. b5 T6 E# z  e* }
  139.         while(bytesToRead--). F2 R# _+ ^) p  _- U; a
  140.         {
    ; t: N" o- |% e4 x% }- A9 c
  141.                 if (FIFO_GetOne(pFIFO, p))
    ! M/ a* I1 F1 o' p# U' y: R
  142.                 {: J# p2 O& [. y( K0 b& s& L
  143.                         p += pFIFO->ElementBytes;
    % H9 }7 `$ e( L
  144.                         cnt++;
    * l7 x" g/ J# i
  145.                 }
    ! i3 ?. j( n/ \- w. g: ]5 Z. V1 s
  146.                 else; P) M& q9 M! k! X
  147.                 {2 t2 j% q' Q8 y. b
  148.                         break;
    0 N/ }& B" Z" t
  149.                 }
    + P5 t1 W0 B1 V% ]1 j8 }) q
  150.         }
    * {5 ^( X$ M) W% L) N9 N

  151. 4 t& E) ^0 p* u5 q9 v
  152.         return cnt;
    - g6 V# T- d- N  q0 r* v  A* \
  153. }
    5 V- U: ?6 [. K0 Q; h5 i* [
  154. 1 |% `9 K2 m/ u. ~1 Z; P- Z+ ]1 C
  155. /********************************************************************//**7 q& N5 u  s- L" Z- m7 K! B
  156. * @brief       清空FIFO
    3 Y* d9 c4 J9 W( D  U& \
  157. * @param[in]   pFIFO: FIFO指针1 C( J5 U" I" V; s
  158. * @return      None$ e) @" _9 S. d# i: ?7 t4 f5 V7 S
  159. *********************************************************************/
    ! {$ h9 m  a$ S( ]. q! O. A  U
  160. void FIFO_Clear(FIFO_Type *pFIFO)
    + z+ D" n' [$ `6 P4 S
  161. {
    ) ]- |# ^' ]2 i+ p4 V4 i
  162.         pFIFO->Counter = 0;
    # z2 q; Z1 K- C9 y* E9 s! |7 U+ c  z
  163.         pFIFO->Head = 0;4 y) r9 x0 V- p
  164.         pFIFO->Tail = 0;% \* |) v0 v. S: _
  165. }
复制代码

4 ]2 O* A+ o5 z ③ 串口初始化, m# Y- n9 ^% s5 J6 C) y& C+ P
  1. static void MX_USART1_UART_Init(void)$ I- S3 B4 g0 R; v3 ~8 w
  2. {( p0 ]0 d+ p. Z. J. P  V
  3.   huart1.Instance = USART1;% J; x- H7 P2 l' n
  4.   huart1.Init.BaudRate = 9600;
    3 R4 g0 s8 t% o
  5.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    ; R' O" M3 h9 h- c5 m7 v7 j3 @' ^
  6.   huart1.Init.StopBits = UART_STOPBITS_1;* E0 \% Z3 r7 m. J
  7.   huart1.Init.Parity = UART_PARITY_NONE;
    ) ?1 i( ^% M& F8 m6 V- @
  8.   huart1.Init.Mode = UART_MODE_TX_RX;+ |6 T/ ?$ B$ z' x
  9.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    ; Q  ~2 ~  F3 A/ }
  10.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;6 [' d  h, b* h$ R% ~
  11.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    9 w( s% e- S* H5 r
  12.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    5 W5 \' [' u$ B: j
  13.   if(HAL_UART_DeInit(&huart1) != HAL_OK)3 d6 g, d+ r9 C" a8 G+ A
  14.   {( O, n& ?- W& E" P+ S
  15.     Error_Handler();
    2 a- l0 P7 N8 o! Z: ^* [3 c
  16.   }  2 g/ q/ K- P- X- W6 a3 I1 P! Y: ~
  17.         ( X3 G, V8 N; w: L! ~/ Y0 L
  18.         if (HAL_UART_Init(&huart1) != HAL_OK)
    3 F& J7 o8 |4 B% g7 O. Y
  19.   {" h, ]9 A# B0 ?5 t3 x' X6 h
  20.     Error_Handler();6 u8 C  S8 ~6 U( D
  21.   }* y& s7 X, N5 C
  22.         : {( F! A- @* x5 Z9 |: f( d
  23.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
      O7 a4 P  ^; Y& G
  24.   /* USER CODE BEGIN USART1_Init 2 */; C3 q! E  R+ I7 Z
  25.         if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK): z; G: j3 p- m5 K9 c! f
  26.   {0 {" V: s, b( a3 z% Q! ~; m
  27.     Error_Handler();
    , ]: d+ b/ u2 `/ q' Q& V: y( {$ N  Y
  28.   }
    4 |( r' p. M$ k
  29.         
    " o1 l, t8 K0 _/ t" o3 U- X
  30. }
复制代码
2 R( z+ |5 U; G
④ 接收空闲中断
$ o) l4 _/ l4 Z
  1. void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)  X- s& z. m5 b* u- P. u" z# V7 K
  2. {: U, z( T0 r: @+ P. k7 s# t4 _
  3.     HAL_UART_DMAStop(&huart1);
    * V& E, u  b4 q2 |* ?2 |" O. T

  4. , m& h0 ]$ ]: ~5 [
  5.     uint8_t data_length  = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);3 f" Q; D' `5 v8 P& t4 U# w" O, V
  6.         
    # q+ L% B+ W$ c( b; D& \
  7.         FIFO_Add(pfifo, aRxBuffer, data_length);, b; I* Y5 r; M5 t' B
  8.     data_length = 0;; v  I0 e4 L8 S) `
  9.     HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
    ! V+ `& H, P) F* M
  10. }
    $ `' K6 p' C- O( R2 I4 k/ L0 v
  11. 9 }  P+ Z6 |( `6 ]% L
  12. void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
    6 C0 o8 W! P. @$ v& |
  13. {
    : q1 g8 B9 m+ v# w6 M. H
  14.     if(USART1 == huart1.Instance)
    0 @" d( i7 F7 `  y  T
  15.     {6 t2 i! n) s: n  e3 r2 ]
  16.         if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
    5 g6 M7 R) f- }0 O) Q
  17.         {! ]! o4 Y/ w# N$ s0 t) _) N1 y
  18.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);4 E: T3 @* G0 P0 F# k
  19.             USAR_UART_IDLECallback(huart);6 O9 X7 x- n3 H$ n/ v' N3 s$ ~& F
  20.         }0 Z' [0 [' }% |% W7 k( s
  21.     }
    & v8 q) Y$ Y8 k& j  h# g3 U$ u" w
  22. }4 r: S- Y4 v4 z' L0 |

  23. 9 G! O1 f4 |9 ~; w# {  r
  24. /**
    2 Z4 N7 p3 s8 H! X
  25.   * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
    4 O. n3 K5 ~" y. P  [! v0 t8 }
  26.   */
    4 H" E: h: j2 R3 ?2 ]1 ]" v0 ~" Q
  27. void USART1_IRQHandler(void)
    # y; u# f' q8 X( }
  28. {
    % O" z9 P  a0 y' z
  29.   HAL_UART_IRQHandler(&huart1);8 P* v: Q) j8 o& p% a& H
  30.   USER_UART_IRQHandler(&huart1);1 p2 \" |6 N5 h" O
  31. }
复制代码
; Y  D- Z& S2 A
⑤ 主函数调用:% O; [9 e# E& x6 F$ R1 v0 Y
  1. #define TXBUFFERSIZE                    30
    " f' d: O  U9 M
  2. /* Size of Reception buffer */
    " F$ W( ~0 z, C; W
  3. #define RXBUFFERSIZE                    TXBUFFERSIZE
    . {# P: h2 @% {
  4. #define RXFIFOBUFFERSIZE                TXBUFFERSIZE * 5- p1 G2 Z3 Q$ a! |  u

  5. . ]4 |; ^  E; l/ q' \  X7 f" \
  6. : q( y# X' a# g% z; h+ R6 @0 @
  7. uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";
    + n7 j" N& M; x( o2 v" K

  8. $ ]0 i1 Y. M5 E8 F) N6 ~5 }& K
  9. /* Buffer used for reception */
    1 S2 v$ |& S. n5 B- O4 h$ @
  10. uint8_t aRxBuffer[RXBUFFERSIZE];$ q7 J, v( @+ v3 |2 ^9 P

  11. * {1 y/ |4 C( q
  12. uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];+ K8 u, ^1 J& T4 K7 W: F
  13. FIFO_Type        fifo;
    9 n. c! i1 n0 o9 b! ], y
  14. FIFO_Type        *pfifo;
    3 Q; ]$ q5 \8 `6 j# R
  15. , g2 W. e5 |1 C6 U0 q
  16. int main(void)
    4 x( @( d* m; E" p
  17. {3 K4 ]7 x. ]* g& W" J
  18.   /*此处省略硬件初始化*/
    , x. E0 [6 {# D$ E  }% R3 }/ i
  19.   if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
    - o0 C+ e# `$ A$ R1 J  {  i
  20.   {
    % T; I% C  E, ^8 F( Z' v9 b' n2 D
  21.     Error_Handler();
    1 s  L. r" l4 k+ x: |6 |/ ^1 @7 C8 e
  22.   }& \% r0 t9 J: c" s; [) p
  23.         2 `0 z9 L  \7 s3 q2 }- @
  24.   pfifo = &fifo;
    ; C  Z4 p1 b! @( h( u

  25. 8 O9 f1 y" L0 S
  26.   FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
    0 Q! U6 F) o& ?. M  j$ [( h
  27. ) z5 t) }! ]7 @0 h/ C' H2 L
  28.   while (1)/ Q4 e/ h9 d7 [1 Q. f% q. k
  29.   {
    3 Y" x) z0 u- {3 u& F3 Q
  30.         /*一次接收的缓存,重新发送*/; b6 `6 N) V! R' s$ x' c
  31.                 if(!FIFO_IsEmpty(pfifo))- I. q9 n$ J4 d1 ]5 J2 z! G! }
  32.                 {
    ) I6 r. H2 r; s; S
  33.                         uint8_t a[100]; //存放读取fifobuffer的数据
    " I% {- P2 F9 P
  34.                         int i = pfifo->Counter;//先保存接收缓存的数据个数
    + q3 S! h& z: x
  35.                         FIFO_Get(pfifo, &a, pfifo->Counter);
    , q: z; {# J( z1 \# W) l4 ^
  36.                         HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率, P1 A( F& K* Z% f& h! X1 q
  37.                 }  Q& P( [- C1 Y. ?! L
  38.   }& x9 c$ G7 Q  X7 ?; j
  39. }
复制代码
& v: M' M0 D& @# x% M5 U
测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
, C/ j/ P9 H% K! ~, O' X8 N, J" J3 B9 n* @
202109031459585.png

. l  n$ Z" P( _; ?: I8 ?0 Y2 v. `( q6 l4 X& d' \: ]2 ?
问:关于 stm32 HardFault_Handler问题处理?
* O+ Q( E# G4 j: ]+ U# Q: y* O, H# }# H) B
ANS:2 r4 p* G' ?. a' W

  a( V4 ]3 r3 V' q0 n1 x; ~6 R: C        在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,4 \, g$ A- H1 T+ |+ {9 p" s- g

6 o+ ?- D" b* T1 Y% b
20210903150306628.png

/ F, x% k; B. D' j1 X( R2 h
5 _5 z/ f" a$ p9 J  h
20210903150316369.png

3 G8 N9 _4 p  l( ~# c" d
9 J" O) {$ }2 J4 o 最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!
" J: Y; d9 w. p* h: O, O
  1. pfifo = &fifo;
复制代码

1 q7 P4 N+ t; I8 `! y6 c2 x% Y3 T0 U( S3 Q" }) O. Y0 c9 R' \
, u* Y- r# F' m9 X7 z( R1 g( z: r
. d3 p! k4 S  A
收藏 评论0 发布时间:2021-11-25 15:00

举报

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