stm32程序中串口发送以及VC++后台软件接收浮点数所遇到问题的处理总结

一、stm32程序

通过查找网络资料,决定采用函数转换的方式,实现float数转换成char数,再送入modbus寄存器。

首先,在头文件.h中定义:

void float_char(float f,u8 *s);

其次,在源文件.c中增加float_char子函数:

  void float_char(float f,u8 *s)
   {
     u8 *p; 
     p=(u8*)&f;
     *s=*p;
     *(s+1)=*(p+1);
     *(s+2)=*(p+2);
     *(s+3)=*(p+3);
    }

最后,在modbus收发处理函数里增加:

    u8 *Att_0; 
    float Att;
    float_char(Att,Att_0);//将Float数据Att,转换成Att_0的字符数组
    Modbus_HoldReg[192]=(int)Att_0[3]*256+(int)Att_0[2];
    Modbus_HoldReg[193]=(int)Att_0[1]*256+(int)Att_0[0];

说明:Att=4.8414259,在单片机里面为0X409AECF6,正确的是:Att_0[0]=0xF6,Att_0[1]=0xEC,Att_0[2]=0x9A,Att_0[3]=0x40;但是调用 float_char子函数后,发现Att_0[0]=0X60,Att_0[0]=0X12,Att_0[0]=0X00,Att_0[0]=0X20,

通过单独调式发现R2寄存器里面的数据变成了0X409AECF6,可是Att_0就是不正确。stm32程序中串口发送以及VC++后台软件接收浮点数所遇到问题的处理总结_第1张图片

难道是float_char子函数不对吗?在VS2013里面,将程序拷贝进去,cout << uu[0] << endl;的情况下,输出的uu[0]为符号,将uu[0]转换成int,输出的结果的确是0xF6,其他三个字节也是完全正确的。

再通过单片机程序调试发现,Att_0[4],Att_0[5],...Att_0[9]这些变量里面都有值,但是和Att的32位浮点数却不一致。感觉在单片机程序里面,程序在执行时,似乎Att的字节未按照顺序传入Att[0]--Att[3],决定修改程序如下:

 u8 Att_p[4]={0,0,0,0};

 float_char(Att,&Att_p[0]);
 Modbus_HoldReg[192]=Att_p[3]*256+Att_p[2];
 Modbus_HoldReg[193]=Att_p[1]*256+Att_p[0];	 
		
        

 直接用数组的方式,将第一个数组的地址送入子函数的形参中。通过监视串口发送的数据,发现完全正确,问题得到解决,浮点数按照先高后低的方式存入modbus寄存器中。

二、C++程序

在C++中需要将单片机中发送过来的以4个字节形式的浮点数数据进行转换处理,送入float变量。具体程序如下:

float Heading = 0.0;//浮点数变量
char Heading_0[4] = { 0, 0, 0, 0 };

//Modbus接收的数据处理
Heading_0[0] = mySerialPort.RevData[8];//注意接收字节顺序要反过来
Heading_0[1] = mySerialPort.RevData[7];
Heading_0[2] = mySerialPort.RevData[6];
Heading_0[3] = mySerialPort.RevData[5];

memcpy(&Heading, Heading_0, sizeof(Heading_0));
//Heading = ((float *)Heading_0)[0]; //也可行
//Heading = *((float*)Heading_0);    //也可行

cout << "浮点数据:" << Heading << endl;

需要注意的是,字节形式浮点数转换过程中,先从低字节处理开始,需要将Modbus接收的最低位先送入Heading_0[0]进行转换处理。

你可能感兴趣的:(工业控制)