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

stm32串口发送16进制字符和16进制数的区别和具体实现方法

[复制链接]
Terry-351571 发布时间:2017-8-23 23:07
在调试一个stm32串口通信时,下位机设置好的发送方式采用串口助手接收后已经可以正常离线解包。但是由于需要实时解包并存储,因此写了一个实时解包存储的上位机,通信正常后接收的数据一直有误。经过单步调试,发现单片机发送的数据帧是字符串,并不是16进制数,而在线解包程序直接是对16进制数进行处理的,这就导致的比如16进制的数0xAA(170),下位机发送的是“AA"(字符串),上位机处理的16进制数是41 41(10进制为65*100+65)。查询‘A’的ASCII码可知,‘A’的ASCII码对应的10进制数为65,16进制数为41,也就是说上位机把接收到的16进制字符串当16进制数处理了,所以出错。" i$ [! [4 |* F3 f% G, H7 i5 R

, O! U/ i9 D( V- [   解决方法两个,一个是修改下位机发送方式,将其改为发送“16进制数”,而不是“16进制字符串“;另一个是修改上位机接收方式,收到后将”16进制字符串“先转换为”16进制数“。多次尝试后发现还是修改下位机发送方式较为简单,且比较实用,因为大部分下位机串口发送协议发送的是16进制数。
) p! U- i/ H1 u9 ]) z  n! ~1 u, g6 b- h5 `6 n) O+ e
下面是在stm32中进行两种数据发送的具体方法:
, J2 s1 x: X% P, f! K& T' ?! V2 U
% G0 h" h9 G2 x7 F2 t一、发送16进制字符5 m% I9 o3 _7 s% v+ v
例如我们要发送一个32位的数:uint32_t  temp_send;* g' S$ s: G! J, ?
发送方式如下,将32位的16进制数转换为8个对应的字符分别输出,例如:0xF0123456,将发送“F0123456”字符串:  @4 J2 ^. h3 i
  1. 7 d0 N6 e& p, j% C* j( y2 X
  2. [cpp] view plain copy' w7 J- p7 V' S  N+ _0 e3 G8 W+ V
  3. uint32_t  temp_send;  1 S+ L2 K. z2 m4 `& H
  4. //主函数  - [% R  e* I8 i
  5. int main(void)  
    % X6 P: d9 z. M: m3 R5 J* M' Y( ?% {
  6. {  
    : U3 J3 X$ d  n7 B' N1 K
  7.   while(1)  ( |# g: i& B8 K* c
  8.   {  # q6 g  O! e1 S% h) a# e
  9.    UART4_Putc_Hex(0xAA);//帧头  6 ?! ]/ O+ O. e0 @1 Q6 z. u, w
  10.    UART4_Putdw_Hex(temp_send);   
    / ]  `) E' D* Y0 X
  11.   }  . b3 e( \, O5 b0 A% n' I
  12. }  
    " j! R% ]" w% L; E& G$ b
  13. //子函数  2 t7 \! G, k4 i! X/ A
  14. /**************************实现函数******************************************** , L$ h' P8 w4 d& F
  15. *函数原型:  void UART4_Putdw_Hex(uint32_t dw)
    & d$ q- N1 b+ S( p) C: j% h
  16. *功  能:  RS232以十六进制ASCII码的方式发送32位的数据. & b7 F% ]& G# S
  17.         如:0xF0123456 将发送 " F0123456 " 1 ~6 ^5 s$ ]) @3 C, }
  18. *输入参数:uint32_t dw   要发送的32位数据值
    : n0 l& j8 H- j3 U. @) R
  19. *输出参数:没有  
      g% D  `% N" o. {
  20. *******************************************************************************/  
    $ _* v9 W3 |3 L! t
  21. void UART4_Putdw_Hex(uint32_t dw)  ' x3 H6 ~, R! g3 P) O( B
  22. {  
    ; m  n. H; {: L5 W8 W
  23.     UART4_Putw_Hex((uint16_t) (dw >> 16));  
    2 H4 ]& E. A% ^/ V  `& G( I
  24.     UART4_Putw_Hex((uint16_t) (dw & 0xffff));  & J# y! q; _. x( p( q! z
  25. }  
    / L7 X  f. U6 X+ @7 ?$ P4 ]
  26. /**************************实现函数********************************************
    + o3 \1 ~& n9 z! P/ E$ E! W
  27. *函数原型:  void UART4_Putw_Hex(uint16_t w)
    & R! v. f, K3 B! M7 h+ d9 m
  28. *功  能:  RS232以十六进制ASCII码的方式发送一个字的数据.就是发送一个int % T& C5 W; F1 t# k  `/ \
  29.             如:0x3456 将发送 " 3456 "
    ; ^8 F. K( L' S8 y! T; ]
  30. *输入参数:uint16_t w   要发送的字 1 d" d* k5 R7 ?" N% Q
  31. *输出参数:没有  
    ( s; M( c# T7 g0 P% ?: f
  32. *******************************************************************************/  
    2 d% }# m6 N; k3 C: A9 N) x
  33. void UART4_Putw_Hex(uint16_t w)  
    * ^7 }" ^& y$ p5 \0 m% u
  34. {  5 o# S- E$ J% `9 M( e
  35. //发送高八位数据,当成一个字节发送  ! Q$ r# P% X/ j/ r3 o9 I
  36.     UART4_Putc_Hex((uint8_t) (w >> 8));  & y9 O$ o4 ?5 O1 w1 T: Y
  37. //发送低八位数据,当成一个字节发送  
    , D. {1 U7 q, S
  38.     UART4_Putc_Hex((uint8_t) (w & 0xff));  
    $ y/ p6 Q! q+ ^+ U
  39. }  
    2 a* g. Q7 J: B+ _% S$ z
  40. /**************************实现函数******************************************** & d( m+ Y, O: e& B1 F) U+ E# ^
  41. *函数原型:  void UART4_Putc_Hex(uint8_t b) % v8 D  w7 g2 \2 }
  42. *功  能:  RS232以十六进制ASCII码的方式发送一个字节数据
    * D5 l. g2 H1 t2 y7 Q$ R
  43.         先将目标字节数据高4位转成ASCCII ,发送,再将低4位转成ASCII发送
      X7 }7 q2 j& k( Z. ?+ J
  44.          如:0xF2 将发送 " F2 " 7 e- P/ v0 l: s- i
  45. *输入参数:  uint8_t b   要发送的字节
    9 t, y. u/ E7 |8 Z# Z7 z6 c0 N
  46. *输出参数:  没有  
    ) C3 K* `+ S) I3 u- u" w' t
  47. *******************************************************************************/  
    ) e1 ]2 p- z( E1 a
  48. void UART4_Putc_Hex(uint8_t b)  : R! B# T1 }( l8 m  [, t7 ]
  49. {  
    " k! X  \) U9 Q4 {( f
  50.       /* 判断目标字节的高4位是否小于10 */  
    2 Q2 ?2 W7 m  a+ t, j8 @( l4 T
  51.     if((b >> 4) < 0x0a)  
    9 x. U* e& {3 P5 i7 i' N
  52.         UART4_Put_Char((b >> 4) + '0'); //小于10  ,则相应发送0-9的ASCII  ' O4 |, r0 E. x4 P( @% g% c. D
  53.     else  
    ! C7 J1 R/ v  z( X- P
  54.         UART4_Put_Char((b >> 4) - 0x0a + 'A'); //大于等于10 则相应发送 A-F  
    : K" R2 Y/ r1 B0 `1 b0 B
  55.   3 m, s, O, j! \5 L. O9 o
  56.     /* 判断目标字节的低4位 是否小于10*/  3 a" k. |3 V* t7 L$ U
  57.     if((b & 0x0f) < 0x0a)  
    & W3 L4 s- \, @* r8 u" `& o
  58.         UART4_Put_Char((b & 0x0f) + '0');//小于10  ,则相应发送0-9的ASCII  
    4 a- N- `* y5 R& b5 }; r) N4 h
  59.     else  
    6 C0 c% }. B9 y! A" X5 a
  60.         UART4_Put_Char((b & 0x0f) - 0x0a + 'A');//大于等于10 则相应发送 A-F    R- |  e( l; O- n: A. j
  61. //   UART4_Put_Char(' '); //发送一个空格,以区分开两个字节  9 {$ G: P& f3 _
  62. }  ' a% w1 O; g. I& e
  63. /**************************实现函数******************************************** % \) R7 S  G* D4 N3 g- U
  64. *函数原型:  void UART4_Put_Char(unsigned char DataToSend) 8 c' T+ m6 e4 O" J
  65. *功  能:      RS232发送一个字节
    : l+ `, [- [4 B0 y( f% G5 m1 I
  66. *输入参数:unsigned char DataToSend   要发送的字节数据
    ; L( I% V8 \' X) a3 C6 ~* n" m
  67. *输出参数:没有     1 w, {6 v0 l8 [7 a9 v
  68. *******************************************************************************/  
    8 G4 ?0 }  V. e1 L; K. w: s
  69. void UART4_Put_Char(unsigned char DataToSend)  
    9 [5 w5 |/ z/ E" v6 H) {- w/ F
  70. {  7 D4 I. z  P" V/ I
  71.   TxBuffer[count++] = DataToSend;   
    8 S' p% V" Y5 r: h) @
  72.   USART_ITConfig(UART4, USART_IT_TXE, ENABLE);   
    9 f' e6 X2 k5 H/ g4 O1 v
  73. }  
复制代码

: G9 o+ B( e! L( k6 I; `
) @* i8 d1 X; m/ G1 q9 e  \二、发送16进制数" Z! i: C) b$ F* |3 m" z& V7 p
发送方式如下,需要先将32位的数移位分割为4个字节(1个字节8位)的8位数分别发送,例如:0xF0123456,将发送F0 12 34 56(4个16进制数):
0 Z' A7 Q, }' Q+ n& a, P* I
  1. [cpp] view plain copy! S* x( z9 v% z* K, W
  2. uint32_t  temp_send;  ! F# R. \) B8 Z$ X  v
  3. char ByteSend[5]={0};//发送的字节  
    # H% M# |4 g9 n" r- o
  4. uint i;  - A* g- I6 p' p1 I8 P* `
  5. //主函数  
    # A1 R& F$ h- ^' Y9 _1 t' Y0 e
  6. int main(void)  ) i6 v- j% i5 q/ E( K1 L5 k
  7. {  
    7 _6 o/ B4 J% g
  8.   while(1)  
    * z6 Y" e  O# e
  9.   {  + V: |% n- K4 G8 I5 ^) U
  10.     ByteSend[0] = 0xAA;//帧头,ByteSend的类型为uchar或char均可         
    $ V) E( ^& F8 b% T9 l
  11.     ByteSend[1] = (temp_send>>24) & 0xFF;//  - w, n  w3 _* ^" i, F0 U: g! _
  12.     ByteSend[2] = (temp_send>>16) & 0xFF;  % B# z& [4 a5 [( ?' g
  13.     ByteSend[3] = (temp_send>>8) & 0xFF;    a, J) |  S5 }- _1 W2 e
  14.     ByteSend[4] = temp_send & 0xFF;   
    ! L) C4 W3 u5 T
  15.     for(i=0;i<5;i++)  
    . c9 L1 k9 c% [; H; w9 p; X3 z1 Q
  16.      {   
    $ p2 l- ~0 L3 z. ~7 z* \" j
  17.        UART4_Put_Char(ByteSend[i]);  5 h6 ]  D6 V: j# k! ?( Q! g3 N4 L
  18.       }         1 d, r' o7 O6 v' u- c) |3 s
  19.   }  , l+ n" w9 z& q" i* }: b
  20.   
    ! e& Y# ~1 G6 [! J: E
  21. }  0 n9 j( H2 e+ B5 \3 Z
  22. //子函数  . O; \8 O) B3 d- g/ w* ]
  23. /**************************实现函数******************************************** + s9 u/ N) G' n+ ~2 {3 D0 j
  24. *函数原型:  void UART4_Put_Char(unsigned char DataToSend) % q- e3 ~" u5 `# a' X
  25. *功  能:  RS232发送一个字节
    2 `7 G0 h  d+ H
  26. 输入参数: 3 {) i* [- Y6 p1 b3 w
  27.   unsigned char DataToSend   要发送的字节数据 3 K5 b7 t" z# U1 u  @' L' ?5 Y: B
  28. 输出参数:没有  , y: o- i( i9 Z) @
  29. *******************************************************************************/  0 z8 \5 L% x: j# C
  30. void UART4_Put_Char(unsigned char DataToSend)  + I% N$ ~/ l/ k4 l: c" |7 F
  31. {  
    # n& D7 _: z1 W8 C
  32.   TxBuffer[count++] = DataToSend;   
    2 n9 L0 ~: C8 \* c- L1 w
  33.   USART_ITConfig(UART4, USART_IT_TXE, ENABLE);   
    % ?8 P4 s9 |9 X$ ?
  34. }  
    $ q( S# w; k7 `" o
  35. [html] view plain copy  X1 k; |% T/ l( @# X" M) G
  36. <pre class="html" name="code"></pre>  % U, m& w0 s) l
  37. <pre></pre>  
复制代码
2 w( _4 ^( g4 I6 V1 c2 |

3 _" `1 i9 u" ]! v( `6 }# B0 A
5 b. g0 D, I# \$ T  Y0 o
赞 收藏 评论0 发布时间:2017-8-23 23:07

举报

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