背景 P$ e5 {" T: Y4 ?, q' M9 N
1、单片机串口接收数据处理,这个代码已经过很多项目验证,没有问题。用这个代码帮了好几个同事解决数据接收久了就异常。
/ r# }, v# [$ g, e2、这个代码做到接收和处理分开。避免不必要的处理逻辑问题。
; @; f) Z: G$ i- E& v3 b* I8 D3、也可用于网口tcp,udp,spi,iic等方式。
& N8 \6 H" M$ V% d V8 u
& n: _% p" T& Y4 q2 s! N
; |3 B. i2 {8 G7 n0 n3 p; m; e缺陷 :3 c' K: ]: }2 o: y
1、接收和处理两个缓存区,比较吃内存,不过现在单片机内存大,不是问题。
$ k; W$ `; K5 ~% e( @ ^7 a1 q2、接收和处理分开,响应没那么及时。现在芯片主频都高,可以忽略。( F1 [6 e) ~: a6 _/ N
0 E% E ?4 i+ B, p& m, R. J ?8 B3 J( X! g8 o! j% g0 p5 L! `
实现
* v8 d, f( R* K, d- <font face="微软雅黑" size="3">//缓存区根据实际情况修改
6 M# f* f, e. F2 F" b2 W - #define UART_RX_BUFSIZE 16 // receive# ]4 z T4 Q, e: M G
- volatile uint8_t UART_RXBuffer[UART_RX_BUFSIZE]; // receive" X2 I0 B x7 z# p
- volatile uint8_t UART_RXReadIndex = 0, UART_RXWriteIndex = 0; // receive buffer indexes :
1 n& d7 p7 q! M - volatile uint8_t UART_RXCharCount = 0; // count of received bytes:2 F; y5 ^1 ], g$ i) Z
- & r Z- y6 E& Z2 ?* h$ c
- //根据实际情况修改4 W' U) R: g# y" N6 @5 G
- typedef struct _REC_TYPE1 a" E( s) s( q* P9 c" v
- {
9 |$ L" T& ?, @9 Y" g, C - uint8_t Head;) ^- W9 ]0 H( k3 Z5 w+ M
- //uint8_t OptCode;
# a$ q( F6 c! f! j4 q - //uint16_t DataLen;
* d d$ U& f- d1 g5 L1 Q - uint8_t DataBuf[5];0 Y/ z. ]2 w8 D
9 _: M1 a# L& U/ K, d: r! v- uint8_t Tail;
. D% [# N, ~1 D
; n0 q& j7 Z2 J3 E" q- } REC_TYPE;
: L5 h/ g! m' X
" C8 |: Z: b$ K7 C- typedef union REC_DATA_TYPE
, U( m( \1 |& C4 [# k' _- b; m" e - {
. U) U6 N) a8 h8 I9 y9 ] - REC_TYPE data_type;
( z7 u7 d( v; W -
4 ^& P% h5 }! s7 D! a Z! E - //根据实际情况修改& ]! ^; }9 d8 _/ m% ?% R; a! X8 }
- uint8_t data_arry[16];
4 f R6 }" J! e6 M" @8 V - ) d! g. |, A( w/ m4 Y' u) n
- } REC_DATA; f; d7 h- o H/ `1 r. P
- + c P3 M- J- g% e5 e3 D8 B# u
- REC_DATA uart_rec_buffer;//16byte$ D0 I& m }$ e5 C% _0 i
& E# ~& j: s$ @! j- uint8_t uart_rec_count = 0;3 J3 @: Q- I" B m2 }' r
- uint16_t uart_timeout_count = 0;: n g- A- o: k; d: `/ H3 b
- ) R( p7 B! h* P8 M
' j6 K! ~ a4 L- P* h- //中断接收,根据实际芯片修改
* u$ \, h& Q2 _4 j - void USART1_IRQHandler(void)* d; ?: g2 `7 u. k& I$ e
- {
" }) z9 |. i1 ~$ W; M - if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)* @8 ~: Y. C! H2 w
- {
9 [ j. N7 H! T3 _, ^/ N - USART_ClearITPendingBit(USART1,USART_IT_RXNE);
! _$ c1 H7 n0 A5 z8 Z1 f4 I - , A( @! H" \8 m$ y* x, D6 f
- UART_RXBuffer[UART_RXWriteIndex++] =USART_ReceiveData(USART1);
+ l7 q) W' w- w' B! Z. w - UART_RXWriteIndex &= UART_RX_BUFSIZE - 1;5 E! m% B% ~9 k3 T: W+ U: N$ c) u
- UART_RXCharCount++; h. d* r7 u9 _+ b* R% O4 h
- }
3 j* r4 W: F# t4 _% P - }
& J; l2 r( h1 O' m/ A" |4 O0 E - //读取缓存数据
% c+ N9 b) `8 d: G$ E2 E# h - uint8_t UART_Ci_ReadChar ( void )
' F! S; I( O% L1 f% ^' a - {
5 x1 a& O; S' j& u ^" c0 \ - register uint8_t Byte;
( q5 t- P& _2 d. Y. p -
1 F, D8 d# a. {# p8 ^1 U U" x - if ( UART_RXCharCount )7 |0 }# d) C D
- {
+ w; o x9 j1 \% G - Byte = UART_RXBuffer[UART_RXReadIndex++];
/ ?% E, ?' N9 |; U3 I4 p3 k - UART_RXReadIndex &= UART_RX_BUFSIZE - 1;
+ G5 j4 |/ Z+ W- t - $ {6 y. O6 m! V. m; N) r
- UART_RXCharCount--;
8 ~. w4 P) g, c9 I( Z8 n6 @ - # W$ ]) ~) f& `7 K. N: t
- return Byte ;
\# v' I4 q9 J/ R2 N( } - }
+ a' I6 O7 S* K! j" o0 F u - return 0;& [7 o0 ?7 x2 B# j2 M. o1 d$ T
- }
+ A/ ~& L/ ~: y( F9 T" F; @
K) N4 R1 I, r7 D c) V/ B- void Uart_process_rec_data(void)0 A/ a- O; A8 N6 J7 o4 A
- {
1 ^/ o- x6 [+ \7 A - : Q! o7 K5 t& F) p+ Y! Z
- uint16_t m_ui16Data;
5 k! d/ G6 y% e6 H - 4 d' H$ N6 t, \; r- y: a) g
- if ( UART_RXCharCount )
* u1 U: Z3 F5 `, i f& j9 z1 x - {
1 B9 N# K* [1 [! J$ g - //设置超时初值& q/ _. g# U" B& G3 b
- uart_timeout_count = 50000;1 [' c, c* B% T& @. X1 f* y* L
- uart_rec_buffer.data_arry[uart_rec_count] = UART_Ci_ReadChar();
. l. X% A0 r+ A6 c$ d" G - uart_rec_count++;' O+ s3 [/ A- [% F8 ?$ Q
- }
, }# T3 U1 t9 ~! U* I# Z$ z - //添加超时处理" z8 v/ U8 U0 y
- if ( uart_timeout_count>0 )
4 L) q4 S; v: s8 d2 m. c$ p; ]5 M4 g - {
* ]( c; t2 o1 {- ~2 S - uart_timeout_count--;
Y8 H. C( J1 p* J- m/ h; x - }5 H4 l; W& `! T; d# q
- else. W5 F. A) w$ U+ h
- {
2 s7 W& R% g4 e$ {" |" o - uart_rec_count = 0;
1 e$ q0 }' W5 F - }
' E) {0 `1 \, t/ b - if ( uart_rec_count > 0 && uart_rec_buffer.data_type.Head == 0xff )
0 d# J' @" E# I. P* r" ?2 B - {
: a5 H2 Z e5 d3 ]- N! b - //这里添加类型处理# K) ?, _6 e7 B& H# B# K* r
6 c4 {8 k' {5 V: E3 b2 c- //7是帧长度,根据实际情况修改0 q6 @- [6 e+ }
- if(uart_rec_count>=7)1 Q" I% [% ]6 L6 c
- {) s5 b" B t1 d! Q. r- t, @
- //记得清0
e9 c5 i9 Z1 I0 Q1 a2 P9 k: `9 r2 W+ U - uart_rec_count = 0;1 u7 {1 p' ^& T F, F g$ O
- if(uart_rec_buffer.data_type.Tail==0x00)
2 p2 o9 p5 [: n# m6 c - {
; N' A6 O0 k' I - //数据处理
/ R& z8 y K7 [ - }, `) N( M- _2 x0 `5 {
- : q. K4 {. i! N) a
- }9 F$ ~& w7 _% j( E+ n, O
- }
. X3 T% |8 H2 C) Z8 F( q - else4 r$ c2 R; [( D, b
- {7 J! I' G% F; U5 x8 K2 I! a/ {
- uart_rec_count = 0;
. W, B8 Y. p# h6 W0 L - }
* {/ J3 V$ @* Q% r! \7 ^ - }
8 D: V S4 Z5 R. U$ P$ K- E; V - </font>
复制代码
4 V6 a# U3 N* {& p
$ v+ s% G8 a3 P5 F2 v6 P |