Gegenseitige Konvertierung zwischen Float und Byte zwischen C# und Mikrocontroller

Dieses Kapitel dient als Ergänzung zum Debugging-Assistenten für die serielle Schnittstelle und zum Senden und Empfangen von Strukturen . Es wird hauptsächlich zum Senden und Empfangen negativer Zahlen, Gleitkommazahlen usw. in benutzerdefinierten Protokollen verwendet (die zuvor verwendeten Gleitkommazahlen waren direkt). Wird zum Senden und Empfangen von Zeichenfolgen verwendet. Aus der Zeichenfolge Zur Analyse verwenden wir hier hauptsächlich Hexadezimalzahlen, um die Sende- und Empfangsprinzipien und Verwendungsvorgänge zu analysieren.

Assistent zum Debuggen der virtuellen seriellen Schnittstelle

Im Allgemeinen können externe Computergeräte über verschiedene Anschlüsse an den Computer angeschlossen werden. Zu den gebräuchlichsten gehören USB, VGA, DVI usw. Im industriellen Bereich oder im Bereich der Softwareentwicklung müssen wir häufig eine einfache, kostengünstige und schnelle Möglichkeit nutzen, um die Verbindung zwischen Computern und Geräten herzustellen. Dann ist der serielle Port eine sehr gute Wahl

In der Entwicklungsphase ist das Gerät möglicherweise noch nicht fertig. Zuerst muss die PC-Software entwickelt werden, und dann können wir über die Software einen seriellen Port virtualisieren. Die Entität, die zum Ersetzen des Geräts verwendet wird. für den Lerngebrauch

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Einer verwendet COM1 und der andere COM2 zur Kommunikation.

Bytes und Datenkonvertierung

c#-Implementierung

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));
        }
    }
}

Fügen Sie hier eine Bildbeschreibung ein

c-Implementierung

#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;
}

Fügen Sie hier eine Bildbeschreibung ein

üben

Mit Debugging-Assistent für die serielle Schnittstelle

Die ersten beiden Bytes, das letzte Byte und die Zwischendaten sind 4 Bytes. Die aus der C-Sprache konvertierten 4 Bytes mit einfacher Genauigkeit sind in der obigen C-Implementierung zu sehen.
Fügen Sie hier eine Bildbeschreibung ein

        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# empfängt Gleitkommadaten

Fügen Sie hier eine Bildbeschreibung ein
Was empfangen wird, sind zwei Bytes kürzer

//直接调用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;
        }

Fügen Sie hier eine Bildbeschreibung ein

Supongo que te gusta

Origin blog.csdn.net/chengcao123/article/details/131513755
Recomendado
Clasificación