c# 与单片机之间 float与byte的相互转化

该章作为 串口调试助手结构体的收发的补充,主要用于自定义协议中的负数,浮点数等的收发(我们以前用的浮点数等,是直接使用的字符串的收发,从字符串中进行解析的,这里主要使用十六进制,对其收发原理及使用操作进行剖析)。

虚拟串口调试助手

一般来说,电脑的外部设备可以用过各种端口和电脑连接。常见的有USB,VGA,DVI等等。在工业领域或者是软件开发领域,我们常常需要用简单低成本快捷的方式,完成电脑和设备的连接。那么串口就是非常好的选择

在开发阶段,也许设备端也许还没有就绪,PC软件需要先进行开发,我们就可以通过软件虚拟一个串口出来。用来替代设备的实体。供学习使用

在这里插入图片描述
在这里插入图片描述
一个使用COM1一个使用COM2 就可以进行通信了

字节与数据转换

c# 实现

using System.Runtime.CompilerServices;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {

            byte[] dataByte = new byte[120];
            int count = 0;
            //将double型数据存入databyte中。
            double data1 = -123.125;
            //C# BitConverter 类用来字节数组转换 可以转换成字节 也可以字节转换成int、double等
            byte[] buf = BitConverter.GetBytes((double)data1);//单精度浮点型用 BitConverter.ToSingle
            Console.WriteLine(BitConverter.ToDouble(buf));
        }
    }
}

在这里插入图片描述

c 实现

#include <stdio.h>


/*
*function:ftoc(float fvalue,unsigned char*arr)
*decription:  浮点数转化成四个字节
*input: 浮点数 
*output: 4个字节的字节数组
*/
//例如12.5--0x41 48 00 00;转换完之后,arr[0]-00,arr[1]-00,arr[2]-48,arr[3]-41
void ftoc(float fvalue,unsigned char*arr) 
{
    unsigned char  *pf;
    unsigned char *px;
    unsigned char i;   //计数器 
    pf =(unsigned char *)&fvalue;            /*unsigned char型指针取得浮点数的首地址*/  
    px = arr;                               /*字符数组arr准备存储浮点数的四个字节,px指针指向字节数组arr*/

    for(i=0;i<4;i++)
    {
        *(px+i)=*(pf+i);     /*使用unsigned char型指针从低地址一个字节一个字节取出*/
    }
}

/* 
*function:float ByteToFloat(unsigned char* byteArray) 
*decription:  将字节型转化成32bits浮点型 
*input:       长度为4的字节数组 
*output: 
*/  
float ByteToFloat(unsigned char* byteArray)  
{  
    return *((float*)byteArray);  //强制类型转换 然后取值 
}  

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

    int i;
    unsigned char byteArray[4];
    ftoc(-12.5,byteArray);//浮点数转化成四个字节 

    for(i=0;i<4;i++)
        printf("%x  ",byteArray[i]);//%x即按十六进制输出,英文字母小写,右对齐

    float x=0;
    x = ByteToFloat(byteArray);
    printf("\n%f  ",x);
    return 0;
}

在这里插入图片描述

实践

与串口调试助手

其中头两个字节,尾一个字节,中间数据4个字节,使用的是c语言转换过来的单精度4字节 可见上面c实现
在这里插入图片描述

        public static int cnt = 0;
        private void serialPort1_DataReceived2(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            cnt++;
            this.Invoke((EventHandler)delegate
            {
                uiRichTextBox1.AppendText("\r\n" + "cnt:" + cnt);
            });
            Thread.Sleep(40);

            int len = serialPort1.BytesToRead;//一共接收到多少数据
            Byte[] readBuffer = new Byte[100];
            serialPort1.Read(readBuffer, 0, len);

            //2+4+1  80 81  0 0 48 c1 ff   就是-12.5
            //获得一帧掐头去尾的数据
            for (int ptr = 0; ptr < len; ptr++)
            {
                if ((readBuffer[ptr] == HEAD1) && (readBuffer[ptr + 1] == HEAD2))
                {
                    if (readBuffer[ptr + 6] == 0xff)
                    {
                        int index = ptr + 2;
                        byte[] fdata = new byte[4];
                        for (int i = 0; i < 4; i++)//这样就把尾巴给去掉了
                        {
                            fdata[i] = readBuffer[index + i];
                        }
                        this.Invoke((EventHandler)delegate
                        {
                            uiRichTextBox1.AppendText("\r\n" + "接收数据值:" + BitConverter.ToSingle(fdata,0).ToString());
                        });

                    }

                }
            }
        }

c# 接收浮点型数据

在这里插入图片描述
接受到的是两个字节ushort

//直接调用ReadDate函数,接收到的数据会自动保存入 ushort[] value1 中
//一个ushort占用两个字节,一共接收到2个ushort,共四个字节
//调用GetFloat即可实现转换
        public static void ReadDate()
        {
                ushort startAddress = 0x0066;
                ushort numberOfPoints = 2;
                ushort[] value1 = master.ReadHoldingRegisters(1, startAddress, numberOfPoints);
                log.SaveLog("value1字节数:"+value1.Length.ToString());

                float valuefloat;
                valuefloat = GetFloat(value1[0], value1[1]);

                log.SaveLog("流量" + valuefloat);
            
        }
        
        public static float GetFloat(ushort P1, ushort P2)
        {
            int intSign, intSignRest, intExponent, intExponentRest;
            float faResult, faDigit;
            intSign = P1 / 32768;
            intSignRest = P1 % 32768;
            intExponent = intSignRest / 128;
            intExponentRest = intSignRest % 128;
            faDigit = (float)(intExponentRest * 65536 + P2) / 8388608;
            faResult = (float)Math.Pow(-1, intSign) * (float)Math.Pow(2, intExponent - 127) * (faDigit + 1);
            return faResult;
        }

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值