一、STM32CubeMX开发) [" I1 I2 A! }: N
1.1 新建工程
, H- U/ G2 h& z, B1 Ffile -> new project 9 @& `& r2 d6 c. ^' Q4 G
' g4 l' k5 u* k6 d" h4 m选择芯片-> stm32 core内核 ' r2 h! O5 q$ Z* l5 [# Y$ e
3 m, ~; `$ N( I/ @ stm32 series 系列
$ y2 p2 _! ~4 S! P1 V V @7 T& P, F$ Z1 S+ R& l# q7 y1 t
stm32 line5 F& U0 C4 i ]
e5 E, L0 _0 g6 H stm32 package' R5 n, a( ] x3 F" e3 F
6 M# t* y0 Y# y" i
选择芯片根据自身需求去选择,目前该项目是stm32f0系列
0 g. {/ B: V8 p" t% i& h9 j
: ~, ~# C. G- ~. e' B( K stm32 core内核 M0
* [+ d9 ?: o! C) |. I0 W; ?2 w0 k( {9 W5 v x6 m" N& V. g
stm32 series 系列 F0
7 q' l& ]# C! w% b1 K
& y, X' ~6 Z0 Z: {# o1 c7 ?* t stm32 line F0X1$ X! n) n9 R4 r' I6 N
& b4 e# T) u) @9 e8 S$ ^ stm32 package TSSOP 20
) o; k* s& Z) k+ O5 V. D5 X! y* I8 v0 L* d
1.2 配置 USART1
) z+ N) C- S7 e3 }" ?$ W/ i$ f配置 USART1 的模式为 Asynchronous,即异步串口模式8 L2 ]5 a2 e2 p9 y( u& j' d' c
' R. E" j, `$ d7 Q% }3 i' F$ [! d; `* S# q
/ C a- V; _0 I) H+ O1 }. Y
1.3 配置串口参数
/ a6 B4 I$ [9 `6 z 根据需要设置波特率和数据宽度等参数,在此使用 9600,8,N,1
& u5 h4 P( {( H4 Z* \% F2 U
5 A7 D: n" j. p8 `3 Z2 F9 X$ M( w0 P' L- C0 C; S
0 c9 c! d& a4 r! d4 G$ U ~" T 1.4 设置DMA
- m' m+ k/ w- o( |( E& E2 m: ^( \6 |. |3 Q: `1 a
, @* l' D5 w5 L1 ?& i z4 `
! |; N5 j- u7 \% z2 \ 1.5 添加串口中断
3 i2 o# f# V2 p
) q8 ^9 \4 b$ r! o& b4 _. l4 M
3 G+ N1 P5 |8 @ m" v% n
5 L# ]6 g! T4 j7 v- W: a t 1.6 生成源代码。
& o. u$ K% |# r1 i在界面中输入工程名,保存路径,工程 IDE 类型,点 GENERATE CODE 即可。7 v4 S `: e3 S
" [* @3 ]3 J6 [4 j% B
# p* J7 C7 i$ ?( _& z3 O* r4 S
# \3 j7 ~: \9 `$ R1 j7 W
生成代码完成后可选择打开工程。 8 d! d% `' R4 X7 S5 ^; l
% m) B. X! E. m, T. |3 d% v
, H" ]: z3 H |1 ?; `7 e1 f
" |% V$ T$ r5 p二、代码部分2 \' p) z, J* D2 l F
2.1 接收中断处理2 }' F; T) Q3 Z# B
2.1.1 接收固定长度:(舍弃)
* ?, f( e( A' G, h3 L$ q% M只有接收缓存到固定长度才会触发中断 x2 \; e4 v' m6 E. w1 s: m# Z8 J0 w
串口接收回调函数
4 n: t9 |* r" Q/ A
( @4 u/ @' H2 c/ T4 W3 ^- uint8_t aRxBuffer[RXBUFFERSIZE];1 I6 M4 L. |5 A; A3 }2 X# J
- /* Size of Reception buffer */6 D: R$ X5 b% h2 T; I0 t d- u
- #define RXBUFFERSIZE 10
) N1 S+ q; F# A% O: Z/ p- f
7 N' q( P3 r/ o5 A. p" k% R
! `% s! c) p3 {3 j- X- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)+ s# n; X1 v( r
- {) H; f! ]+ l; g0 o" h4 x, p
- /* Set transmission flag: trasfer complete*/! A- `! i+ x7 I, a9 m- @: V3 C' v# j& I
- UartrxReady = SET;8 C3 F' b5 c" D4 E, b4 T
- HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
+ [" Y% }1 ~ R. E+ ?1 d - HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);9 p5 ^- \, \' D+ v+ _
- HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
1 k/ O; `8 B3 ~ V# E3 N - # O- u6 Z* s n5 k% Y( ~$ W$ x
- }
4 H- ~4 P- U* R2 T$ W+ h' M - 9 J! y f3 Y& O# b+ l W
- void USART1_IRQHandler(void)1 k/ x( X5 |1 z/ Z9 c3 Y s9 n/ t/ ?
- {; d! U. _7 {7 E" M
- HAL_UART_IRQHandler(&huart1);
9 U; I% q, u) I - }$ i& {$ p* y( c$ S6 Y
6 O5 \- q: X) W( O
1 x0 W9 g& A; A- r- static void MX_USART1_UART_Init(void)
& _% ]+ c" Y6 b- ^/ U - {
& L; U" A x4 z! \1 @' W/ k9 B
7 I7 z; w8 z' z* |- huart1.Instance = USART1;& U1 i" y$ `; c3 p; |
- huart1.Init.BaudRate = 9600;. N) m6 b& Q' Y+ e
- huart1.Init.WordLength = UART_WORDLENGTH_8B;6 P$ V& K+ U2 G& ^' b& @
- huart1.Init.StopBits = UART_STOPBITS_1;: Z5 i% W* @4 b5 y* o
- huart1.Init.Parity = UART_PARITY_NONE;) M0 o9 `+ A9 E
- huart1.Init.Mode = UART_MODE_TX_RX;3 L- Z8 C5 x7 l& }1 D2 ^/ ?9 W
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;/ B8 B% n0 k3 M) \# P( L
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
, e8 @$ R1 h$ R# w - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
' Z" \; t6 s3 C& ]! o+ N+ M" q7 ~/ r - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;+ Q, H/ j, Y* L6 T" N" \4 _- l( L3 g9 G
- if(HAL_UART_DeInit(&huart1) != HAL_OK)
4 ?! b# O7 x7 r - {
" j3 `& `, z8 L c. d - Error_Handler();
& P6 H9 v8 ?* }8 k: b/ z - }
( u% A1 T; x3 T. t - ( U8 e- S1 y, T0 C( c& l+ P
- if (HAL_UART_Init(&huart1) != HAL_OK)
$ q! }2 z, m2 A6 ]; {! y _! y - {
9 m4 R* v7 H8 p' l: Z0 y& E - Error_Handler(); |" x" L3 t- V
- }& B/ R% F. |" C. Z
-
" R5 e# P9 [! X$ q3 Y - UartrxReady=RESET;
7 Q; }( N& g8 x' n+ Q$ I - /* USER CODE BEGIN USART1_Init 2 */
3 b' _( o0 ]$ L5 h - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
. D1 H2 g7 Y" s/ l( d - {8 W7 _& z0 C" `
- Error_Handler();
: W8 H9 U L% _8 A. S9 c - }4 _; ]1 a* y4 ~( c( f% s
- ( r/ p( A' [: d+ G
- /* USER CODE END USART1_Init 2 */* A) w" ? E) {: v
- }
复制代码 7 Z1 m2 v7 a8 p1 T
从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。
" j+ A& `. U1 B' q* B$ O: q: [# e/ O2 o+ }/ }
% O9 V* b6 W+ C2 H3 Q0 v4 ]
7 m: C: a+ K( S+ [8 l4 c2.1.2 编写空闲中断函数接收不定长- Z2 v* L# `! g1 l. \4 Z
USART1初始化:. R( r n5 f9 P7 Y" b/ E8 X
- static void MX_USART1_UART_Init(void)) B' p$ { Z# K
- {+ g' U# l! b9 K0 W2 J, H
- huart1.Instance = USART1;3 R6 W! K' k9 j" N8 X& f% w0 Q
- huart1.Init.BaudRate = 9600;* ~" T9 P. J* q6 m
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
' {" f! q" }4 u0 X1 C4 v) ?- I - huart1.Init.StopBits = UART_STOPBITS_1;
% A2 u3 R, G8 ?# G6 A* U. N - huart1.Init.Parity = UART_PARITY_NONE;
& K: @3 ]$ S+ f - huart1.Init.Mode = UART_MODE_TX_RX;
# m' v9 ~9 |6 ^6 N% T3 y. V - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- S$ s1 T# M, s8 {, k/ M - huart1.Init.OverSampling = UART_OVERSAMPLING_16;
; ~, J4 e7 ?, I - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
) ~0 I: @! B' {$ p* j) G5 w5 O - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;2 v b# s1 }2 ^1 d2 ?
- if(HAL_UART_DeInit(&huart1) != HAL_OK)" n+ @9 _ T8 h+ A/ l; d j
- {. k" N& q# u/ E7 c1 j9 k# A
- Error_Handler();# ?0 Z8 J( J" I3 _1 P
- } % `& r8 x/ o3 O/ R3 `" O
- 0 M1 Q! h ? u
- if (HAL_UART_Init(&huart1) != HAL_OK)
) D7 {- w& T; G0 X4 X1 P- @. G+ @ - {
h- L$ D( X$ A9 T6 S' Q l - Error_Handler();) o% c$ `, ~: c* m* L+ }
- }
" |3 o; o% o0 s3 ~1 V2 s - . V$ W6 y6 M9 p' P5 r6 ~
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); % W. M1 m6 V0 V/ n" v7 K0 m
- /* USER CODE BEGIN USART1_Init 2 */
; I/ H. @6 |) V! a E1 @4 K - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)8 e) x0 q5 D# V# j( S, g) x
- {$ m6 c2 g# p5 y6 b
- Error_Handler();# X" y5 v4 J6 x- `/ Z8 f
- }
/ P+ n3 m" ]+ |$ E9 l5 {! [ - 9 p) X3 W8 d8 c$ P2 w4 o; t
- }
复制代码
* C6 ?: n/ i7 x% M空闲中断函数:
1 `) x$ |+ K: B9 Q1 ]2 t3 Q- #define TXBUFFERSIZE 30
2 T6 `$ j) m) {+ o; w - /* Size of Reception buffer */
" x3 Z3 o+ N5 t" j) a9 x - #define RXBUFFERSIZE 30; ?9 d6 v2 `, `6 A& L9 _% w
- 1 y0 N, z# ?, |$ L7 W8 d6 D& o* K# B" M
- void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
7 n1 B6 `* H! R/ S! W9 I8 k& R - {9 L5 g9 F9 D' V) P _# X
- HAL_UART_DMAStop(&huart1);
6 D# ]3 e6 _. e7 m+ ]2 Q* Y" b - & Y1 a9 a" i/ |8 H9 [3 Q& `
- uint8_t data_length = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);4 {, }; r( V9 h9 ?
r n- V( q) A" g' h' g! d
( `- L, X* a8 t8 n- HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);
( n1 Q0 G2 s; X' h
. J! M7 _* s" L- memset(aRxBuffer,0x00,data_length);
: i7 `$ M5 r7 O* q; ]# M - data_length = 0;& }0 r' P: _2 D$ u- n2 }" G
- HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
$ h$ \# h% ]- H" f" s/ E0 Y - }7 a. S5 H; o" P( k+ g
- ?4 ~& O: ~2 @6 @
- void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
( p6 ]! e1 f; S$ Y3 |8 U$ y/ G8 S. ? - {
) y/ x5 B6 B! o W* D! j; l - if(USART1 == huart1.Instance)5 Y6 Q+ N+ [: m3 p1 L$ h* S: z7 Q% Y' h
- {3 i8 S3 z0 t) H# h/ R4 Q
- if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))8 `7 G) w9 M- P6 i) r
- {" l+ v% o, Z4 ^3 r/ h2 r& w+ C
- __HAL_UART_CLEAR_IDLEFLAG(&huart1);6 \0 H! Q) \/ x X
- USAR_UART_IDLECallback(huart);
. o* Z" S3 B) P6 O7 }$ g - }
) [& z/ o4 S4 j/ x - }
/ o- C( e: W# H/ e4 m - }
' a' m5 v! w- |' y6 o# S
# c9 ~3 j( X9 }9 ]- /**$ U& x3 d& y: o; _+ e
- * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.+ R8 j9 k, P9 w( A; }( M9 v" }$ w! T
- */; w$ F7 s) L* I" k" E" j2 G
- void USART1_IRQHandler(void) [9 I. c1 c( \3 t8 ^
- {& N2 A& F. [2 J/ T" g3 A
- HAL_UART_IRQHandler(&huart1);* \3 l. m- `! P: [% I& |! I
- USER_UART_IRQHandler(&huart1);
c* W [5 K" w+ K - }
复制代码 , e$ O0 k9 |) L
可实现不定长的接收! " v H( e" l, ?' G* }
- p! n/ P: W7 b( s- r: Q# M+ K" W2 i( _
. q' a! u _5 G5 f. L# h& y* I- z* d. I P1 u
注意:
: C2 C/ z" |# t3 n: X6 @. K在中断中,尽量处理简单,不要做过多的处理,如发射,可以在函数外执行。
, G! L S3 h3 C
4 g- F1 b2 F- r+ a8 b# X4 J3 r 三、使用ringbuffer实现任意数据类型的FIFO处理接收数据
2 t2 g) p3 m2 W使用原因:. ^/ N, }3 E5 o2 _5 t
4 H0 [) E7 X4 B f! b" t1 q 虽然将数据保存在DMA接收缓存中,但在处理接收数据时,可能存在接收新的数据在调用数据完覆盖了接收缓存,导致调用数据时候会出现与原计划的处理不同的问题。/ |0 x. r% B! ^# d) b! T2 a
% [1 [ u: T4 ~! F+ q9 ? 因此,使用ringbuffer将DMA接收缓存,以防数据的被覆盖! N4 A* j1 C/ I- Y' L
6 i: M/ U3 ^$ ?① fifo头文件:' ]3 v; C6 D$ A* ]9 h
- #ifndef __FIFO_H_5 A5 {# f5 e4 a
- #define __FIFO_H_
' c5 t1 m$ b/ u2 @
B, J8 }1 X: K" ]6 M- #pragma pack(4)
2 \* x2 A4 C1 J7 {. z7 S" p' z$ p - typedef struct FIFO_Type_STRU; d. H7 p% C2 M8 i9 T' p6 x
- {
2 d+ i+ i* s8 m' i0 X) X/ f: z - unsigned int Depth; // Fifo深度
8 Q- S, _- L* O1 M" E - volatile unsigned int Head; // Head为起始元素
! y0 y& N2 ?+ O1 B - volatile unsigned int Tail; // Tail-1为最后一个元素: n9 f( G3 Q$ ]% q; ]! n" a u, v" F
- volatile unsigned int Counter; // 元素个数
2 l( ]2 ]3 l. s- S. u+ q. x7 s5 X& U: H - unsigned int ElementBytes; // 每个元素的字节数element' `7 n g! K, I* W U" F: B
- void *Buff; // 缓存区3 d6 \. x. V" _! b! y3 G
- }FIFO_Type;
/ x) L& E! v U/ j7 Z - #pragma pack()
c# U2 ?0 a! e5 c, x6 w# W3 a
, Q8 a* q l D7 [! c0 ]' s- /********************************************************************//**
/ R& u x, T, K/ { - * @brief FIFO初始化' T2 h+ B( U- U+ w7 Y- K+ r
- * @param[in] pFIFO: FIFO指针( z" L. E& Z7 x" y2 h/ I* ?- h" |
- * @param[in] pBuff: FIFO中缓存
3 h n# f4 F7 q/ A- p - * @param[in] elementBytes:FIFO每个元素的字节数
: i7 X, p( j/ w4 F8 D - * @param[in] depth: FIFO深度& i! U1 x1 f0 J
- * @return None# h. Q' _6 x) s9 P& _! R
- *********************************************************************/
1 m7 A9 u1 f5 ?1 S2 E& q - void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);
; h% b0 N! e. { - : |3 d c$ J% Y, q- `$ I
- /********************************************************************//**
# }) a* e8 }" H& m9 ^9 q - * @brief 向FIFO添加一个元素/ F+ T, u' w+ Y4 G! y
- * @param[in] pFIFO: FIFO指针
/ }8 S6 i$ }6 V. L$ U/ q0 t1 S3 J - * @param[in] pValue: 要添加的元素
N" J! }8 g7 W% O( P2 [9 _3 d% j- q - * @return 1-TRUE or 0-FALSE
- C; L' E: p( F& Z" v/ m - *********************************************************************/8 P: [/ S8 ~" z) D K' Z# }6 V- U
- unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
& O2 w: h) r( _/ @9 G0 D* n& X - % {+ ]$ d: P* w% G" \! N+ S+ `* a
- /********************************************************************//**
0 W! P* j0 ^# {9 o8 i; V5 v - * @brief 向FIFO添加多个元素) j- r( Q! ^$ Q9 I) _- ^
- * @param[in] pFIFO: FIFO指针
% e" f5 T+ v5 ?4 `' b! j - * @param[in] pValues: 要添加的元素指针
+ y) J4 s5 w# _5 T+ D) v- C2 t - * @param[in] bytesToAdd: 要添加元素的长度
* s( W" A' S* e9 W( H7 G6 c5 y) ^ L - * @return 实际添加的元素个数4 A) f1 M2 \0 j) m
- *********************************************************************/
4 F1 H+ r% d7 R! p5 p - unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);3 w4 \- N+ {) @1 I9 V, u
0 a. }2 b5 u3 |- /********************************************************************//**+ \ [$ Y) H! j& z+ Z% S
- * @brief 从FIFO读取一个元素$ Y! i4 f+ [) s; w! ?4 D! L
- * @param[in] pFIFO: FIFO指针2 b. Z3 R% W: ?- `/ k4 ?8 ?
- * @param[in] pValue: 存放要读取的元素指针
' B6 l4 C8 ~( T$ ?& Q! `$ v1 N j - * @return 1-TRUE or 0-FALSE0 Y/ m" t1 W0 [9 j" V
- *********************************************************************/1 z6 s9 f) F5 J4 S, T% K
- unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);9 Q, i% D. n: ], I
. h& `% Q0 l' Z {- /********************************************************************//*** k4 f( g4 S9 S0 P2 M5 x& i3 h
- * @brief 从FIFO读取多个元素% ^" C- K8 R8 X* _
- * @param[in] pFIFO: FIFO指针
3 R% b# Q# d e! L. d - * @param[out] pValues: 存放要读取的元素指针. i* [3 |/ n2 ^' Q
- * @param[in] bytesToRead: 要读取的元素长度* m& m: h) G) n
- * @return 实际读取的元素个数& ]- E1 M9 x/ D1 S
- *********************************************************************/
4 O( T. H) ^ I% g, D - unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
; b5 t, Q) j0 U - - N) t' I1 E' L5 B/ E9 {& J( V* y# W3 ]
- - G6 H1 T3 } D/ z1 M% A, y) y
- /********************************************************************//**
2 U3 o2 z/ C4 [# a5 n. h( ]; Y8 N - * @brief 清空FIFO3 O/ r/ i3 E. m# S
- * @param[in] pFIFO: FIFO指针
0 e0 e; p! m6 K4 @% Z% ^ - * @return None1 i' o( c/ o& I4 v$ v2 Z
- *********************************************************************/
- x+ H; w" q7 K5 w4 H( |0 E" u - void FIFO_Clear(FIFO_Type *pFIFO);6 M* R9 B0 E3 r
- ( {, ?' t6 e Y1 r6 T. s$ p
- . }* ?$ |. r- W2 G
- unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);. c" l$ K, y- U- Z+ ^: W& x0 f3 c
- 1 W( h1 X# o: X5 N w) @- s
- #endif
复制代码
+ f. q. e0 h7 I5 X# F' i# T② fifo.c程序主体+ @9 i0 q! ` K8 O0 ^/ d
8 z' C6 |! X5 D: a. d2 q- #include <string.h>
2 _& k/ I, J6 k* N& {5 D5 o0 a - #include "fifo.h"( y" M8 ]+ o- J0 z4 T2 j" W! `
- 1 V3 X; U K* ?, |) k/ P
- 7 b" T6 G9 r! j J4 w
- /********************************************************************//**5 N4 Q5 ]$ ]. L7 p9 O. J, [; j4 o5 C
- * @brief FIFO初始化
: \; p0 W: c- Y" {, S! X - * @param[in] pFIFO: FIFO指针! V9 y8 t0 l) ~6 f) D6 b
- * @param[in] pBuff: FIFO中缓存
/ K* l0 _! z) J' d3 Z. U* x2 n( k4 u - * @param[in] elementBytes:FIFO每个元素的字节数
# K4 X1 k( f0 h - * @param[in] depth: FIFO深度
) T5 |/ t7 ^ _% N - * @return None% E/ h8 ?6 F' o" L$ B
- *********************************************************************/3 q) E: {) ~6 n% F. j! q
- void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
, A' o# h2 Z" E0 O - {
- `% ?4 N5 G2 L( ]8 A4 }2 X0 U - pFIFO->Buff = pBuff;
5 n+ {- y' k7 b9 s - pFIFO->ElementBytes = elementBytes;
% i6 S7 y7 K9 }# m' _# n8 [ - pFIFO->Depth = depth;
: k- o% E" l4 u0 T8 w) s2 U - pFIFO->Head = 0;3 x1 j) F( J+ s$ f# v }
- pFIFO->Tail = 0;0 `0 G0 i% Z8 f
- pFIFO->Counter = 0;
- b2 T! |2 y$ f- v - }
. ~) L2 h- e+ _8 @0 D( T" ~" `8 Y - ; ~7 ]! D4 f9 `) X. e/ h. `& m# c
- /********************************************************************//**
, a$ @% X( w0 _1 i- k3 G Q - * @brief 判断FIFO是否为空
: R) W, ^# X! p2 t$ e6 G! F - * @param[in] pFIFO: FIFO指针
- L5 r/ R+ M& ?, t - * @return 1-TRUE or 0-FALSE- b- E+ W; N p- Q: m; S( r
- *********************************************************************/3 w% r1 V( n' G# x' w2 ~: x
- unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO): C% Y3 {# g0 t* n i
- {
) ]! |+ Y C! p! O1 K& G3 U8 p - return (pFIFO->Counter == 0);
; B6 g3 K1 S% E, B$ ^- r - }
4 S. N# P0 g7 E( j
9 C+ P2 `1 [( @3 u- /********************************************************************//**
6 f' ^! v) |8 K5 { - * @brief 判断FIFO是否已满
1 O J& O1 ?' ?" z - * @param[in] pFIFO: FIFO指针: {( `+ |0 O! M: D2 B& s& Z- M! \
- * @return TRUE or FALSE7 O g9 u1 ^! v, A9 ^+ z
- *********************************************************************/9 N+ J& K9 Z9 l$ T2 c ~6 u$ }
- unsigned char FIFO_IsFull(FIFO_Type *pFIFO)
: ~3 b4 H/ B" E$ ~) G7 u - {
$ }/ S( b. A% G2 r& L3 u0 D& v* z - return (pFIFO->Counter == pFIFO->Depth);
/ C1 ]! T0 q! ^( I - }
9 X. g$ N2 Y# i5 ~' X: C6 S
9 w& b1 ^! n5 v7 t0 X! f" |# F- /********************************************************************//**
* x7 P# g) _" w C; S9 Q3 `, J/ ^8 W - * @brief 向FIFO添加一个元素
' I' H) m4 n& C* `0 G - * @param[in] pFIFO: FIFO指针
( b3 ?7 p8 \. R - * @param[in] pValue: 要添加的元素
1 k7 j7 X, p7 T+ T8 b) K2 t9 J0 ^* ` - * @return 1-TRUE or 0-FALSE
' x7 s- @) k+ t4 C9 O; R - *********************************************************************/
/ _) x2 g w: u* P6 B - unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
# I: W3 x8 b D" k# m5 f - {
2 ?! l7 k) V; P5 \' Y% J6 C9 p - unsigned char *p;
L6 n, T7 V& D! g; l- N& I( y( k
5 [$ b/ O; X$ B$ q% y' |) C- if (FIFO_IsFull(pFIFO))
; _; K$ X8 D# j$ m - {
# L4 P3 [ B9 Y( I - return 0;
8 K; W( }$ l* Y2 k - }
3 R4 y' X) |5 s; n - 8 X: v: @1 N, T4 Z8 T! W
- p = (unsigned char *)pFIFO->Buff;
" H" X8 w# l% p5 X9 w3 Q, x - memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);
- x2 \# C/ Q$ V7 M: G( } - / @5 t% g3 h( U9 }* D
- pFIFO->Tail ++;" ]0 e/ p& d, s& h
- if (pFIFO->Tail >= pFIFO->Depth)
: d8 F, J2 D* I8 U - {
& @; L& @0 H; C. G; Z& Y - pFIFO->Tail = 0; H0 ~3 m0 ]; }$ i
- }
* E% V0 Z' ^. W' w2 b" l4 l2 J - pFIFO->Counter ++;+ [; ?: n/ f# w
- return 1;
+ F) e$ Y$ E% L0 A$ P - }
" ?% U6 w$ m. M( @" B0 H - * e) s: c4 w0 H% v' P! `2 e
- /********************************************************************//**
$ n0 l/ n0 l0 l7 x1 B - * @brief 向FIFO添加多个元素: x" N! t1 p" a/ }2 p
- * @param[in] pFIFO: FIFO指针. Y7 P% p% M% O( X3 b
- * @param[in] pValues: 要添加的元素指针" q+ s: Z7 B. |5 i! |2 F V7 P0 Y9 }
- * @param[in] bytesToAdd: 要添加元素的长度
* S' W5 c; o' s! W - * @return 实际添加的元素个数
/ y% k6 e- u3 i- N4 k% g9 B0 @ - *********************************************************************/
, E+ | r) i3 p6 W5 X0 _ - unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)
! ~" G- u' t: x1 u - {- r7 w; Q5 U w% d' T4 y
- unsigned char *p;0 ^' U; V# Q1 Q Z; |
- unsigned int cnt = 0;
% i) V) [# G$ M6 z) e6 y3 |- n
( q3 P7 G9 R# n& r- p = (unsigned char *)pValues;
2 x( @- c3 b! B* b- p1 r: p9 E - while(bytesToAdd --)! w r; j2 S. m6 g' X
- {: M. L U8 M7 W9 d! C% I$ M4 N5 Z
- if (FIFO_AddOne(pFIFO, p))0 I5 d0 X8 _/ S" Q8 P. J @, z
- {
2 n7 @9 R2 Y* \5 a - p += pFIFO->ElementBytes;; `5 ^" F- V7 d) g% _+ E- ]% K# a
- cnt++;. H$ K) L( ?! u# s4 E; X; E7 E
- }
+ i5 c" I: W- _ - else4 B4 }3 q8 d1 C' g: C3 _; G
- {
4 i/ K5 C" ^" k+ {( u! v& b - break;
! ]* C( l" _! u7 t- }# _ - }- |! z# c7 L5 @, k
- }
% ~! G" a S( e2 S5 R0 b9 I$ h
0 g% O! a4 U" e8 Y- return cnt;
d" D) \* N- F3 C0 ^4 G4 N: B - }, |4 f+ z1 D! {- n' O( ^) C
6 L( X+ g0 _- G- /********************************************************************//**
. E# m% d1 I+ z, c - * @brief 从FIFO读取一个元素8 i1 t% X0 b# g5 \4 Y# K$ W
- * @param[in] pFIFO: FIFO指针
9 s! O1 Y: |3 f" m - * @param[in] pValue: 存放要读取的元素指针
$ E g0 S6 v. X' V - * @return 1-TRUE or 0-FALSE+ @- [# m9 _0 T& ]6 H# }+ u
- *********************************************************************/, a" U9 ~& U/ a! ~" G
- unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)& M z8 l: X' k) G% X
- {
7 h' N# t1 `4 L x- u( y - unsigned char *p;' {! J) i# ~ O5 V
- if (FIFO_IsEmpty(pFIFO))
7 W9 x/ @/ _; j9 { - {
7 s% ?9 S3 z% K% o; F - return 0;
" S" {2 u3 ^: G2 |6 l( l - }! q6 n" q; y( u
3 D: H& U7 O9 u+ T6 Z- p = (unsigned char *)pFIFO->Buff;2 {4 s# I; R4 u( R: T* q- D
- memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);# Q- W9 S% Z2 v+ x8 t% X4 e
- 1 H. x; I, P2 T8 y9 C- e% S
- pFIFO->Head ++;
7 b6 O% c6 s% J5 l: d - if (pFIFO->Head >= pFIFO->Depth)
) P. w) L/ s& ~' ~4 Y; ^; j1 \ - {/ `/ X9 s' z. F# V+ B+ m% o0 |
- pFIFO->Head = 0;( B( c& G& }, [ x- A
- }0 h" z$ Q9 P$ a& x
- pFIFO->Counter --;
( g& j6 c) v. G. S- I3 t( c - 3 P6 }) Y3 ~5 M4 ^
- return 1;
: t0 C4 l) h! ?9 ?: x - }
) b' w: G; E, y$ y6 T# u+ n: N
' Z2 p+ i: T# o- /********************************************************************//**
- x0 `, Y! h2 W% @ - * @brief 从FIFO读取多个元素
) d( V9 A7 L/ l+ Q9 z - * @param[in] pFIFO: FIFO指针
& G0 W5 Y! k$ @" Q - * @param[out] pValues: 存放要读取的元素指针! r' l! v* Q+ z' W* h s+ w
- * @param[in] bytesToRead: 要读取的元素长度
* v. B, H$ W& d0 c; |$ X - * @return 实际读取的元素个数
% t- u6 D5 G U9 k' J - *********************************************************************/- E" t- O. j8 ]# H& q
- unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)! h! i6 d# r1 @6 F- t% e0 N1 C
- {
0 o' K5 M& G, ^; K# u/ x& S* e - unsigned int cnt = 0;8 V% P/ B* I% G) l5 }, ~
- unsigned char *p;
! n3 v! i: A4 I4 j6 q - + w8 |" W" h P# o0 [1 c
- p = pValues;
6 a1 S @! S0 K$ D! |2 o - while(bytesToRead--)
" J0 p3 {# o- b; m# y - {- ]0 H8 }( `; n
- if (FIFO_GetOne(pFIFO, p)) d$ `2 b1 f% u8 D+ I
- {$ b) k- L$ T5 C4 g
- p += pFIFO->ElementBytes;8 U3 W; V8 Q2 h6 `+ B
- cnt++;
3 Q$ c; ^5 T3 X, Z7 R |, t5 F - }
' n& c/ O, D2 c) D, G% d0 W+ [. w% P - else# f$ z" g2 E# ]7 q
- {
/ r& E8 t, ]( S- ~8 N( D0 P - break;
' ] P& q- F8 o. Q; t' `$ Q* K: r1 D - }
% q* B: S5 C3 @, C5 j - }
% F _8 W" t3 `8 A& ^, p y! b - $ K L" i* A9 d& u9 n; C
- return cnt;
* D# g+ R. ?5 Z* F% N7 J7 K) c - }) ?4 Y0 R) o+ J% @9 b+ E* m" V* H2 C* g
- , M2 h1 R2 i0 b, Y
- /********************************************************************//**$ Q) W' q1 T$ c t$ v v. s1 C
- * @brief 清空FIFO; D) X% e' w" y" |
- * @param[in] pFIFO: FIFO指针7 O- a8 i* B) G0 _$ w g. ^9 h' V
- * @return None
% ~' ?# w3 n& t1 V; e+ E5 F - *********************************************************************/# i0 c3 ] [; c a$ ~; O& K
- void FIFO_Clear(FIFO_Type *pFIFO)
- A+ s7 }, w4 O3 Y* M2 X$ H - {& ^; T% P, y( I7 z1 {
- pFIFO->Counter = 0;. p+ F7 [6 g/ J& Z' L
- pFIFO->Head = 0;
4 |* K9 O6 o6 x2 b' p - pFIFO->Tail = 0;, O/ J2 n# k# v* T
- }
复制代码
/ b& t, P( f# T W, @; J# U ③ 串口初始化
) \" [* o) N; A! b- static void MX_USART1_UART_Init(void)
* w \, ~+ O; D% g9 l6 Z/ T+ W - {6 T7 B2 e$ k! R4 t
- huart1.Instance = USART1;
! k; x& v+ {0 p - huart1.Init.BaudRate = 9600;
' d C; V0 G# W2 Q* W ] - huart1.Init.WordLength = UART_WORDLENGTH_8B;
7 ^$ s' s* {+ m# U j - huart1.Init.StopBits = UART_STOPBITS_1;7 J! x5 I( N: [9 ^0 Q3 h
- huart1.Init.Parity = UART_PARITY_NONE;
' ^1 H6 y5 I3 S& I, b- w1 L* E& M - huart1.Init.Mode = UART_MODE_TX_RX;
9 P" o' Z6 Y; |9 i; P9 Q. `" `0 Z - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
) E) P; M7 \8 o - huart1.Init.OverSampling = UART_OVERSAMPLING_16;8 \$ \) d0 j& j* g: ~5 p2 X
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
, d, D0 d% a( v Y0 i. \ - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+ ^8 j% } W) _7 I8 F' r2 b8 i - if(HAL_UART_DeInit(&huart1) != HAL_OK)
% A6 \# L6 S+ a2 w - {' S. v( C2 V, F7 T; d% c; K
- Error_Handler();
5 J, D0 P, U8 N - }
% @, J$ q6 h+ D' I9 y) S* U5 ^ -
' D7 L N, V1 @7 p; s+ ? - if (HAL_UART_Init(&huart1) != HAL_OK)1 F8 X2 f( g4 H& q( N! ~# D$ ~+ H
- {0 x1 \# t2 @5 R2 @. _( O9 G8 d
- Error_Handler();3 c4 p/ }: O1 P+ r1 x& w
- }1 n8 w I( W) a0 v
- 0 R* ^/ D, P. Q
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
) Y9 E! g$ `" w: {: j7 u - /* USER CODE BEGIN USART1_Init 2 */
3 Z; |" Z4 D0 L4 h! H+ ` - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)5 G# I3 h! [( {( M* B) K
- {. |6 l) d- t( s$ A1 r
- Error_Handler();
( d0 K! t3 e0 r - }
" k; J0 {/ g! d$ Y# y; P$ \ - - q" K8 e7 c; [. X% k( m" f
- }
复制代码 : O6 g0 F; Q# N: E0 M
④ 接收空闲中断( H; W: D+ @) {" N
- void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)+ v5 ^: Q, f7 O6 D0 C R1 ^
- {8 ~3 @1 a! p7 L$ g; U$ J
- HAL_UART_DMAStop(&huart1);
' U) E* u7 r5 \! o& m0 @
1 G* J1 \9 E( Q( b- uint8_t data_length = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
r' i. a- ]5 v( Y -
5 R9 d3 y+ M: \- w - FIFO_Add(pfifo, aRxBuffer, data_length);, T1 E' M$ E3 p) q7 C: x
- data_length = 0;$ A. N( `0 H _4 g; i3 N$ o- X
- HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
3 b/ _3 e8 Y6 d0 y# q - }; L0 y' P/ E/ C
/ n1 {9 R6 T/ B7 \9 G- void USER_UART_IRQHandler(UART_HandleTypeDef *huart)- P4 W% r- k* t, Q2 k0 [
- {
( F/ f" X# }6 k, D2 E4 t - if(USART1 == huart1.Instance)% y/ S5 _3 D8 A$ O$ N) e0 N
- {
9 D: C: a+ a4 f2 c' c - if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))- H! |, k4 i5 Y7 \8 s" n4 _
- {
" U! z. J" ]' {( F/ K - __HAL_UART_CLEAR_IDLEFLAG(&huart1);$ x* D, S8 _! p' u1 S0 L+ Y: R
- USAR_UART_IDLECallback(huart);
* X7 i3 v7 U9 g X) n3 T& j$ v - }
$ H1 L" B" P+ d0 a5 Q2 i7 ~9 k - }5 |0 K9 ~( e5 _7 N; r
- }( }& D9 |1 D- U; O4 x
& p4 G% S3 t4 p- /**& Q8 {3 O3 U& ^9 w) W+ d
- * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.! f# w) d# m/ |# J6 s
- */
/ t% Y) W, Y5 n* W - void USART1_IRQHandler(void)
7 Y8 T+ o: ?3 @) c+ [2 f - {
$ b7 p& B: \2 {/ K9 D - HAL_UART_IRQHandler(&huart1);; n( x1 T) b8 i0 K( a# B C
- USER_UART_IRQHandler(&huart1);
9 |' _) _' J5 k" N/ h: \. [3 B - }
复制代码
) N. Q5 h7 i; q( F⑤ 主函数调用:0 a$ l& `' e& f t
- #define TXBUFFERSIZE 303 L4 f" ^( c' j$ Q5 `0 F+ C
- /* Size of Reception buffer */
1 _* n1 U) L, L - #define RXBUFFERSIZE TXBUFFERSIZE+ n) [( b; ]1 e1 S6 e
- #define RXFIFOBUFFERSIZE TXBUFFERSIZE * 5
) f3 d' @* [. `# ~
5 }& c7 M# s N- . i& H$ }* b- m: x/ F
- uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";4 d3 R: [5 Y/ N/ l2 a
& o/ R2 m) ~9 f- M1 h- /* Buffer used for reception */7 t ? d6 N, y) U' o# g
- uint8_t aRxBuffer[RXBUFFERSIZE];# f9 D6 ?9 s2 |/ n3 _- ^9 {2 C
7 ^, q+ v* h# S4 o: _# y- uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];# c% e" E1 E4 x$ x0 l; S
- FIFO_Type fifo;2 {0 A9 ^+ r6 {/ M9 z d& v
- FIFO_Type *pfifo;, a8 P* q8 }/ l0 E6 Y
4 H* E; o5 k W' r" y* {- int main(void)
, w. D8 t& k: Q/ ? }! | - {
) ~0 A- M2 {* M# M - /*此处省略硬件初始化*/0 d7 v! v" x4 a6 h4 Q
- if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
$ e7 q" v8 F2 P5 k o5 b - {
: a8 G6 t2 Y& ?1 d1 m/ T4 ^ - Error_Handler();
5 V- T" N% }" ~" _5 Y1 l - }4 w4 g* Y5 a# j( F
-
, U4 Q7 p' g; M0 I2 U' | O! H - pfifo = &fifo;
$ i5 q" g- z8 L
2 N: D5 M0 g m* a: f- FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
, o( \, {, ]8 g* M - , A2 R8 {: x% J$ ]( J4 r ~
- while (1)
7 F! e0 y) L- j. ~ - {$ D0 q! F& U8 h- @$ k9 }
- /*一次接收的缓存,重新发送*/
8 i8 X2 I a8 ?- J0 s1 X7 `9 l - if(!FIFO_IsEmpty(pfifo))- `# G+ I, `6 E" i% T E1 L
- {9 }" f% s6 { f2 U6 G
- uint8_t a[100]; //存放读取fifobuffer的数据
. V) n( Z+ z( j7 M8 o4 |2 Q! x/ H - int i = pfifo->Counter;//先保存接收缓存的数据个数
6 W/ G$ r3 X- c8 i3 V! f - FIFO_Get(pfifo, &a, pfifo->Counter);
( p7 q' F, r9 I - HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率
7 Y& |5 L, z7 \; O% H - }! a' G2 j( F" o& x
- }
! e! c2 J3 F- ]4 p# R - }
复制代码 4 ]6 V' a& W. q- t& @# M( R; [9 _
测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖! 7 v6 ~7 J4 u* W- h
% s1 M* S' V$ G+ g) K$ N
* f% L g/ A* U* C; S* S* r! C9 O% T0 V
, h( ~! B& O1 L: P" F; y$ x问:关于 stm32 HardFault_Handler问题处理?
% U( G* u) t& u9 ~
/ v8 Z4 A. L! jANS:, x" E& D( L! j
) h& H" G* T% c3 \& R' `. n
在代码调试是,发现在执行fifo_init初始化,会进入HardFault_Handler,) i! } v! M% I1 S
9 O9 m6 }" \ H& W8 ?0 n# V; p/ l; q
+ ?/ i& \- M/ K0 U
7 n( |0 L4 T9 r1 S. o
/ v4 y0 T& D/ l; X" d
6 y, [7 ?6 _. B( f, D
最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!
1 Y# N3 R( ^4 M: `- X" [ ~" N% C0 ^' d9 J, O9 ]
/ B" X |- y: s8 Y! a' J$ B* s. R$ o: q/ v! }8 S) D+ ?
M- o/ U7 d. E |