一、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
! 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
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% ~
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
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
: 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
" 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/ `- uint8_t aRxBuffer[RXBUFFERSIZE];
* J }3 V4 L2 }% _1 T3 |6 h - /* Size of Reception buffer */
+ B$ @5 g; h E1 X g z - #define RXBUFFERSIZE 10
5 x8 \ K5 K* i4 S5 ?+ ?2 c - 5 u& h( ]. k* [6 p) [8 B
- 5 |! Q6 @3 x3 g. ]
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)" U( w, D9 n7 v x3 C# O
- {
- O" k; y$ p1 W! @ F) F9 {% ]* E - /* Set transmission flag: trasfer complete*/
% S: Y+ }9 i) _3 W! { - UartrxReady = SET;8 b% Z* b$ ~: c0 f5 d5 s8 B: V7 X
- HAL_UART_Transmit(&huart1, aRxBuffer, 10, 0x200);
5 E0 H$ M Y& K7 x- v% W0 i - HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);4 c' X" _) z$ ]# b3 l: e6 ~" |
- HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer,1);
3 Y4 S4 ] X3 s: K# M/ V/ U
! y& u8 `2 G! W- }& ?* d5 X2 ?7 z9 x; o
- A: v% W& o+ p- b- void USART1_IRQHandler(void)7 n9 r, u+ u1 ~* s# {- A
- {2 d& S6 } F4 w2 T6 w! ?0 N8 i
- HAL_UART_IRQHandler(&huart1);' W3 r: u$ _3 ?) l5 n
- }
% e% [- z! X! ^! j6 ?& a' y - . `& k9 V( x; i1 b( ]! A1 l
3 O% `* m& a' }/ I8 m Q: `( c- static void MX_USART1_UART_Init(void)) Y/ _! j. I1 _- G
- {
+ e K: l8 {7 W0 H. V+ ]4 ~% x1 R' e - ( Z2 m7 s7 M) V8 X7 @( A: t
- huart1.Instance = USART1;
$ d( c$ C9 v& A - huart1.Init.BaudRate = 9600;
" L1 [+ C0 s: F# q$ A - huart1.Init.WordLength = UART_WORDLENGTH_8B;
1 Y9 p& \; G9 N4 c6 B) N1 v8 E* m+ M - huart1.Init.StopBits = UART_STOPBITS_1;
0 O7 u9 | ~0 O# }4 d - huart1.Init.Parity = UART_PARITY_NONE;2 D" F) K2 }, `/ M. [; p4 f
- huart1.Init.Mode = UART_MODE_TX_RX;
G- S& ?8 K. g6 r1 Y8 s - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;9 Q$ |; R" J; T) s* Z
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
( P( [/ W* q" B9 y - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;( u4 G# B1 Q# h& V' p3 C
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
% G \+ W3 F* p; V. {2 Y - if(HAL_UART_DeInit(&huart1) != HAL_OK)
0 i2 c# E; B4 j5 o# D - {! w' O. t2 P/ J# |
- Error_Handler();
/ Q" k% v& {) D+ Y8 ` - } 8 Y& z2 w/ u- x& f- V
- " o3 `; w+ w& x9 _1 n3 ^' ]
- if (HAL_UART_Init(&huart1) != HAL_OK)9 p. g2 E8 c( T! a6 X
- {
4 s0 l7 y9 j( q2 s$ l - Error_Handler();$ M, q- C2 m, e
- }
0 @1 b1 G8 H" A4 R3 A -
8 v8 m9 u$ y, K& ^0 x, O - UartrxReady=RESET;
; h0 q5 Z) u2 j& u - /* USER CODE BEGIN USART1_Init 2 */
. A# T0 @: O# S0 q+ Z - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
6 y- d( ~4 g0 `" K) l - {' p1 ]9 p$ J: ?, P% D, g0 C- L
- Error_Handler();1 r2 t# n2 I" y
- }
* d1 L8 J1 l1 n -
2 N( ^4 O0 E5 }- S) Y4 S" }- t+ Y5 W - /* USER CODE END USART1_Init 2 */
3 c7 ?* a4 M' R$ u' y9 a - }
复制代码 4 ] J9 k8 X$ F& M
从串口调试助手可以看只有接收的长度 RXBUFFERSIZE为10时,才触发接收回调函数。' Q2 L/ Z" ~" u- p
3 n' _$ u0 R3 K9 D* |, 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 `
- static void MX_USART1_UART_Init(void)* C( |9 M* `8 r) n6 i; t
- {; o+ m+ z+ \1 t6 t0 B4 B: {
- huart1.Instance = USART1;
% A2 ^2 ^2 M7 g" @ - huart1.Init.BaudRate = 9600;
9 P! z* N* V8 n5 F( `. L% V - huart1.Init.WordLength = UART_WORDLENGTH_8B;
5 a9 V. i) o9 y1 ] - huart1.Init.StopBits = UART_STOPBITS_1;
/ o8 X0 L$ ?2 B' Y; G - huart1.Init.Parity = UART_PARITY_NONE;- v! X) c9 W4 N
- huart1.Init.Mode = UART_MODE_TX_RX;
7 W+ X3 D! T3 Q( w/ Q) q" o - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;+ n% _8 y) [$ b7 C
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;, j+ x7 L9 E5 I" h% {1 M1 {
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;% O: \" G. L4 ]$ z( j. l; w
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
: I" { i) p. O+ X; s: ]- \ - if(HAL_UART_DeInit(&huart1) != HAL_OK)4 N3 p2 q& e/ N* v
- {3 b, C/ a" x$ @: d! c* u7 J% J
- Error_Handler();
?8 ]( {% @# I/ c' Q! V - }
. I0 J5 k1 e( \" g$ x -
1 `% s" y7 [" {* Y8 X% q; C - if (HAL_UART_Init(&huart1) != HAL_OK)
6 z* G% V3 x q - {
+ e8 @1 [' y9 Z% e0 h" B6 t - Error_Handler();
& l1 t& v2 B- C6 h* K! j - }
g' A) c$ a! W$ [ @" B% [: B
& H2 y4 N7 m9 I* v. A7 [$ h- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 8 P8 Q: U, X+ s
- /* USER CODE BEGIN USART1_Init 2 */
9 m L1 u' L. c* D: H9 ~! w - if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
! q$ S( ]( W: K; N3 { - {* m( U4 j5 b% @5 ^ p
- Error_Handler();9 g) u/ F4 v9 S
- }
2 \7 ]1 q( M/ b7 {) L4 e* r2 j -
7 R8 t) o# F9 s4 f" m/ ]& ^2 s - }
复制代码 4 ~% B' q3 \) v" F
空闲中断函数: ! A/ X# A0 V6 d# p7 o
- #define TXBUFFERSIZE 30
. d2 i! v/ U+ x% L - /* Size of Reception buffer */" C" P' H4 U! D& N" U
- #define RXBUFFERSIZE 30$ M' u; A! @1 V; \7 H
- * V! C$ O4 s4 j9 j
- void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
6 ~1 K$ m/ ~7 `3 i - {
8 t6 W4 j, h0 d3 }6 A' x - HAL_UART_DMAStop(&huart1);& m4 P" ~, G% `! n" Z6 a
- + ?/ C a7 ~& Q6 j" z
- uint8_t data_length = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
8 K, g3 p1 a5 n% g3 A" J - 1 F" v ~. i0 |2 Y. k6 ]2 m1 [
$ }* K/ \9 s7 |; {7 l- HAL_UART_Transmit(&huart1,aRxBuffer,data_length,0x200);
- X3 z/ a1 V7 D! m6 G" d
& G4 K l# F ^0 _% l+ o- memset(aRxBuffer,0x00,data_length);3 Y& a' t2 |; N6 r9 k
- data_length = 0;7 S( b: o' g" _# H0 X9 Q
- HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
5 ], I# A9 S5 ^# l! ]( c2 f9 b - }
5 p& b# a$ f* p3 ]& V _: P3 X" F' l
5 l3 V% ~0 [; ^0 L3 ^9 e5 c! u J- void USER_UART_IRQHandler(UART_HandleTypeDef *huart)* @ z% F0 e, B8 S% a! n
- {/ N: [/ a& c4 L" v* v( \2 ^% |
- if(USART1 == huart1.Instance)
* S4 K" J! G! E/ |0 U8 G' M - {( ^3 s: Q+ v" j. d% h
- if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))! `$ p+ R: M2 j% I$ ?2 ]8 n+ W
- {
- U+ |4 ?# {6 p4 | - __HAL_UART_CLEAR_IDLEFLAG(&huart1);
6 l8 [9 k0 m1 r: i0 G - USAR_UART_IDLECallback(huart);
3 Q% A( A9 c& r& e+ Y4 t* D0 ` - }+ t5 ]! o; t9 \$ Y* v* B! ^& t- ]
- }
0 ?. p2 ]4 g; A: A$ E _5 h - }& `2 t G( T9 _% P+ E
- 9 [8 N: e) H; R! W' ?9 L* B$ X- @
- /**+ |- k+ u: X" ^) X" g3 i, H3 {
- * @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
- */8 h" D$ E1 R6 T+ j/ x
- void USART1_IRQHandler(void)
5 P4 N. U/ X9 o) n - {
1 a, q( ^% z# F5 q! u - HAL_UART_IRQHandler(&huart1);8 l) O; }; ~# l+ h
- USER_UART_IRQHandler(&huart1);
2 g6 D6 Y4 }% n1 c$ t - }
复制代码
, V; {/ y7 V+ T- a) b7 G& B可实现不定长的接收! 7 g. d0 W. N( B& h
}8 ^2 L7 N9 T" j" S* J* L5 |
( 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- #ifndef __FIFO_H_' D- t* F+ [- K0 [9 M) ?8 V6 `9 c
- #define __FIFO_H_" O7 ^9 T5 g$ C) B$ h* Y0 p$ J
7 [* n7 q2 H/ x& P! }) ?2 n- #pragma pack(4)
4 ?4 S+ Q/ J* s3 n4 U - typedef struct FIFO_Type_STRU# p- ^' @" p4 O+ c
- {- c9 r& N9 G9 G# l% j: M6 ?
- unsigned int Depth; // Fifo深度
1 u; Q) b3 @- V" N) {4 m+ q9 U& l - volatile unsigned int Head; // Head为起始元素
! ~* T, i6 b3 Z3 }7 G1 z - volatile unsigned int Tail; // Tail-1为最后一个元素. t# B0 G, |% ?+ }' \( b) t
- volatile unsigned int Counter; // 元素个数6 m, p* d0 E& G9 h2 B9 l5 x
- unsigned int ElementBytes; // 每个元素的字节数element
0 K# f+ }4 x F$ x5 c6 M - void *Buff; // 缓存区% C$ q. o, V2 k' {
- }FIFO_Type;4 Y# Y9 T7 v& H+ L1 C( {) n
- #pragma pack(): L P# z, ]8 I
- ' x& @. n0 O, ^8 @' X/ q( i
- /********************************************************************//**
1 w z% F% h* n! f" ] - * @brief FIFO初始化
0 K% }6 X7 T0 z# @, G0 W - * @param[in] pFIFO: FIFO指针: s8 j$ u0 m1 H$ {" M
- * @param[in] pBuff: FIFO中缓存
- X+ r' P# X+ u8 x) y! O3 b8 X - * @param[in] elementBytes:FIFO每个元素的字节数+ a& s( ~$ S8 k" x( J' H
- * @param[in] depth: FIFO深度9 i. ^2 q, j3 G8 w' G
- * @return None# J4 D2 r' R1 S+ N2 _6 a
- *********************************************************************/; ]6 M$ T) ?, z
- void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);
; l& z5 \/ d3 | - 5 O! K4 \; P- f0 z
- /********************************************************************//**
! ]$ ]7 @% l( w7 [3 C. p - * @brief 向FIFO添加一个元素2 L W0 T8 J7 ~$ O( T- ~- E
- * @param[in] pFIFO: FIFO指针2 g% Y7 |; L( [$ s
- * @param[in] pValue: 要添加的元素
, @# `& E# a1 ?) Y* D5 X' {" F - * @return 1-TRUE or 0-FALSE5 ~$ |6 `0 m# _8 T- P* j/ l L3 v& ?
- *********************************************************************/. [% X, T: L, b. Q- o( d0 b
- unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
1 }9 X1 K$ O9 t
& V5 t$ v! Z8 E6 q; T) Z. }- /********************************************************************//*** X/ u1 J# E7 t5 m9 x. V) p
- * @brief 向FIFO添加多个元素7 G6 e* u9 h1 D! W+ t6 \8 e
- * @param[in] pFIFO: FIFO指针
7 |" ]- x3 T' h& @: z - * @param[in] pValues: 要添加的元素指针
' o. I1 A' N. b8 R - * @param[in] bytesToAdd: 要添加元素的长度+ I( D5 @1 Y+ k' F
- * @return 实际添加的元素个数
/ b, ^' z/ Y" @4 a - *********************************************************************/
+ s. H4 d- F) D3 V8 Y) g( Y - unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);
, O% @. s) F! @9 n
: D9 u! i: l9 ]# Z- /********************************************************************//**
) @; n/ v. T3 J$ Y! _6 A6 ? - * @brief 从FIFO读取一个元素
( K% s& _( y1 F+ U6 J& f - * @param[in] pFIFO: FIFO指针
% q' O/ J) p' O; {7 Y4 ? - * @param[in] pValue: 存放要读取的元素指针
8 g7 o. U) |9 e8 u, ~& Z$ | - * @return 1-TRUE or 0-FALSE1 n* v0 s+ M% T' L0 f% r v* c
- *********************************************************************/
/ \/ }0 P9 _ o& k( T$ `+ f - unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);9 c; T S! S6 y7 R
- , X+ V. `0 D+ ?8 s' Z1 |
- /********************************************************************//**
0 C6 y) b# u/ `5 X - * @brief 从FIFO读取多个元素2 l+ H; K+ \* H9 `2 k. e
- * @param[in] pFIFO: FIFO指针6 B7 i8 _' P* O; D3 T; Q; ?
- * @param[out] pValues: 存放要读取的元素指针; L) N8 ^* P3 X1 F( [
- * @param[in] bytesToRead: 要读取的元素长度
3 A# c8 u2 s. r' F, i - * @return 实际读取的元素个数
; u8 B$ s* P3 E! k! W t - *********************************************************************/6 D7 i8 X! M, `) h" v; G% x0 W
- unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
0 d; v2 w& _& J: H
" b S1 {# w4 b, t
! L* y$ C8 r) ?- /********************************************************************//**. |5 S& i X9 A X* x& S; |& D
- * @brief 清空FIFO( g' S: ?, _* _: v
- * @param[in] pFIFO: FIFO指针
9 J5 M$ Y' H H0 @ L - * @return None8 ?1 h8 P% {# k% B7 N; P3 W
- *********************************************************************/
2 S1 V7 H6 \& _1 X9 L5 u. H& a" ^& P+ Z - void FIFO_Clear(FIFO_Type *pFIFO);
; g; U" C6 g. S; N$ d+ x+ l! g
- i8 v$ k8 p: o/ p9 Q
" x+ b9 q0 y- P, m- \- unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO);
1 @% P# c% i' u) Z
$ H* S) Q/ K- n }* Q2 n, M% Z- #endif
复制代码
; G% n d: `! u! D② fifo.c程序主体
; {; O3 i( ~- U% O* @- L: u0 o- ?7 k5 z0 D5 o' r# m
- #include <string.h>3 |# O/ X/ Q4 o: ?4 p. O% J- C! Y
- #include "fifo.h"% t" t& I! `2 f2 Y. e& C
% ]+ l4 q. W" v7 B
: ]9 I. c" L# c% n& h: [- /********************************************************************//**8 Y- |/ Q- D/ `# g+ b! @1 s; M0 Z
- * @brief FIFO初始化
3 p0 y7 u! l* _6 u3 f - * @param[in] pFIFO: FIFO指针5 T" r5 r' X2 [; Q
- * @param[in] pBuff: FIFO中缓存
6 U! c/ b3 ?! p' @/ v* H' x - * @param[in] elementBytes:FIFO每个元素的字节数
2 i2 \5 P- F* y: V) ^ - * @param[in] depth: FIFO深度& F, O1 ]' R3 L% u! E
- * @return None
' a' ]' V0 j3 s - *********************************************************************/" w3 S ?# x" P
- void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
$ n; y; u: n+ W" O5 I" [ - {! m, T, d/ v K
- pFIFO->Buff = pBuff;
+ @6 I; D8 ~' E/ M - pFIFO->ElementBytes = elementBytes;+ w% Y* a, m3 g9 H& s/ c
- pFIFO->Depth = depth;6 G, J/ l/ @3 Q& @
- pFIFO->Head = 0;
1 S* n0 o& ^' F! _' A - pFIFO->Tail = 0;
( {* @& ] S0 D8 G* {* x - pFIFO->Counter = 0;1 p! K! m/ V# a5 Z x1 k/ E
- }
E& Y' j! q8 h. ]; P0 A
7 u7 V1 p: G w1 y+ U- /********************************************************************//**" o+ |9 Q9 U# Q: y( N5 b
- * @brief 判断FIFO是否为空
q0 I3 s7 B9 P, G7 b - * @param[in] pFIFO: FIFO指针4 f& r+ T: K: G" G9 M0 ]
- * @return 1-TRUE or 0-FALSE
! ]' i9 b; `( q, D- o9 Q3 y - *********************************************************************/
8 M! D0 Z6 [, ^! x; {' v% P$ l - unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
# H* b5 \7 E* J% Y1 `% v - {' ]: v) S# [3 y( f& g
- return (pFIFO->Counter == 0);5 Z7 S' [4 [' v5 v3 P
- }
) }4 m7 z' b0 Y, @) u% N - ; d/ M! G# R# m& d2 ?3 x
- /********************************************************************//**
$ s8 |4 c+ s, \% T3 n; ? - * @brief 判断FIFO是否已满. \1 W( X$ _! A* g
- * @param[in] pFIFO: FIFO指针) A7 X2 G& y0 m8 _' ]6 S
- * @return TRUE or FALSE# t: G1 M* i# s! U ?8 t
- *********************************************************************/
' n6 {" P6 `0 h - unsigned char FIFO_IsFull(FIFO_Type *pFIFO), P' N. p# f6 W% q; h$ `1 [
- {) [! k1 o0 z& s. M. z) y( ?
- return (pFIFO->Counter == pFIFO->Depth);. k& ^, M6 N( d8 E0 ~( }! j
- }
; g7 r4 W" U/ m& y: o9 N' c4 v
' ^9 o1 U! j3 a- `- /********************************************************************//**
4 J2 O K: Y! N; N3 V/ Q( c - * @brief 向FIFO添加一个元素6 x! L. `: m, q
- * @param[in] pFIFO: FIFO指针
: ]' g% x7 W$ a Q+ k, f. E - * @param[in] pValue: 要添加的元素
1 V% q- k! j7 X - * @return 1-TRUE or 0-FALSE
5 ?: n: F6 C( b% N5 w: w& d: a1 n - *********************************************************************/
; m, j$ R+ ~" r; ~. j - unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
E& o; h0 E5 j* b6 o - {
, q: U+ N n5 e; P - unsigned char *p;' b4 X) A% u0 }+ b6 i4 n
9 l! H' N2 o" V% a" Q7 D& n- if (FIFO_IsFull(pFIFO))
2 |: O1 o8 m$ e8 A6 @ - {! y5 j/ V" ~# V" M3 y1 |7 u
- return 0;
Y( R' S& Q+ ?) N3 k - }4 ~. }' e, x; K9 X
# o5 ~# t8 ^0 V, ^0 D- p = (unsigned char *)pFIFO->Buff;4 U8 ^0 Q Q) i8 n5 W0 _
- memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);8 L: R9 ]4 N" M% j# O
- 4 ]2 t d9 }) J7 y0 S7 A
- pFIFO->Tail ++;- W5 P* J/ h; P8 A* R( C- N( o
- if (pFIFO->Tail >= pFIFO->Depth)
: p* g/ {9 ?( S/ X5 O - {8 k4 ?& Q2 f% h$ \1 W( K
- pFIFO->Tail = 0;$ L$ R3 N4 a2 p5 f
- }7 }* l* v/ s. B2 p% v+ V
- pFIFO->Counter ++;
7 [5 |" w$ a1 H7 Z4 I) M, Y: f - return 1;
" Y) ?2 b) _( i - }
! N; l) h7 S) s X0 ?4 n2 x/ X$ u - * }/ w- m W/ {. |
- /********************************************************************//**
- e; w( ^9 P: d" s - * @brief 向FIFO添加多个元素
5 k6 V) d5 f8 @1 ]: Z% O - * @param[in] pFIFO: FIFO指针. l7 p4 d6 T2 U8 f Q/ L
- * @param[in] pValues: 要添加的元素指针
! ^1 n0 G" ]/ k5 | - * @param[in] bytesToAdd: 要添加元素的长度
z& v5 V4 w" U5 d4 g8 D( M4 _1 T - * @return 实际添加的元素个数
8 W( j1 F ^# E# K - *********************************************************************/0 M @& W- x& U6 F
- unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)# K3 V+ l, ]! e
- {
; X6 G( @% v7 I( `/ s+ q - unsigned char *p;- W/ [0 i- e* b! q" R* D4 H5 i
- unsigned int cnt = 0;
! R! C* U; \+ @' y% i - . ]) i. N* y3 @" m3 T/ x
- p = (unsigned char *)pValues; y6 S- e" I7 b2 I0 y
- while(bytesToAdd --)
' y* ?2 f1 e: X' u; ]# O9 r - {
# j1 n; p9 W# J( K' U% N6 g - if (FIFO_AddOne(pFIFO, p))9 m# J. @) N& s5 `% m: s4 P i
- {
6 i) J+ R) T$ C2 [8 i5 E1 J - p += pFIFO->ElementBytes;
: a1 z# B, |6 G/ Y: W3 C3 U1 p - cnt++;7 O) j( \/ e" O$ r/ U% B2 v
- }6 q- d! C a8 i
- else! Q$ e! T7 @5 V7 i, ~4 Z
- {
% O) ~2 S, A' g- X. Z - break;, ?4 g( C# k+ h b% J7 }# P8 n' E
- }* j2 x- L2 m7 e# p. ^ o2 C0 p
- }
5 D) ^+ W, E. u. i- h - 6 h+ S" R7 i2 y" _ c( ~5 L- Y
- return cnt;
/ a# q& g& S4 r - }
$ l7 v9 {* G- `
) S& `* C3 v8 _6 V6 N- /********************************************************************//**$ D& C6 ], m$ V' \* |
- * @brief 从FIFO读取一个元素
$ [# R$ S" r- ^: s - * @param[in] pFIFO: FIFO指针
: N. b! j% y& f5 W: W0 B$ g+ M/ A - * @param[in] pValue: 存放要读取的元素指针
4 u$ N& u3 y( H - * @return 1-TRUE or 0-FALSE
6 o4 v# g, \' d3 L. C( C0 S - *********************************************************************/2 \4 U: h! {) e; d. q: s
- unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)
4 W5 F+ b B4 Z0 o7 N. z - {
- E. ~) o* v s2 d! r - unsigned char *p;% \' L) p' D+ K1 y0 \- ^4 r
- if (FIFO_IsEmpty(pFIFO))
8 l1 i) d; U7 z; h8 F1 F - {9 g$ h+ w5 a1 Y7 ]9 x% n
- return 0;
/ w2 \& K) b+ a/ F( Y# m$ e - }. T1 _- a* r; D5 K# ?1 n" f- p
- 1 {$ N8 l( _! M, U, j# p& _
- p = (unsigned char *)pFIFO->Buff;
3 ^% |" N# b% }8 g. |5 E4 [ - memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);
5 q5 C8 f+ N2 H& w' z
/ W% w! n8 U# W& Q& [- pFIFO->Head ++;
' C, Q: k9 v! n5 f2 p% b7 u; u - if (pFIFO->Head >= pFIFO->Depth)" v( V# @4 {0 d( `
- {
9 d7 G$ F$ @5 j$ L2 a - pFIFO->Head = 0;9 {, {0 B+ [- V2 ^) v7 f
- }6 }& Z! H/ L$ S1 s6 y m
- pFIFO->Counter --;5 B" S1 C" i8 Q Q6 u- u9 _
" ^2 R+ A2 ^4 K( j! K+ E: e- H- return 1;
8 i# b9 N1 f3 L9 | - }& p w! A, x0 @. ~2 b* R
4 F/ q- c8 ?5 |7 o- /********************************************************************//**& k. t3 w: X! s
- * @brief 从FIFO读取多个元素
/ ]4 `7 h: i* a; W, p - * @param[in] pFIFO: FIFO指针
) \, N/ Q- c5 F - * @param[out] pValues: 存放要读取的元素指针' b/ o/ M4 ^- ?! N8 U9 D
- * @param[in] bytesToRead: 要读取的元素长度7 |. |) s, `) v4 D J8 a: s; }
- * @return 实际读取的元素个数, c" L* \7 r2 Z; t) t9 u- M
- *********************************************************************/
3 _- U7 M; V4 o- s - unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)# u( H6 |3 g- i- z; U/ v: I8 `( l+ \
- {% V5 e( M+ y" R6 N( a
- unsigned int cnt = 0;8 z8 h7 Z9 C: ^4 m
- unsigned char *p;
4 _7 G. R4 \5 G. t - + }4 k; U9 F2 H" b$ H
- p = pValues;
$ w7 J3 S, L. b5 T6 E# z e* } - while(bytesToRead--). F2 R# _+ ^) p _- U; a
- {
; t: N" o- |% e4 x% }- A9 c - if (FIFO_GetOne(pFIFO, p))
! M/ a* I1 F1 o' p# U' y: R - {: J# p2 O& [. y( K0 b& s& L
- p += pFIFO->ElementBytes;
% H9 }7 `$ e( L - cnt++;
* l7 x" g/ J# i - }
! i3 ?. j( n/ \- w. g: ]5 Z. V1 s - else; P) M& q9 M! k! X
- {2 t2 j% q' Q8 y. b
- break;
0 N/ }& B" Z" t - }
+ P5 t1 W0 B1 V% ]1 j8 }) q - }
* {5 ^( X$ M) W% L) N9 N
4 t& E) ^0 p* u5 q9 v- return cnt;
- g6 V# T- d- N q0 r* v A* \ - }
5 V- U: ?6 [. K0 Q; h5 i* [ - 1 |% `9 K2 m/ u. ~1 Z; P- Z+ ]1 C
- /********************************************************************//**7 q& N5 u s- L" Z- m7 K! B
- * @brief 清空FIFO
3 Y* d9 c4 J9 W( D U& \ - * @param[in] pFIFO: FIFO指针1 C( J5 U" I" V; s
- * @return None$ e) @" _9 S. d# i: ?7 t4 f5 V7 S
- *********************************************************************/
! {$ h9 m a$ S( ]. q! O. A U - void FIFO_Clear(FIFO_Type *pFIFO)
+ z+ D" n' [$ `6 P4 S - {
) ]- |# ^' ]2 i+ p4 V4 i - pFIFO->Counter = 0;
# z2 q; Z1 K- C9 y* E9 s! |7 U+ c z - pFIFO->Head = 0;4 y) r9 x0 V- p
- pFIFO->Tail = 0;% \* |) v0 v. S: _
- }
复制代码
4 ]2 O* A+ o5 z ③ 串口初始化, m# Y- n9 ^% s5 J6 C) y& C+ P
- static void MX_USART1_UART_Init(void)$ I- S3 B4 g0 R; v3 ~8 w
- {( p0 ]0 d+ p. Z. J. P V
- huart1.Instance = USART1;% J; x- H7 P2 l' n
- huart1.Init.BaudRate = 9600;
3 R4 g0 s8 t% o - huart1.Init.WordLength = UART_WORDLENGTH_8B;
; R' O" M3 h9 h- c5 m7 v7 j3 @' ^ - huart1.Init.StopBits = UART_STOPBITS_1;* E0 \% Z3 r7 m. J
- huart1.Init.Parity = UART_PARITY_NONE;
) ?1 i( ^% M& F8 m6 V- @ - huart1.Init.Mode = UART_MODE_TX_RX;+ |6 T/ ?$ B$ z' x
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
; Q ~2 ~ F3 A/ } - huart1.Init.OverSampling = UART_OVERSAMPLING_16;6 [' d h, b* h$ R% ~
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
9 w( s% e- S* H5 r - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
5 W5 \' [' u$ B: j - if(HAL_UART_DeInit(&huart1) != HAL_OK)3 d6 g, d+ r9 C" a8 G+ A
- {( O, n& ?- W& E" P+ S
- Error_Handler();
2 a- l0 P7 N8 o! Z: ^* [3 c - } 2 g/ q/ K- P- X- W6 a3 I1 P! Y: ~
- ( X3 G, V8 N; w: L! ~/ Y0 L
- if (HAL_UART_Init(&huart1) != HAL_OK)
3 F& J7 o8 |4 B% g7 O. Y - {" h, ]9 A# B0 ?5 t3 x' X6 h
- Error_Handler();6 u8 C S8 ~6 U( D
- }* y& s7 X, N5 C
- : {( F! A- @* x5 Z9 |: f( d
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
O7 a4 P ^; Y& G - /* USER CODE BEGIN USART1_Init 2 */; C3 q! E R+ I7 Z
- if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK): z; G: j3 p- m5 K9 c! f
- {0 {" V: s, b( a3 z% Q! ~; m
- Error_Handler();
, ]: d+ b/ u2 `/ q' Q& V: y( {$ N Y - }
4 |( r' p. M$ k -
" o1 l, t8 K0 _/ t" o3 U- X - }
复制代码 2 R( z+ |5 U; G
④ 接收空闲中断
$ o) l4 _/ l4 Z- void USAR_UART_IDLECallback(UART_HandleTypeDef *huart) X- s& z. m5 b* u- P. u" z# V7 K
- {: U, z( T0 r: @+ P. k7 s# t4 _
- HAL_UART_DMAStop(&huart1);
* V& E, u b4 q2 |* ?2 |" O. T
, m& h0 ]$ ]: ~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
-
# q+ L% B+ W$ c( b; D& \ - FIFO_Add(pfifo, aRxBuffer, data_length);, b; I* Y5 r; M5 t' B
- data_length = 0;; v I0 e4 L8 S) `
- HAL_UART_Receive_DMA(&huart1, (uint8_t*)aRxBuffer, RXBUFFERSIZE);
! V+ `& H, P) F* M - }
$ `' K6 p' C- O( R2 I4 k/ L0 v - 9 } P+ Z6 |( `6 ]% L
- void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
6 C0 o8 W! P. @$ v& | - {
: q1 g8 B9 m+ v# w6 M. H - if(USART1 == huart1.Instance)
0 @" d( i7 F7 ` y T - {6 t2 i! n) s: n e3 r2 ]
- if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
5 g6 M7 R) f- }0 O) Q - {! ]! o4 Y/ w# N$ s0 t) _) N1 y
- __HAL_UART_CLEAR_IDLEFLAG(&huart1);4 E: T3 @* G0 P0 F# k
- USAR_UART_IDLECallback(huart);6 O9 X7 x- n3 H$ n/ v' N3 s$ ~& F
- }0 Z' [0 [' }% |% W7 k( s
- }
& v8 q) Y$ Y8 k& j h# g3 U$ u" w - }4 r: S- Y4 v4 z' L0 |
9 G! O1 f4 |9 ~; w# { r- /**
2 Z4 N7 p3 s8 H! X - * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
4 O. n3 K5 ~" y. P [! v0 t8 } - */
4 H" E: h: j2 R3 ?2 ]1 ]" v0 ~" Q - void USART1_IRQHandler(void)
# y; u# f' q8 X( } - {
% O" z9 P a0 y' z - HAL_UART_IRQHandler(&huart1);8 P* v: Q) j8 o& p% a& H
- USER_UART_IRQHandler(&huart1);1 p2 \" |6 N5 h" O
- }
复制代码 ; Y D- Z& S2 A
⑤ 主函数调用:% O; [9 e# E& x6 F$ R1 v0 Y
- #define TXBUFFERSIZE 30
" f' d: O U9 M - /* Size of Reception buffer */
" F$ W( ~0 z, C; W - #define RXBUFFERSIZE TXBUFFERSIZE
. {# P: h2 @% { - #define RXFIFOBUFFERSIZE TXBUFFERSIZE * 5- p1 G2 Z3 Q$ a! | u
. ]4 |; ^ E; l/ q' \ X7 f" \- : q( y# X' a# g% z; h+ R6 @0 @
- uint8_t aTxBuffer[] = " ****UART_TwoBoards communication based on DMA****";
+ n7 j" N& M; x( o2 v" K
$ ]0 i1 Y. M5 E8 F) N6 ~5 }& K- /* Buffer used for reception */
1 S2 v$ |& S. n5 B- O4 h$ @ - uint8_t aRxBuffer[RXBUFFERSIZE];$ q7 J, v( @+ v3 |2 ^9 P
* {1 y/ |4 C( q- uint8_t aRxFIFOBuffer[RXFIFOBUFFERSIZE];+ K8 u, ^1 J& T4 K7 W: F
- FIFO_Type fifo;
9 n. c! i1 n0 o9 b! ], y - FIFO_Type *pfifo;
3 Q; ]$ q5 \8 `6 j# R - , g2 W. e5 |1 C6 U0 q
- int main(void)
4 x( @( d* m; E" p - {3 K4 ]7 x. ]* g& W" J
- /*此处省略硬件初始化*/
, x. E0 [6 {# D$ E }% R3 }/ i - if(HAL_UART_Transmit(&huart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 200)!= HAL_OK)
- o0 C+ e# `$ A$ R1 J { i - {
% T; I% C E, ^8 F( Z' v9 b' n2 D - Error_Handler();
1 s L. r" l4 k+ x: |6 |/ ^1 @7 C8 e - }& \% r0 t9 J: c" s; [) p
- 2 `0 z9 L \7 s3 q2 }- @
- pfifo = &fifo;
; C Z4 p1 b! @( h( u
8 O9 f1 y" L0 S- FIFO_Init(pfifo, aRxFIFOBuffer, sizeof(uint8_t), RXFIFOBUFFERSIZE);
0 Q! U6 F) o& ?. M j$ [( h - ) z5 t) }! ]7 @0 h/ C' H2 L
- while (1)/ Q4 e/ h9 d7 [1 Q. f% q. k
- {
3 Y" x) z0 u- {3 u& F3 Q - /*一次接收的缓存,重新发送*/; b6 `6 N) V! R' s$ x' c
- if(!FIFO_IsEmpty(pfifo))- I. q9 n$ J4 d1 ]5 J2 z! G! }
- {
) I6 r. H2 r; s; S - uint8_t a[100]; //存放读取fifobuffer的数据
" I% {- P2 F9 P - int i = pfifo->Counter;//先保存接收缓存的数据个数
+ q3 S! h& z: x - FIFO_Get(pfifo, &a, pfifo->Counter);
, q: z; {# J( z1 \# W) l4 ^ - HAL_UART_Transmit(&huart1, a, i, 200); //将接收的缓存数据再次发送,判断有无误码率, P1 A( F& K* Z% f& h! X1 q
- } Q& P( [- C1 Y. ?! L
- }& x9 c$ G7 Q X7 ?; j
- }
复制代码 & v: M' M0 D& @# x% M5 U
测试成功!可以在主函数对数据进行处理,不用担心缓存的覆盖!
, C/ j/ P9 H% K! ~, O' X8 N, J" J3 B9 n* @
. 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
/ F, x% k; B. D' j1 X( R2 h
5 _5 z/ f" a$ p9 J h
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 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
|