一、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- `" 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
+ 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
" 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
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
2 k) @' }" y" U5 r
- \( q E( p- h6 K: V( T生成代码完成后可选择打开工程。 3 o, k7 [& b$ \4 b! G3 t
- L' N* M+ z1 \/ {
, {: 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
- uint8_t aRxBuffer[RXBUFFERSIZE];: ?0 ?, }+ _& w" _* N2 F
- /* Size of Reception buffer */9 D) b0 u; L. d8 V% a
- #define RXBUFFERSIZE 10$ P/ C: _+ a) T1 {% \* a
5 p9 s1 _" O6 [% X* c
& W, R4 @1 p ?6 t! T- f3 R" p- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle): T5 d! Y/ e7 p- [7 l2 ?& N7 i
- {! }% }1 e" h. R' Z( N: O
- /* Set transmission flag: trasfer complete*/9 k$ s9 F/ a1 T* V+ ?+ v
- UartrxReady = SET;
* M$ i- ^2 P( e: n1 j - HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
1 y* h# W3 ^( m; ?" e% E - HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);0 R9 [1 d( q( |
- HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
+ \! Z7 k7 a1 ]; b, x - 2 w/ V: W' b$ e& ~8 J1 N
- }" t+ y8 Y9 `. Z" i# z" v- O
+ X4 Z, S3 L! P6 {$ T9 I+ I+ C0 J- void USART1_IRQHandler(void)
) x" J8 z: q; A/ N - {
# M# m' z6 n u2 t3 O - HAL_UART_IRQHandler(&huart1);
6 H7 f/ u( }* e4 {( k - }- K+ W2 k2 ?4 G
- ' j% ]& E( p1 g
N2 m& E( r m5 O- C4 _- static void MX_USART1_UART_Init(void)* t, Z, l( P; c/ h, o+ o5 Q) P
- {& a5 p& ~1 ]+ V$ J" x
- # H+ n* y6 P9 [3 L3 e! Q
- huart1.Instance = USART1;: @, M1 d0 m. ^# |/ H1 ?. m
- huart1.Init.BaudRate = 9600;
& w* P# X; h& z: u4 c( i - huart1.Init.WordLength = UART_WORDLENGTH_8B;+ V# |0 ~' d; P% f, q9 z. D
- huart1.Init.StopBits = UART_STOPBITS_1;
, l# u( q: C0 k3 [) d - huart1.Init.Parity = UART_PARITY_NONE; k2 Z1 P9 s4 l
- huart1.Init.Mode = UART_MODE_TX_RX; D w* Y6 F2 {# T
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
6 s, ^3 V* A2 w - huart1.Init.OverSampling = UART_OVERSAMPLING_16;$ M3 a* F* [; }: P' _4 C7 ?/ M
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+ g. l' E7 V" S! S$ K - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;) n* K, A+ I8 p4 K9 X3 ^; o7 T
- if(HAL_UART_DeInit(&huart1) != HAL_OK)
9 J% w6 [2 y% R5 a" g, R - {
& w8 B+ c( f; [, B - Error_Handler();
4 J. B# Q( h) D9 D) m( R+ i - }
! N/ I2 F# R* I# j2 P+ F6 Z6 f9 b -
3 E( |7 q; o% ^) v+ O; M- [% q - if (HAL_UART_Init(&huart1) != HAL_OK)* W8 S3 I% R' U" C2 z
- {4 M; _2 O9 Y1 S) b/ v2 o; r
- Error_Handler();
. W, z( O/ Y' a7 C" ] - }
# c2 ^5 W( o8 z7 s" L -
' f6 x! {. f4 @' A2 h- }; c" t3 C. ^ - UartrxReady=RESET;
% r* p- n5 _" w" S, N$ U - /* USER CODE BEGIN USART1_Init 2 */6 J* m; w% n/ I
- if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
. Z' O, b2 z. O - {$ |1 r7 g4 W) z3 P
- Error_Handler();
% J, y, X' }) K2 f/ H5 j - }/ X0 h! T5 w2 B/ c1 D( E* p
- * z" \! \/ w6 w, O' i, M& C. H! `
- /* USER CODE END USART1_Init 2 */
5 \. S; I/ F& w+ P) n - }
复制代码
. 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. \
' }' 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- static void MX_USART1_UART_Init(void)
5 c4 n* e0 d1 R - {
6 n5 \4 B0 K* m' k; r6 v& R - huart1.Instance = USART1;) M- J3 S S8 j5 U5 O
- huart1.Init.BaudRate = 9600;# p; o: G& O z: @! M8 F7 a% b
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
# C2 l5 `) ~$ ^/ x% o( T - huart1.Init.StopBits = UART_STOPBITS_1; c6 L, p9 d m/ |- K
- huart1.Init.Parity = UART_PARITY_NONE; q) r0 {9 U$ D8 i
- huart1.Init.Mode = UART_MODE_TX_RX;+ J. ?$ H' O& s6 Q
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
$ V! U1 O- {8 x$ F - huart1.Init.OverSampling = UART_OVERSAMPLING_16;; e: L% o. e/ Q- @( k4 K s1 A Q; J; F
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;1 ]: O/ z$ [& M; X7 S& W
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;# m, S" Q; @) n e+ X
- if(HAL_UART_DeInit(&huart1) != HAL_OK)
, a. I/ u' ~* a6 y - {
( D5 k3 i2 S1 X# J0 g8 ^ - Error_Handler();# m8 i- G2 ?+ a. Q
- }
- d: |& ?0 H- i; w' l - n& V) @8 B: O) K* [* ]
- if (HAL_UART_Init(&huart1) != HAL_OK)
7 X/ W: n' S, S) B - {
& V/ n6 _; n1 n - Error_Handler();
$ A5 i8 m2 q, Z- b j$ W- v' R+ L7 T% | - }& Q, {- |; P8 @9 p% D* M0 L9 w. d5 @
5 }1 ]. a) e1 F. H1 P5 }5 p- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
v5 ^7 F: |/ [7 ?: x - /* USER CODE BEGIN USART1_Init 2 */
. T9 W5 F2 U6 b6 Z/ N6 m0 t - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)( D5 P. U- C; e, k; S7 c
- {
/ R8 e, m& J" D( b" n' ?: w9 U- ] - Error_Handler();
9 R% `2 S6 Z2 ^7 N; C: a6 t6 w - }
. g) O3 } y+ R) y" c* o - ( t& f4 w, X/ b& S% d5 Y
- }
复制代码
7 `. ^# Q3 {7 ?" A i空闲中断函数: . Y( j! x/ v1 K' _- D2 y0 W
- #define TXBUFFERSIZE 30' D% `; [' G6 V4 ~. y5 Y9 k6 L& t
- /* Size of Reception buffer */
9 m) H$ Y! R* y9 O - #define RXBUFFERSIZE 30
, V( _: y( L, g g - ! t) k: P4 j& Y3 w# X+ b
- void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)9 L: l; z/ f, A. |$ E
- {
y4 q2 p) L' T5 w - HAL_UART_DMAStop(&huart1);% _) U i' ^: m6 ^ ^
- p0 k; M A- Z4 N" G- uint8_t data_length = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
8 P) Z% |+ l# M4 z4 b6 s
5 ]3 M) G# |3 h: ]4 M' y$ e
7 x/ c x+ {! y: _7 d! B( J# ^5 o- HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);+ u& v3 s; [$ c3 k2 E
- # a0 ^& m5 q2 C2 h* ~" i; g
- memset(aRxBuffer,0x00,data_length);' J" V. u0 B: T" s/ L
- data_length = 0;! b2 @- t0 A+ O) e5 \- i
- HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
1 T2 k8 D* A& k0 ?& f5 e - }- B! ~( A7 g) Q* J. e1 P
- - ]9 b( Q9 o! j4 C
- void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
3 o5 H y0 G3 a6 ~) C H, C - {
: t0 F6 c; _# Y - if(USART1 == huart1.Instance)
5 T8 O# G# J3 o2 r$ J* f - {
' J( J: k) d3 g% p - if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))+ k9 L% P1 s. O! Y# m
- {+ C2 q6 z) t9 ~6 v/ D. N! C
- __HAL_UART_CLEAR_IDLEFLAG(&huart1);
! i" L& ^; ]3 H2 E! W' i4 A. p - USAR_UART_IDLECallback(huart);8 G* W9 u+ ^- u( ~9 q/ u1 `
- }, W( f' b! H9 R* r: F: k; c
- }' C Q" F5 _5 L8 R( y) _7 Y. J( Z
- }# V7 T; g( Z4 q3 G( `
- 3 }* n6 u. v0 x* K
- /**6 i# w) A1 {& ?1 y& u0 e
- * @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 - */6 U) N2 j% n! j. y! s- k
- void USART1_IRQHandler(void)
# J0 {8 O9 N2 J* W; i - { G0 t; Y, s1 s
- HAL_UART_IRQHandler(&huart1);/ A* k: ~: S, w# k- J' i
- USER_UART_IRQHandler(&huart1);- N: {, U$ c. o* p7 t. ?+ [7 o
- }
复制代码
: k0 L7 S/ ~6 Y1 \6 e6 b! R3 _8 {可实现不定长的接收!
+ z! z% h) [3 z8 P t
# s2 V& t/ X! K) o6 ?' d; ~. 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
- #ifndef __FIFO_H_1 P) \2 F ~! B) V, z# q
- #define __FIFO_H_% S2 J' o# X, o( u( K+ }
7 z3 o% {( T4 g) i0 v1 y9 b- #pragma pack(4)* T- p) g# H7 v- G1 J) p) j9 W
- typedef struct FIFO_Type_STRU' B' L8 d" N, }4 A: g. _# o P
- {
" r4 P: z: R7 a s' u8 u - unsigned int Depth; // Fifo深度) }3 [; W6 W, ?$ ?9 a6 W
- volatile unsigned int Head; // Head为起始元素
9 z+ ^$ _9 w( D/ E3 B0 S - volatile unsigned int Tail; // Tail-1为最后一个元素 S1 B% v' n X3 H6 h% A$ v) ]
- volatile unsigned int Counter; // 元素个数0 `% C! f! I. X4 h6 I! f
- unsigned int ElementBytes; // 每个元素的字节数element
7 G9 h& d' S9 A. M6 ~ - void *Buff; // 缓存区
6 E5 Q' [) Y+ V7 V0 | - }FIFO_Type;7 p/ }0 n+ _1 r* T! ~4 d5 P
- #pragma pack(). k; E+ x% N- o7 j6 y- |" r8 ^
- ; i" F2 y F" e9 ~* k2 l
- /********************************************************************//**
* L: C5 s& I& ~6 f& r - * @brief FIFO初始化& T& `/ f% J9 U4 j
- * @param[in] pFIFO: FIFO指针
( P% L- b8 p2 v3 {+ N) o* d+ t - * @param[in] pBuff: FIFO中缓存! q" p$ h$ i7 C# c" U, G
- * @param[in] elementBytes:FIFO每个元素的字节数
/ I9 P8 |3 e2 u# R1 c0 v - * @param[in] depth: FIFO深度$ D- G3 y! r. I/ s+ k: ]8 j; B9 L% s; ^
- * @return None0 {2 a/ ?3 z" `5 y+ `
- *********************************************************************/
' w W. P) ~7 |% h/ u) f - void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);. q0 W2 a9 K8 |
- . I9 W6 Y$ ^7 j3 n5 g4 T$ r
- /********************************************************************//**
+ I; n0 n3 R" J k7 o - * @brief 向FIFO添加一个元素$ Y6 ?9 @- L9 W
- * @param[in] pFIFO: FIFO指针- x: L) k- Y' Z3 E- a
- * @param[in] pValue: 要添加的元素/ Z7 c1 A$ G) N d6 ~
- * @return 1-TRUE or 0-FALSE
3 Z* o7 W9 M( A2 M - *********************************************************************/
. W+ r; O0 z' ]7 p7 a - unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
" U K9 ^1 h* d3 B4 E) m, p) i, i
0 w3 l% {1 I f7 o- /********************************************************************//**" M9 |3 j# W/ O" X" e
- * @brief 向FIFO添加多个元素7 R6 Q& y" D$ p* i; d
- * @param[in] pFIFO: FIFO指针
& g3 D/ Y* a& F9 ]9 {% d - * @param[in] pValues: 要添加的元素指针+ N) ?6 \ ]9 z; f
- * @param[in] bytesToAdd: 要添加元素的长度
$ w/ a1 r& \! X/ p7 N - * @return 实际添加的元素个数' F/ `$ c' H9 W& ~% m3 q2 u
- *********************************************************************/
& @5 `, l$ k8 t - unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);6 z' P' A; Y8 @$ b. G
! K3 n* X1 j. \; `8 Q- /********************************************************************//**' ^7 W8 l9 Q/ x3 S+ \% `* ~
- * @brief 从FIFO读取一个元素% U3 b& i. d2 T, g
- * @param[in] pFIFO: FIFO指针/ I6 {, u: O3 E: p5 y7 ?6 W
- * @param[in] pValue: 存放要读取的元素指针
; I8 K! B+ C5 G - * @return 1-TRUE or 0-FALSE
6 I& f; K4 m: I0 S1 `+ a - *********************************************************************/
+ F3 V* v9 j [% g& J" Y5 d6 T - unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);
4 k6 l' i. | Q. P. v
# Q# @! U) y9 y- /********************************************************************//**+ }: q: U1 b. |3 T7 H* w; n
- * @brief 从FIFO读取多个元素
6 m& h" D/ ^. { - * @param[in] pFIFO: FIFO指针
! F: J$ ~+ ^ J; c: w( v" V - * @param[out] pValues: 存放要读取的元素指针
8 X/ E# `( R& n( }. v - * @param[in] bytesToRead: 要读取的元素长度
7 q$ @ h. l, r1 x" M - * @return 实际读取的元素个数* m% Y) O2 T3 I* s9 u% k
- *********************************************************************/
$ `+ t I9 v% z4 Z - unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
; ^/ m; p4 s; C" w v8 j, k5 ]' ?
4 t p }4 H; \8 S7 m% \( ~
4 N$ @3 v/ _5 y; K9 g- /********************************************************************//**
& p4 z7 b" a, @1 _7 I( W - * @brief 清空FIFO+ j' f5 x2 H3 X! H
- * @param[in] pFIFO: FIFO指针' J2 W/ P1 p5 |& O6 m/ O, o. G. P
- * @return None
4 x+ T/ a& c a3 t% G! s: h) s - *********************************************************************/
+ O1 n& t4 H0 L: [9 F7 `3 @- L - void FIFO_Clear(FIFO_Type *pFIFO);/ L) s9 \' s) J/ F, F8 o% F
: ]+ B3 T0 K% ]' I' [7 C- 8 J- F% T7 u9 M/ R9 F* ?0 I
- unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);5 h* }2 }& B! J j3 I' m# u
- 4 h" ?& l) }% {$ P9 u
- #endif
复制代码 * ]! |- E7 Q& E, h9 U+ Z: N9 h- w
② fifo.c程序主体
( [" e* u7 A) \" z4 U5 T$ J+ D3 x$ s0 i. Z" _
- #include <string.h>7 k4 i( o9 C9 p2 J; y; u
- #include "fifo.h"3 t" k- ]: \% M8 j- g+ V& }# l8 ]
- * t; b' j2 j) H) E0 J, U4 l
$ f5 |+ A* X% x8 `! l- /********************************************************************//**/ ]! J( y# o. ?( g* B
- * @brief FIFO初始化! G, g$ s @( t- n1 U
- * @param[in] pFIFO: FIFO指针
% m1 j, d6 J2 i$ t. I - * @param[in] pBuff: FIFO中缓存
7 K g6 A- }2 F0 c5 } - * @param[in] elementBytes:FIFO每个元素的字节数& a7 Q4 p" v+ `9 v4 f4 ]5 r
- * @param[in] depth: FIFO深度) D- W- t# l# |
- * @return None$ `: E5 v- r9 m2 P& l& V
- *********************************************************************/
/ ?" ^- z. }4 f - void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
1 |7 z' C7 G2 O - {
( {- T' u) A2 g3 b0 I1 \ - pFIFO->Buff = pBuff;# \) M+ [8 R8 ]
- pFIFO->ElementBytes = elementBytes;
& ^# x* j8 Q, O# W2 | - pFIFO->Depth = depth;) c* K3 R5 R. U3 D5 p; {: G5 s
- pFIFO->Head = 0;
- r' u5 U) `+ O$ J' }. ]/ Y - pFIFO->Tail = 0;
4 o* [2 k/ L. O' b/ i. a4 @ - pFIFO->Counter = 0;* s( h, A- y; V6 D% M* h1 x$ C& p' \
- }
' @7 {+ D) S" m8 r8 y0 i
5 a, d' G/ O& p3 V) x6 n9 B3 E- /********************************************************************//**
1 E: n m7 Z2 n0 b8 b8 E - * @brief 判断FIFO是否为空4 R1 j; b, i/ ]+ x
- * @param[in] pFIFO: FIFO指针
$ z" \( G9 j2 P. E ]& L% X - * @return 1-TRUE or 0-FALSE
+ _9 u6 X5 b! Y9 d l0 V% Q. D4 b0 s - *********************************************************************/
) a0 g. f" i* G" b - unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
; T+ |' h$ R7 I g - {
4 f7 k+ e4 L! X, x8 e - return (pFIFO->Counter == 0);: M- F1 p8 R- |9 G
- }
0 N! s7 e9 }& a, C8 i3 W+ V! ~ - ) U5 t" \ O, t* p! x7 S, b
- /********************************************************************//**
3 }# g; a$ F6 P - * @brief 判断FIFO是否已满) E* k+ v2 @0 D' Q+ o& u" t
- * @param[in] pFIFO: FIFO指针' N. c; C( K9 ]
- * @return TRUE or FALSE I/ N: ?# }- [" H; Y4 H. B$ Q
- *********************************************************************/$ |; n$ `, [! k' ]1 I# g, O
- unsigned char FIFO_IsFull(FIFO_Type *pFIFO)3 P! Q2 y: q/ U. c: @
- {6 e5 T7 t3 r. E& b
- return (pFIFO->Counter == pFIFO->Depth);
x7 c' G' \# ^' @/ D4 \; N7 S - }
2 q9 ^0 w0 g% `" T* N, C: i, { - ) x! C1 q* x' z6 t9 L. I( Z/ t
- /********************************************************************//**& ?1 P2 |+ e* @
- * @brief 向FIFO添加一个元素8 _2 `, A* n7 P, \$ `8 S; W8 o I
- * @param[in] pFIFO: FIFO指针
. E, \+ u# x: ` - * @param[in] pValue: 要添加的元素
- C' ?% B( E V! c9 G# [- b - * @return 1-TRUE or 0-FALSE' @; c8 `' d2 `6 \. b( z
- *********************************************************************/
1 x3 \: W& @& N/ V+ H( @ - unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
! u2 g4 }7 |* ? N4 s( I: e S- P - {
! u" b* Z( {( j; c0 | - unsigned char *p;1 A: _& N, D/ s" ?6 E+ M
- " L* \( c0 ]) g# m3 m# e* y3 r
- if (FIFO_IsFull(pFIFO))# g) \6 W0 g' T' [% O) L( S/ w
- {
$ M8 ~1 H" g1 e/ J! [8 _( z, N - return 0;2 s2 \" u. f D% r- c
- }7 l" L }" Q0 ^! ^
/ j$ a' c6 P. v a- p = (unsigned char *)pFIFO->Buff;4 `" x K6 d- u& V
- memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);
! P \ o, m- f" c1 X7 V; n8 Q! k - 2 w2 p, [6 X+ @, b$ j; q" Z3 a
- pFIFO->Tail ++;6 N( V, G. c6 s% f- j
- if (pFIFO->Tail >= pFIFO->Depth)
! o* E+ J+ C; a3 L" A y; ^# K N: L - {
* Y5 h' Y! D1 P - pFIFO->Tail = 0;2 w) a! |- \( P1 j! _" m
- }7 K3 `' f2 I4 o4 z' ]
- pFIFO->Counter ++;/ e8 t7 E5 J! Y/ ]) q* H3 s
- return 1;9 w3 ?; y8 u- C2 q# a
- }4 q9 @$ s% g- N: C, I
- " ~! ^% \% M9 d0 f+ K% e6 _, X
- /********************************************************************//**% s3 ~, u) {0 }, k: w' T) N/ t: H6 H8 s
- * @brief 向FIFO添加多个元素
3 a- J0 @3 e6 k, N0 f/ V - * @param[in] pFIFO: FIFO指针
$ T# x( `7 [3 d/ e3 V+ \ U! { - * @param[in] pValues: 要添加的元素指针
. n; R% e% I# Z - * @param[in] bytesToAdd: 要添加元素的长度! ~6 O) D* @ g, T& F, X
- * @return 实际添加的元素个数7 c- ~' _5 D$ c
- *********************************************************************/
8 U, l! W3 ^$ h' b8 U - unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)- x. t1 g+ `2 D4 d$ n+ K4 h1 X
- {
6 d/ R( `' m0 C, I) v. w+ X - unsigned char *p;% C! w& W+ D+ }$ C3 I! X1 k
- unsigned int cnt = 0;
6 g+ m% A( T2 n - " i% y6 ]3 u: T+ u8 m$ d# s4 c
- p = (unsigned char *)pValues;, T( M5 t" n5 A! S+ B$ S
- while(bytesToAdd --)8 @9 q# A9 L& I4 W& o: U
- {
6 x( |2 E4 }0 H/ c/ s - if (FIFO_AddOne(pFIFO, p))
+ o" |7 Y; G4 O8 b - {% l5 ~ U! C0 s5 z
- p += pFIFO->ElementBytes;
& ]- h; ]; s- ?* L. z* X/ P - cnt++;! m( e) ^$ M6 U$ n
- }
2 o+ B$ `! _5 }! p9 H - else$ g2 G5 W" w6 y0 D
- {
. k! v9 U& a6 g$ [3 k( C - break;9 G7 ]9 c' w1 _; f) f9 K
- }" O) R' S+ ~3 E& K- x. { n
- }
& U% z3 n$ _/ M# l+ n0 x' s: n. C
* T7 v7 ^; V1 l- return cnt;; ?' o% p: g/ b- m% f
- }
+ ~& I& {$ v+ V* l" E - `7 Y% ^- D$ h, p
- /********************************************************************//**
/ r. U- F+ b2 F$ S - * @brief 从FIFO读取一个元素
/ c3 f& W: g; `6 G( @% X- _) g" D - * @param[in] pFIFO: FIFO指针
) }# M3 @9 q4 q% E - * @param[in] pValue: 存放要读取的元素指针
/ V5 Q4 r6 y1 d - * @return 1-TRUE or 0-FALSE" ~) L; k* w ^' r' C
- *********************************************************************/# p& N2 z8 u: ]* n H3 c0 k
- unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)! @2 a" O6 z! ^% d o
- {
! j8 B. Z- R3 C* @$ o. F, d - unsigned char *p;
/ D; E5 P7 y: m - if (FIFO_IsEmpty(pFIFO))
4 c+ Y N- r# I% M# Q9 o - {: h5 l! Q0 ~4 x- G! L" n
- return 0;7 i& R' K: @1 g5 O% F9 Y
- }3 P4 o$ J( z0 z3 N. y7 r% i9 C( \; r
$ X) J4 G) }- s" S X- p = (unsigned char *)pFIFO->Buff;
& `6 R* c. S7 e0 Z( F% w* b6 x - memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);( M6 J& E D' \
- g& V+ n! f/ @6 n4 D- pFIFO->Head ++;& p1 G; C+ Q) Z& B+ L# b; U2 F
- if (pFIFO->Head >= pFIFO->Depth)
2 c' E: Q, p* F" }: b# m* ^ s - {
1 @! x: s/ u9 s/ e1 |; H8 y - pFIFO->Head = 0;- o( q6 e7 J, m) I: i* j% B5 W2 k
- } F7 ~6 z \" K, Q0 y; {
- pFIFO->Counter --;
) J% w, R( Z! |& i0 e9 j' r7 F g - + c- L' E7 }6 c1 P
- return 1;5 g; r( f8 s! d9 A8 v9 T
- }
4 \9 C$ y7 N7 }5 A) f# q2 c
& k, z2 W0 B1 K/ X# z( a& a- /********************************************************************//**$ Q2 `) P6 U1 a' t$ ~' T
- * @brief 从FIFO读取多个元素% p6 t t3 r) F! D' `, ?/ o
- * @param[in] pFIFO: FIFO指针 H% T9 o7 g. `# t1 `
- * @param[out] pValues: 存放要读取的元素指针+ R, ?/ X, f) s+ v6 y
- * @param[in] bytesToRead: 要读取的元素长度
! w$ I/ R7 g8 R$ Q - * @return 实际读取的元素个数6 ^7 w7 m$ A5 W& B$ C" |
- *********************************************************************/
& B/ A- x7 N* Q5 N. u7 b) h - unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)# i. Q6 X/ ]! ?: p* N
- {9 ]; }6 t4 r" ~( I6 i; Y/ o
- unsigned int cnt = 0;
9 n6 L& }. n4 X1 Q9 [9 J5 D - unsigned char *p;! }# C, y- e) a. Q, }5 o5 j
4 g4 L( y- ] K6 Z+ ]- p = pValues;( n/ a: p1 M& ~7 i( i
- while(bytesToRead--)
! w3 g$ {! {& N' a6 @3 I1 N' B# { - {. ]' p4 h. e+ F, l) a" u/ o4 m9 i
- if (FIFO_GetOne(pFIFO, p))' e) ] c8 X( ?. D# {( D2 P' Z0 I
- {
W5 E4 P, t$ G% c; q% F. ] - p += pFIFO->ElementBytes;
5 R- r, s3 d. d% @: T - cnt++;' x" {( W5 V) ]
- }
7 a2 a% F( n6 h5 T2 d% C) u% H( h - else
) h8 e/ z& U! {1 `6 u - {
5 h' ^; @3 i+ @/ p4 D: e3 i8 V8 E - break;
: N0 E( P4 n- d$ { y" k# X7 a' ~0 } - }
! s5 D9 U: i* i* ~ - }* f" C6 G4 l f) @9 q
: I) I& D, S+ m& u2 E- return cnt;
# w- @1 B: q8 y; W% g - } R" _) r6 M V
- / c! u8 Q, _1 s( G( v8 t
- /********************************************************************//**; a/ d# o' ]% y1 E, w
- * @brief 清空FIFO& s# K8 w+ k8 K; n, e
- * @param[in] pFIFO: FIFO指针# W; v; x/ G* K2 c+ `5 Z
- * @return None. h9 g5 a1 k, E3 r6 X" K
- *********************************************************************/
3 Y% |0 q& f# [5 ^; b) k - void FIFO_Clear(FIFO_Type *pFIFO)
1 G, Y* B6 [( H7 ?' ^) O - {) F% e# v3 D% d0 W& R6 @
- pFIFO->Counter = 0;
3 T1 A$ H H& {7 D - pFIFO->Head = 0;& D0 A/ ?5 y$ w ^$ I/ p; g7 q( ]* l
- pFIFO->Tail = 0;
) I/ |( P e% H1 b4 h' m, J3 ?* \: A - }
复制代码
5 |- E! [0 J' A4 U I ③ 串口初始化
y! `/ M9 \/ A7 J5 y- static void MX_USART1_UART_Init(void)
* X2 ~) o5 K# k _6 |5 X - {- {) B2 l% \% ~ G5 K/ v
- huart1.Instance = USART1;
+ {: B* c- r) w: Z - huart1.Init.BaudRate = 9600;0 b1 e: J. Q- P8 B; q9 s/ t
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
" G c$ T+ E$ h: y8 r- n e - huart1.Init.StopBits = UART_STOPBITS_1;' L6 j7 l# O* t! m( j
- huart1.Init.Parity = UART_PARITY_NONE;: Y% |) n1 u, K2 u
- huart1.Init.Mode = UART_MODE_TX_RX; c' K' Z' ?0 [2 U( k" H1 b' ~; a* R. ^0 I
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;5 J# g$ Z6 F! G: U& |$ P
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
g) X9 w t- V( Z4 J. Y6 F. i - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
. P' d2 I* Y# ~- c( P! F6 n; u - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;/ T. v; |: p, A3 o M0 h8 h! `4 Y
- if(HAL_UART_DeInit(&huart1) != HAL_OK); m5 `: L' H( S
- {4 X" z$ z9 [; E2 a/ a& Q! ?* _
- Error_Handler();
+ W- C+ d6 W, v! N - }
& z P' H( t0 K' F, l - % G- n, t( M* o5 o
- if (HAL_UART_Init(&huart1) != HAL_OK)
$ m5 K o$ }+ ~. i - {
" |' H6 _& w V - Error_Handler();
' x$ e) L, d( j - }1 O$ O5 h y$ B
- 6 p5 Y3 Y' L% _6 q
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 0 e7 @4 o( I L2 d" ~+ N
- /* USER CODE BEGIN USART1_Init 2 */
: E' q2 U5 l3 D5 R - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)1 J8 w; ^5 c4 A# s
- {
|0 e/ }4 C x* t# n2 s - Error_Handler();1 k4 E- S7 G" D8 n# K, B- a% B) q. J
- }1 T h2 H& \% o5 l% H
-
8 g4 d! l8 K4 y& ] - }
复制代码
7 c: w8 {/ e Q& O ④ 接收空闲中断- z: U5 U" b6 `2 O# ?8 ^! T( W/ f
- void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)( M1 b9 D+ o. h2 m m/ @, z
- {
! V' Z4 A; h; ^8 Y5 y1 j& F3 I5 C - HAL_UART_DMAStop(&huart1);
7 X( w, @4 k# Q! P2 G) k - 5 I' N; R3 g P/ T: |% Z
- uint8_t data_length = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
" M! J$ d, E& m$ C5 y. N, S& I -
. }/ Y1 s6 A1 M* s! F. D - FIFO_Add(pfifo, aRxBuffer, data_length);; y. L5 { K" i& l& J
- data_length = 0;
2 a" Z( { I. A V1 v) C( M - HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
8 c( |' a! O$ r2 {+ f9 i0 z t - }* y: p& i+ Q0 j" j% ?
8 K, P" ]4 a F# Y! ~0 _0 u- void USER_UART_IRQHandler(UART_HandleTypeDef *huart): w/ P; m& f! B& L
- {
( Z* |8 L/ I' i- S7 {" \ - if(USART1 == huart1.Instance)
}( X3 f5 Q" ?5 W* S# q. X% r - {
g! O3 P* o. z# l. i% h/ Z - if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
- r" T2 }9 j7 C; W8 I9 `$ C: { - {
9 P" A4 n& Y s, K - __HAL_UART_CLEAR_IDLEFLAG(&huart1);% G1 K; J& V# l- x2 `+ V
- USAR_UART_IDLECallback(huart);
6 G/ {; D4 ?; e3 c - }
! M: L: G6 k6 Q* t - }
3 I" f! s9 @* k+ t2 y- H2 Q - }
) H2 u4 I3 S. F# P/ X( R - 0 Q: Q' b2 H4 X5 r% f' r
- /**' p5 F" I+ }' \% R' h* Z( n
- * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.$ i) b6 c. Y0 K7 |7 \
- */: D6 t6 O2 i/ S% m: K* G/ B# Q' D6 p
- void USART1_IRQHandler(void)
) R- C8 p1 A: u" V - {$ C. V; q8 k1 i6 d" k0 `
- HAL_UART_IRQHandler(&huart1);5 A6 g' D1 [- I
- USER_UART_IRQHandler(&huart1);; G- [! [5 Y, K3 B( i) C" `& S
- }
复制代码 ( i% R$ K; `; D1 a; g7 w. \
⑤ 主函数调用:
: H9 s+ T2 c* h4 Z" T- #define TXBUFFERSIZE 302 ?' f" C6 l" ^" b
- /* Size of Reception buffer */
- O# W. X0 ~$ N% D' u# {; b# J - #define RXBUFFERSIZE TXBUFFERSIZE
5 a% V& A0 C$ i+ E - #define RXFIFOBUFFERSIZE TXBUFFERSIZE * 5
8 l- S1 p& u9 ? }: s: V2 r
" J" j- z: o W- ^; e% r- x
; ~7 }/ u* ] a+ M* a* }. T- uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";
3 f( t1 g2 r' t0 K
. _3 z* r' X* R/ V9 R% T7 a- /* Buffer used for reception */5 W8 F/ t( b! M
- uint8_t aRxBuffer[RXBUFFERSIZE];) V; s3 I8 u9 @
- 4 w, J0 h& ?, ^
- uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];' S5 V5 m1 p+ k8 C: O
- FIFO_Type fifo;
- h& k) R# V/ P3 B9 S' } - FIFO_Type *pfifo;- ?" w6 S/ r( p* e% v( b: Y# \' j
- 5 N4 k+ K9 H4 `) B
- int main(void)3 B* ~& b1 P# _ W' w) S
- {3 j' d% d' `( F3 g! X5 {
- /*此处省略硬件初始化*/
+ A# v( I2 U; m' D: R' Z4 c - if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
# p- s6 P, V A- D/ C5 m - {
$ W( h6 O# z5 q& E# Y* I8 u - Error_Handler();3 R w3 s, l+ ~ }6 Q# u" H4 W' g a
- }
( I4 q, f# Y/ \1 Y7 l -
# l2 X' A+ b! O7 J% \ - pfifo = &fifo;6 v8 @# T: V' [
- 0 G0 B5 Y3 R7 T% ?$ c$ ^
- FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
- ? m/ e7 |) M7 Y* r# R2 r! i - : S& F8 u2 t3 X
- while (1)
( f% q2 g4 C& `4 b h7 { - {
5 T, I7 z% T( U- n9 Q$ O - /*一次接收的缓存,重新发送*/
$ t7 c; {" O( O3 l' O+ p - if(!FIFO_IsEmpty(pfifo))
, [# M+ L! j \+ {- J - {( y2 m9 d! U. Y" ~( M0 n
- uint8_t a[100]; //存放读取fifobuffer的数据0 ^+ n9 z+ U* E: q4 J3 ]! t( R5 n
- int i = pfifo->Counter;//先保存接收缓存的数据个数
3 P" k- Z4 a+ Z6 w - FIFO_Get(pfifo, &a, pfifo->Counter);
+ Z5 Z3 K- [$ J. X& U H - HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率
# _( w: W1 C |7 H9 h$ D - }
% {5 v0 l0 n8 u& |) Q g2 k - }
) O2 E5 M9 ` R/ p3 b - }
复制代码
# 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& 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
; U/ J5 Y6 o! V" i: f" b' m2 O4 J: N
3 J4 e9 ?% L2 Q( ?
1 A( ^1 B0 v8 [$ B( v C' f 最后,发现是在fifo_init 调用的指针,未赋地址。添加之后,解决了!
8 o$ X3 R8 K! p9 {( l# I- V* B3 E, r2 ^6 [
% C5 y- {6 U' O" s6 @' [. S
. x1 W/ C, \ m& M4 k. E
F, }, V3 `( F, ^' \ |