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

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

[复制链接]
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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版