PC通过串口助手如何给单片机发送小数,单片机接收后如何处理?

两种思路,供参考。
1. 原始字节
按原始字节数据发送,这也是我个人比较倾向的方式。首先,位、字节和字节流本身没有任何意义,如果按约定的方式去解析,才能有具体的含义。
用什么约定方式呢?使用符合IEEE 754的浮点数标准,每个浮点数为4个字节,按标准解析就可以了。
其实这个标准,包括STM32在内的很多微控制器,都是支持的,内部的表达方式都是一致的,而且效率很快。
技巧就是定义好一个联合体,这一步很关键:

  1. union ByteDouble
  2. {
  3.     float x;
  4.     struct SB
  5.     {
  6.         uint8_t b3;
  7.         uint8_t b2;
  8.         uint8_t b1;
  9.         uint8_t b0;
  10.     }bb; 
  11. }bd;

复制代码

然后在USART的串口中断中,用4个uint8_t获取这四个字节,最后用float表示出来。

  1. //获取数据中断处理函数
  2. void USART1_IRQHandler(void)
  3. {
  4.     
  5.     if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//Got Data
  6.     {
  7.         USART1_RX_BUFFER[USART1_RX_CNT++]=USART_ReceiveData(USART1);
  8.     }
  9.     else if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)
  10.     {
  11.         //Clear USART_IT_RXNE Flag
  12.         USART1->DR;
  13.         //Clear USART_IT_IDLE Flag
  14.         USART1->SR;
  15.         //Process Receive DATA Here
  16.         ////////////////////////////////////////////////
  17.         //Example:
  18.         //printf("%s\r\n",USART1_RX_BUFFER);
  19.         bd.bb.b0=USART1_RX_BUFFER[0];
  20.         bd.bb.b1=USART1_RX_BUFFER[1];
  21.         bd.bb.b2=USART1_RX_BUFFER[2];
  22.         bd.bb.b3=USART1_RX_BUFFER[3];
  23.         printf("%f\r\n",bd.x);
  24.         ////////////////////////////////////////////////    
  25.         //Finally Clear Buffer
  26.         memset(USART1_RX_BUFFER,0x00,USART1_RX_CNT);
  27.         USART1_RX_CNT=0;
  28.     }   
  29. }

复制代码

测试如下:
 
这个是浮点数的表示形式,123.456按IEEE754的规范,表示成十六进制就是42 F6 E9 79。

然后使用串口程序发送给STM32:
 
两个注意的地方:
a. 浮点数是近似表示,所以你看STM32解析的是123.456001,而不是精确的123.456,这并不违反IEEE 754标准,尤其是涉及到最后一个bit的四舍五入方法,在IEEE 754 中并没有明确规定。
b. 字节顺序和对齐。你所有的工作只是定义好联合体,然后填充好联合体,STM32会自动替你完成转换。不过需要注意的是,一些上位机采用的是大端对齐的方式, 发送的字节顺序会相反。

2. 字符串方式
如果是字符串或者其他方式发送,那就可以自定义一套转换机制,甚至你的上位机在发送2/5的分数,或者40%这样的字符串,都可以解析为0.4的浮点数,这种方式的灵活度非常高,但是对编程要求更复杂,而且相对而言,比较占用MCU的CPU时间和Flash。

#include<stdlib.h>    // 使用 atof()函数 需要包含此头文件
#include<stdio.h>
int main()
{
double d;
char str[] = "123.456";
d=atof(str);
printf("string=%s,double=%lf\n",str,d);
return 0;
}

转自http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=615818

猜你喜欢

转载自blog.csdn.net/louyangyang91/article/details/83105000