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

串口助手给单片机发送小数,如何发,单片机收到之后如.....

[复制链接]
watercici 提问时间:2018-5-11 16:58 /
PC通过串口助手如何给单片机发送小数,单片机接收后如何处理?
收藏 评论8 发布时间:2018-5-11 16:58

举报

8个回答
STM1024 回答时间:2018-5-12 13:00:51
本帖最后由 stm1024 于 2018-5-14 10:49 编辑

两种思路,供参考。
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。


评分

参与人数 2ST金币 +6 蝴蝶豆 +5 收起 理由
zero99 + 5
MrJiu + 6 赞一个!

查看全部评分

xiajintaord 回答时间:2018-5-11 17:38:00
#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;
}

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

黑皮男 回答时间:2018-5-11 17:16:00
比如数据buf[]="12.3",则ret = atof(buf).可一获取小数值,或者使用sscanf这个函数来解析也行

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

litter学生 回答时间:2018-5-11 17:01:41
可以定标

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

wenyangzeng 回答时间:2018-5-11 17:34:45
本帖最后由 wenyangzeng 于 2018-5-15 09:42 编辑

浮点小数是32位,当然要化成4个字节的格式分4次发送

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

pythonworld 回答时间:2018-5-12 05:08:15
串口发过来的是字符格式还是二进制格式?解析方式应该不同。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

watercici 回答时间:2018-5-14 09:15:03
stm1024 发表于 2018-5-12 13:00
两种思路,供参考。
1. 原始字节
按原始字节数据发送,这也是我个人比较倾向的方式。

非常感谢,受益匪浅,谢谢!
watercici 回答时间:2018-5-14 09:16:13
pythonworld 发表于 2018-5-12 05:08
串口发过来的是字符格式还是二进制格式?解析方式应该不同。

您能这两种都给我介绍一下吗?

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版