Взаимное преобразование между плавающей точкой и байтом между С# и микроконтроллером

Эта глава служит дополнением к помощнику по отладке последовательного порта и отправке и получению структур . В основном она используется для отправки и получения отрицательных чисел, чисел с плавающей запятой и т. д. в пользовательских протоколах (числа с плавающей запятой, которые мы использовали ранее, были напрямую используется для отправки и получения строк. Из строки Для анализа здесь мы в основном используем шестнадцатеричный код для анализа принципов отправки и получения и операций использования).

Помощник по отладке виртуального последовательного порта

Вообще говоря, внешние устройства компьютера можно подключать к компьютеру через различные порты. Общие из них включают USB, VGA, DVI и т. д. В сфере промышленности или разработки программного обеспечения нам часто необходимо использовать простой, недорогой и быстрый способ подключения между компьютерами и оборудованием. Тогда последовательный порт — очень хороший выбор.

На стадии разработки устройство может быть еще не готово.Сначала необходимо разработать программное обеспечение для ПК, а затем мы можем виртуализировать последовательный порт с помощью программного обеспечения. Организация, использованная для замены устройства. для обучения использовать

Вставьте сюда описание изображения
Вставьте сюда описание изображения
Один для связи использует COM1, а другой — COM2.

Преобразование байтов и данных

реализация С#

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 байта.4 байта одинарной точности, преобразованные из языка C, можно увидеть в реализации 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;
        }

Вставьте сюда описание изображения

рекомендация

отblog.csdn.net/chengcao123/article/details/131513755