美文网首页
串口传递浮点数

串口传递浮点数

作者: 光头不光还亮 | 来源:发表于2020-08-04 18:08 被阅读0次

串口传递浮点数2016-01-09 10:29:47

原文网址:http://blog.tianya.cn/blogger/post_read.asp?BlogID=991984&PostID=23898227

前段时间应师兄要求,要通过单片机串口实现Modbus协议,在看了协议的内容后写好了程序的框架,然后根据不同的协议功能码分别实现不同的功能,比如对下位机分别读取或者写入线圈状态(位状态)、二进制数据以及浮点数等。其他的数据格式挺好实现,但怎样互相传递浮点数据却让我考虑了一番。

  串口通讯中传递的数据格式不外两种:ASCII码(即可见字符形式)和二进制数据格式(对应Modbus协议中有ASCII模式和RTU模式)。最初的想法是把浮点数的各位分别提取出来,保存成一个各元素都是ASCII码的数组,然后通过串口发送出去,对方接收到这个数组后再相应地组合成原来的浮点数。这是以前写过的一段代码:

  //################################################################

  // 函数名:void Float2Char(float Value,char *array)

  // 描 述:将浮点数的各个位的数值转换成字符串,通过串口发送至上位机显示

  // 参 数:float Value为欲转换的正数浮点数值,转换结果保存在字符数组*array里

  //################################################################

  void Float2Char(float Value,char *array) 

  {

   Uint16 IntegerPart;

   float DecimalPart;

   Uint16 i = 0;

   Uint16 j = 0;

   char temp;

   //分离整数部分与小数部分:

   //整数部分保存在IntegerPart中

   //小数部分保存在DecimalPart中

   if (Value>=1)

   {

   IntegerPart = (Uint16)Value;

   DecimalPart = Value-IntegerPart;

   }

   else 

   {

   IntegerPart = 0;

   DecimalPart = Value-IntegerPart;

   }

   //转换整数部分

   if (IntegerPart == 0)

   {

   array[0] = 0+48;

   array[1] = '.';

   i = 1;

   }

   else

   {

   while(IntegerPart>0)

   {

   array[i] = IntegerPart%10+48;

   IntegerPart = IntegerPart/10;

   i++;

   }

   i--;

   //修正转换结果的顺序

   for (j=0;j

{

temp = array[j];

array[j] = array[i-j];

array[i-j] = temp;

}

i++;

array[i] = '.';

}

//转换小数部分,此处设置最多转换到第四位小数

i++;

array[i++] = (Uint16)(DecimalPart*10)%10+48;

array[i++] = (Uint16)(DecimalPart*100)%10+48;

array[i++] = (Uint16)(DecimalPart*1000)%10+48;

if (5 == i)

array[i++] = (Uint16)(DecimalPart*1000)%10+48;

array[i] = '\0'; //结束符

}

// End of line

这段代码没有考虑负数的转换,要转换带符号数只需加入符号判断后将正(负)号标志放在数组的第一位即可。这段函数用起来挺好用,但是这种方法有很多不完善的地方,比如要预先设置字符数组*array的大小以足够存储转换后的各位,小数点位置不确定,给接收方还原数据带来了麻烦。

硬件存储浮点数,统一的标准是IEEE754标准,因此更好的方法是通过这个统一的标准来实现串口传送浮点数据的转换和还原。嵌入式硬件使用的float型数据即单精度32位浮点数格式,这在一般应用中已经足够。IEEE754规定了32位数据的格式,分别规定1位符号位、23位尾数位和8位指数位(不知有没有记错?)。比如浮点数34.9,IEEE754标准十六进制显示是0x42 0x0B 0x99 0x9A,二进制显示则是 0 10000100 00010111001100110011010。我最初的想法是根据这个标准规定的各部分位数,写出转换和还原的代码来;但这样确实太麻烦了。因此何妨直接借助编译器来实现这个转换??这样多方便啊

以下的代码我没有直接写,直接借用了这篇博客文章(http://blog.sina.com.cn/s/blog_4b94ff130100ejyb.html)里的程序:

/*******************************************

函数名称:Float2Byte

功 能:浮点数转换成字节型数组

参 数:入口参数floatNum,欲转换的浮点数

返 回 值:byteArry,转换后的字节数组

********************************************/

void Float2Byte(float floatNum,unsigned char* byteArry)

{

char* pchar=(char*)&floatNum;

for(int i=0;i

{

*byteArry=*pchar;

pchar++;

byteArry++;

}

}

/*******************************************

函数名称:Byte2Float

功 能:字节型(16进制格式)转换成浮点数

参 数:入口参数*byteArry,转换成的字节数组,每四个字节转换成一个单精度浮点数

返 回 值:转换后的浮点数

********************************************/

float Byte2Float(unsigned char* byteArry)

{

return *((float*)byteArry);

}

// End of line

将以上的代码应用到MSP430单片机的串口通讯中,成功实现了430单片机与PC机通过串口进行浮点数据的传送。PC机的串口发送和接收代码,可直接根据上述程序修改。

后来我想将Modbus协议移植到TMS320F28x的DSP上,但上述浮点数转换还原代码却不能正确运行。经调试后很快发现问题,MSP430单片机的开发环境IAR C430里规定的Char(Unsigned char )类型是1个字节(8位),而28x的开发环境CCS里规定的Char(Unsigned char )类型是双字节(16位)。知道这点后,改动起来也很容易:

//定义一个unsigned char型的临时数组,用来保存接收到的十六进制字节

unsigned char temp_char[2];

float FloatNum;

//将接收到的信号参数解码,按IEEE754浮点数标准还原

//假设DSP的SCI接收到的4个字节依次保存在RxBuffer[1]~ RxBuffer[4]里

temp_char[0] = RxBuffer[2]<<8 | RxBuffer[1];

temp_char[1] = RxBuffer[4]<<8 | RxBuffer[3];

//还原成原来的浮点数

FloatNum = *((float*)temp_char);

好了,问题解决了。

https://blog.csdn.net/kaobushangjiugundan/article/details/51352614?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-4-51352614.nonecase

相关文章

  • 串口传递浮点数

    串口传递浮点数2016-01-09 10:29:47 原文网址:http://blog.tianya.cn/blo...

  • 上下位机浮点数的传输方法

    嵌入式产品开发经常会用到串口等接口进行上位机和下位机之间的数据传输,那上位机和下位机是如何通过串口进行浮点数...

  • Arduino 到 Blender 的动作捕捉的代码

    整个架构是: Arduino 读取 4 个电位器的模拟电压值,通过 ADC 采集并转换为浮点数据,通过串口发送给上...

  • Android串口通讯

    串口通讯的步骤: 1.打开串口。 2.串口处于监听状态 3.想串口写入数据,串口接收到数据返回数据 串口的一个基本...

  • Xshell 中使用 rz / sz 命令

    在 linux 中 rz 和 sz 命令允许开发者与主机通过串口进行传递文件了。 sz:将选定的文件发送(send...

  • 关于串口格式与报文格式

    《串口硬件分类》中已经说明了几种串口的类型,并在《串口通信协议》中说明了几种串口协议形式,这里就常用的串口协议进一...

  • 树莓派串口通信

    树莓派的串口默认为串口终端调试使用,如要正常使用串口则需要修改树莓派设置。关闭串口终端调试功能后则不能再通过串口登...

  • 串口编程

    串口连接界面 主要控件 打开串口 自动获取串口列表并显示 初始化串口 写入卡片 插入打卡记录并显示打卡成功

  • Android平台的串口通信技术

    概念 串口通信 概念;串口通信(Serial Communications)按位(bit)发送和接收字节。串口可以...

  • 使用socat虚拟串口

    1、下载socat 2、虚拟串口 3、使用串口 根据步骤2创建的串口名称链接串口、2步骤进程需一直开启

网友评论

      本文标题:串口传递浮点数

      本文链接:https://www.haomeiwen.com/subject/ynnwrktx.html