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