double类型数据通过串口发送到上位机问题

C语言中double类型数据通过串口发送到上位机问题

一、问题引出

众所周知,串口发送数据一次是一个字节,那么如何将一个double类型数据(8字节)通过串口发送到上位机呢?

二、问题思考

首先考虑使用位运算的方式将8字节的数据逐一取出,然后逐一发送,但是没有想到浮点型的数据是不可以位运算的
然后这个时候可以引出联合体了,已知联合体的特性:各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度,那么联合体中变量内存空间共享了,那么给其中一个变量赋值,势必会造成其他变量的值的改变。(这里还需要了解小端存储概念
如下程序所示:

#include <stdio.h>
union
{
    unsigned int  var1;
    unsigned char var2[4];
}data;

int main(int argc, char const *argv[])
{

    data.var1 = 0x12345678;
    for (int i = 3; i >= 0; i--)
    {
        printf("%p : %x \n",&data.var2[i] , data.var2[i]);
    }

    return 0;
}

在上述程序中,定义了一个联合体,虽然我只将var1定义为0x12345678,但是由于联合体变量共用内存,由基于系统是小端存储,因此,连续四字节从低到高分别存储0x78、0x56、0x34、0x12。如下图所示:
在这里插入图片描述

三、问题解决

基于上述的验证,我们在对不能位运算的浮点型数据有把它拆成一个字节一个字节需求时,可以使用联合体去处理,如下所示:

#include <stdio.h>
union
{
    double  var1;
    unsigned char var2[8];
}data;

int main(int argc, char const *argv[])
{

    data.var1 = 1.265341;
    for (int i = 7; i >= 0; i--)
        printf("%p : %#x \n",&data.var2[i] , data.var2[i]); 

    return 0;
}

在这里插入图片描述
如上所示,double型的1.265341在内存上的各个字节的分布,我们可以反过来验证一下。程序如下所示:

#include <stdio.h>
union
{
    double  var1;
    unsigned char var2[8];
}data;

int main(int argc, char const *argv[])
{
    /*实现将double数据转成拆开的单字节数据*/
    /*
    data.var1 = 1.265341;
    for (int i = 7; i >= 0; i--)
        printf("%p : %#x \n",&data.var2[i] , data.var2[i]); 
    */

   /*反向验证将拆开的字节数据放入联合体变量,是否会让double变量恢复*/
   data.var2[0] = 0x63;
   data.var2[1] = 0x9b;
   data.var2[2] = 0x54;
   data.var2[3] = 0x34;
   data.var2[4] = 0xd6; 
   data.var2[5] = 0x3e;
   data.var2[6] = 0xf4;
   data.var2[7] = 0x3f;
   printf("data.var1 = %lf \n",data.var1);

    return 0;
}

运行结果如下图所示,说明该方法可行。
在这里插入图片描述

在C#中,如果你想要从下位机(通常是嵌入式系统或硬件设备)获取温度、电压等数据,你需要进行串口通信或者是通过网络连接(如TCP/IP)。以下是基本步骤: 1. **设置通信接口**: 首先,确保你的C#程序配置了适当的SerialPort(如果是串口通信)或TcpClient(如果是网络通信)实例。对于串口通信,需要包含`System.IO.Ports`命名空间。 2. **数据接收**: 对于串口通信,使用`SerialPort.ReadLine()`读取每一行数据。如果数据是以特定格式(如CSV或自定义协议)发送的,解析每一行到具体的数值字段,例如: ```csharp string receivedData = SerialPort.ReadLine(); var values = ParseData(receivedData); // 分割字符串并转换为温度、电压等变量 ``` 对于网络通信,可以监听接收到的数据,并解析成JSON或其他预定义格式。 3. **数据解析**: 创建一个函数来处理数据,根据预期的格式将字符串转换为实际的温度和电压值。例如,假设数据是一个逗号分隔的列表: ```csharp double temperature, voltage; if (double.TryParse(values[0], out temperature) && double.TryParse(values[1], out voltage)) { // 温度和电压已成功解析 } ``` 4. **错误处理**: 考虑可能出现的异常情况,比如串口未打开、网络连接失败或数据格式错误等,添加相应的错误处理代码。 5. **数据展示或后续处理**: 获取数据后,你可以将其存储到数据库、显示在界面上,或者用于进一步的计算分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值