Эта глава служит дополнением к помощнику по отладке последовательного порта и отправке и получению структур . В основном она используется для отправки и получения отрицательных чисел, чисел с плавающей запятой и т. д. в пользовательских протоколах (числа с плавающей запятой, которые мы использовали ранее, были напрямую используется для отправки и получения строк. Из строки Для анализа здесь мы в основном используем шестнадцатеричный код для анализа принципов отправки и получения и операций использования).
Помощник по отладке виртуального последовательного порта
Вообще говоря, внешние устройства компьютера можно подключать к компьютеру через различные порты. Общие из них включают 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;
}