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