你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

单片机 stm32 接收数据和处理

[复制链接]
STMCU小助手 发布时间:2021-7-22 14:39
背景  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
  1. <font face="微软雅黑" size="3">//缓存区根据实际情况修改
    6 M# f* f, e. F2 F" b2 W
  2. #define   UART_RX_BUFSIZE               16           // receive# ]4 z  T4 Q, e: M  G
  3. volatile  uint8_t      UART_RXBuffer[UART_RX_BUFSIZE]; // receive" X2 I0 B  x7 z# p
  4. volatile  uint8_t      UART_RXReadIndex = 0, UART_RXWriteIndex = 0; // receive buffer indexes :
    1 n& d7 p7 q! M
  5. volatile  uint8_t      UART_RXCharCount = 0; // count of received bytes:2 F; y5 ^1 ], g$ i) Z
  6. & r  Z- y6 E& Z2 ?* h$ c
  7. //根据实际情况修改4 W' U) R: g# y" N6 @5 G
  8. typedef  struct _REC_TYPE1 a" E( s) s( q* P9 c" v
  9. {
    9 |$ L" T& ?, @9 Y" g, C
  10.     uint8_t   Head;) ^- W9 ]0 H( k3 Z5 w+ M
  11.     //uint8_t   OptCode;
    # a$ q( F6 c! f! j4 q
  12.     //uint16_t  DataLen;
    * d  d$ U& f- d1 g5 L1 Q
  13.     uint8_t   DataBuf[5];0 Y/ z. ]2 w8 D

  14. 9 _: M1 a# L& U/ K, d: r! v
  15.     uint8_t   Tail;
    . D% [# N, ~1 D

  16. ; n0 q& j7 Z2 J3 E" q
  17. } REC_TYPE;
    : L5 h/ g! m' X

  18. " C8 |: Z: b$ K7 C
  19. typedef union REC_DATA_TYPE
    , U( m( \1 |& C4 [# k' _- b; m" e
  20. {
    . U) U6 N) a8 h8 I9 y9 ]
  21.     REC_TYPE  data_type;
    ( z7 u7 d( v; W
  22.    
    4 ^& P% h5 }! s7 D! a  Z! E
  23.         //根据实际情况修改& ]! ^; }9 d8 _/ m% ?% R; a! X8 }
  24.     uint8_t   data_arry[16];
    4 f  R6 }" J! e6 M" @8 V
  25. ) d! g. |, A( w/ m4 Y' u) n
  26. } REC_DATA;  f; d7 h- o  H/ `1 r. P
  27. + c  P3 M- J- g% e5 e3 D8 B# u
  28. REC_DATA  uart_rec_buffer;//16byte$ D0 I& m  }$ e5 C% _0 i

  29. & E# ~& j: s$ @! j
  30. uint8_t uart_rec_count = 0;3 J3 @: Q- I" B  m2 }' r
  31. uint16_t uart_timeout_count = 0;: n  g- A- o: k; d: `/ H3 b
  32. ) R( p7 B! h* P8 M

  33. ' j6 K! ~  a4 L- P* h
  34. //中断接收,根据实际芯片修改
    * u$ \, h& Q2 _4 j
  35. void USART1_IRQHandler(void)* d; ?: g2 `7 u. k& I$ e
  36. {
    " }) z9 |. i1 ~$ W; M
  37.   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)* @8 ~: Y. C! H2 w
  38.   {
    9 [  j. N7 H! T3 _, ^/ N
  39.       USART_ClearITPendingBit(USART1,USART_IT_RXNE);
    ! _$ c1 H7 n0 A5 z8 Z1 f4 I
  40.       , A( @! H" \8 m$ y* x, D6 f
  41.      UART_RXBuffer[UART_RXWriteIndex++] =USART_ReceiveData(USART1);
    + l7 q) W' w- w' B! Z. w
  42.                 UART_RXWriteIndex &= UART_RX_BUFSIZE - 1;5 E! m% B% ~9 k3 T: W+ U: N$ c) u
  43.                 UART_RXCharCount++;  h. d* r7 u9 _+ b* R% O4 h
  44.   }
    3 j* r4 W: F# t4 _% P
  45. }
    & J; l2 r( h1 O' m/ A" |4 O0 E
  46. //读取缓存数据
    % c+ N9 b) `8 d: G$ E2 E# h
  47. uint8_t UART_Ci_ReadChar ( void )
    ' F! S; I( O% L1 f% ^' a
  48. {
    5 x1 a& O; S' j& u  ^" c0 \
  49.     register uint8_t Byte;
    ( q5 t- P& _2 d. Y. p
  50.        
    1 F, D8 d# a. {# p8 ^1 U  U" x
  51.     if ( UART_RXCharCount )7 |0 }# d) C  D
  52.     {
    + w; o  x9 j1 \% G
  53.         Byte = UART_RXBuffer[UART_RXReadIndex++];
    / ?% E, ?' N9 |; U3 I4 p3 k
  54.         UART_RXReadIndex &= UART_RX_BUFSIZE - 1;
    + G5 j4 |/ Z+ W- t
  55.         $ {6 y. O6 m! V. m; N) r
  56.         UART_RXCharCount--;
    8 ~. w4 P) g, c9 I( Z8 n6 @
  57.         # W$ ]) ~) f& `7 K. N: t
  58.         return Byte ;
      \# v' I4 q9 J/ R2 N( }
  59.     }
    + a' I6 O7 S* K! j" o0 F  u
  60.     return 0;& [7 o0 ?7 x2 B# j2 M. o1 d$ T
  61. }
    + A/ ~& L/ ~: y( F9 T" F; @

  62.   K) N4 R1 I, r7 D  c) V/ B
  63. void Uart_process_rec_data(void)0 A/ a- O; A8 N6 J7 o4 A
  64. {
    1 ^/ o- x6 [+ \7 A
  65.         : Q! o7 K5 t& F) p+ Y! Z
  66.          uint16_t m_ui16Data;
    5 k! d/ G6 y% e6 H
  67. 4 d' H$ N6 t, \; r- y: a) g
  68.         if ( UART_RXCharCount )
    * u1 U: Z3 F5 `, i  f& j9 z1 x
  69.     {
    1 B9 N# K* [1 [! J$ g
  70.         //设置超时初值& q/ _. g# U" B& G3 b
  71.         uart_timeout_count =        50000;1 [' c, c* B% T& @. X1 f* y* L
  72.         uart_rec_buffer.data_arry[uart_rec_count] = UART_Ci_ReadChar();
    . l. X% A0 r+ A6 c$ d" G
  73.         uart_rec_count++;' O+ s3 [/ A- [% F8 ?$ Q
  74.     }
    , }# T3 U1 t9 ~! U* I# Z$ z
  75.         //添加超时处理" z8 v/ U8 U0 y
  76.     if ( uart_timeout_count>0 )
    4 L) q4 S; v: s8 d2 m. c$ p; ]5 M4 g
  77.     {
    * ]( c; t2 o1 {- ~2 S
  78.         uart_timeout_count--;
      Y8 H. C( J1 p* J- m/ h; x
  79.     }5 H4 l; W& `! T; d# q
  80.     else. W5 F. A) w$ U+ h
  81.     {
    2 s7 W& R% g4 e$ {" |" o
  82.         uart_rec_count = 0;
    1 e$ q0 }' W5 F
  83.     }
    ' E) {0 `1 \, t/ b
  84.         if ( uart_rec_count > 0 && uart_rec_buffer.data_type.Head == 0xff )
    0 d# J' @" E# I. P* r" ?2 B
  85.         {
    : a5 H2 Z  e5 d3 ]- N! b
  86.                 //这里添加类型处理# K) ?, _6 e7 B& H# B# K* r

  87. 6 c4 {8 k' {5 V: E3 b2 c
  88.                 //7是帧长度,根据实际情况修改0 q6 @- [6 e+ }
  89.                 if(uart_rec_count>=7)1 Q" I% [% ]6 L6 c
  90.                 {) s5 b" B  t1 d! Q. r- t, @
  91.                         //记得清0
      e9 c5 i9 Z1 I0 Q1 a2 P9 k: `9 r2 W+ U
  92.                         uart_rec_count = 0;1 u7 {1 p' ^& T  F, F  g$ O
  93.                         if(uart_rec_buffer.data_type.Tail==0x00)
    2 p2 o9 p5 [: n# m6 c
  94.                         {
    ; N' A6 O0 k' I
  95.                                 //数据处理
    / R& z8 y  K7 [
  96.                         }, `) N( M- _2 x0 `5 {
  97.                         : q. K4 {. i! N) a
  98.                 }9 F$ ~& w7 _% j( E+ n, O
  99.         }
    . X3 T% |8 H2 C) Z8 F( q
  100.         else4 r$ c2 R; [( D, b
  101.         {7 J! I' G% F; U5 x8 K2 I! a/ {
  102.                 uart_rec_count = 0;
    . W, B8 Y. p# h6 W0 L
  103.         }
    * {/ J3 V$ @* Q% r! \7 ^
  104. }
    8 D: V  S4 Z5 R. U$ P$ K- E; V
  105. </font>
复制代码

4 V6 a# U3 N* {& p
$ v+ s% G8 a3 P5 F2 v6 P
赞 收藏 评论0 发布时间:2021-7-22 14:39

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版