C# ---- 串口数据YSI实例

简介: 原文:C# ---- 串口数据YSI实例C#----串口数据接收发送中,发送接收数据已经可以模拟了。   本次YSI实例过程中 主要是:类型转换问题 、计算校验码    一、不同设备不同的规则,本次实例代码如下: string serialNumber = s...
原文: C# ---- 串口数据YSI实例

C#----串口数据接收发送中,发送接收数据已经可以模拟了。

 

本次YSI实例过程中 主要是:类型转换问题 、计算校验码 

 

一、不同设备不同的规则,本次实例代码如下:

            string serialNumber = sn;//Packet Command Payload

            int i1 = 0x11;//Packet Length Byte
            int i2 = 0xA5;//Packet Sync Byt[] 

            string[] strarr = new string[32];//命令字符串
            strarr[0] = Convert.ToString(i1, 16);//转化固定字符
            strarr[1] = Convert.ToString(i2, 16);//转化固定字符

            char[] arr = serialNumber.ToCharArray();//字符数组

            int[] ii = new int[16];//整形数组,为了计算校验码
            ii[0] = i1;//转化固定字符
            ii[1] = i2;//转化固定字符

            for (int i = 0; i < arr.Length; i++)
            {
                strarr[2 + i] = Convert.ToString(arr[i], 16);
                ii[2 + i] = (int)arr[i];
            }
            //计算校验码
            int checksum = 0;
            for (int i = 0; i < ii.Length; i++)
            {
                checksum += ii[i];
                if (checksum > 256)
                    checksum = checksum - 256;
            }
            strarr[16] = Convert.ToString(checksum, 16);

上述,一是采用强制类型转换 char 类型为 16进制int,然后计算校验码;二是将char转换为16进制形式的string。

这样最后就得出需要发送的字符串数组。

 

二、发送字符串数据并且接收数据,代码如下:

                //计算传输字符串
                string[] sendstr = Sendstr(sdstr);
                //发送字节数组
                byte[] wbb = new byte[64];
                //转换成16进制字节
                for (int i = 0; i < sendstr.Length; i++)
                {
                    wbb[i] = Convert.ToByte(sendstr[i], 16);
                }
                //接收字节数组
                byte[] rdb = new byte[64];

                //打开新的串行端口连接
                sp.Open();
                //丢弃来自串行驱动程序的接受缓冲区的数据
                sp.DiscardInBuffer();
                //丢弃来自串行驱动程序的传输缓冲区的数据
                sp.DiscardOutBuffer();
                //使用缓冲区的数据将指定数量的字节写入串行端口
                sp.Write(wbb, 0, wbb.Length);
                //当前线程挂起500毫秒
                System.Threading.Thread.Sleep(500);
                //读取数据超时
                sp.ReadTimeout = 1000;
                //读取接收数据
                sp.Read(rdb, 0, rdb.Length);

上述,一是需要转换为字节发送,设备要求16进制字节;二是发送数据后,可以挂起线程500毫秒,避免数据冲突的问题。

这样返回字节数组rdb。

 

三、接收后的字节数组,需要转换解析,代码如下:

                //读取记录转换为字符串
                string[] rdstr = new string[100];
                for (int i = 0; i < rdb.Length; i++)
                {
                    rdstr[i] = rdb[i].ToString("X2");
                }

上述,先转换为16进制字符串。

 

四、最终需要收集的数据是浮点型数据

网上搜到一个string 与浮点类型相互转换的类,可以直接使用,代码如下:

    class stConvertFloat
    {
        public static string FloatToStandard(double f, int style)
        {
            char[] Num = new char[32];//32为二进制结果加1结束符

            if (f < 0) //f为负数 ,符号位Num[0]赋1
            {
                Num[0] = '1';
                f = f * (-1); //转换为整数
            }
            else
                Num[0] = '0';

            //求指数
            int exponent = 0;
            if (f >= 1)//指数符号为正情况,即fabs(f)>=1 
            {
                while (f >= 2)
                {
                    exponent++;
                    f = f / 2;
                }
            }
            else//负指数情况
            {
                while (f < 1)
                {
                    exponent++;
                    f = f * 2;
                }
                exponent = (128 - exponent) + 128;//(128-exponent)为补码,+128是指数符号位置1
            }

            exponent += 127;//指数转换为阶码

            int i;
            for (i = 8; i >= 1; i--)//将指数转换为二进制数
            {
                if (exponent % 2 == 0)
                    Num[i] = '0';
                else
                    Num[i] = '1';
                exponent /= 2;
            }

            f = f - 1;//小数转换为标准格式
            //求小数部分
            double s = 1;
            for (i = 9; i < 32; i++)
            {
                s /= 2;
                if (f >= s)
                {
                    //MessageBox.Show(Convert.ToString(s));
                    f = f - s;
                    Num[i] = '1';
                }
                else
                    Num[i] = '0';
            }

            if (style == 2)//二进制输出
            {
                string tt = new string(Num);
                return tt;
            }
            else //二进制转换为十六进制
            {
                char sum;
                int j = 0;
                for (i = 0; i < 32; i = i + 4, j++)
                {
                    sum = Convert.ToChar((Num[i] - '0') * 8 + (Num[i + 1] - '0') * 4 + (Num[i + 2] - '0') * 2 + (Num[i + 3] - '0'));
                    if (sum > 9)
                        Num[j] = Convert.ToChar((sum - 10) + 'a');
                    else
                        Num[j] = Convert.ToChar(sum + '0');
                }
                string tt = new string(Num);
                tt = tt.Substring(0, 8);
                return tt;
            }
        }

        public static double StandardToFloat(string FNum, int style)
        {
            char[] Num = new char[32];
            char[] Hex = new char[8];

            int i, j, value;

            if (style == 2)//二进制
            {
                for (i = 0; i < 32; i++)
                    Num[i] = FNum[i];
            }
            else//十六进制转换为二进制
            {
                for (i = 0; i < 8; i++)
                {
                    Hex[i] = FNum[i];
                    if (Hex[i] >= '0' && Hex[i] <= '9')
                        value = Hex[i] - '0';
                    else
                    {
                        Hex[i] = Convert.ToChar(Hex[i] | 0x20); //统一转换为小写
                        value = Hex[i] - 'a' + 10;
                    }
                    for (j = 3; j >= 0; j--)
                    {
                        Num[i * 4 + j] = Convert.ToChar((value % 2) + '0');
                        value /= 2;
                    }
                }
            }

            double f = 1;//f为最终浮点数结果,标准浮点格式隐含小数点前的1
            double s = 1;//s为小数各个位代表的权值

            for (i = 9; i < 32; i++)//转换小数部分
            {
                s /= 2;
                if (Num[i] == '1')
                {
                    f += s;
                    //MessageBox.Show(Convert.ToString(s));
                }
            }

            int exponent = 0;//指数部分
            int d = 1;//d代表指数部分各位的权值
            for (i = 8; i >= 1; i--)//此时计算的是阶码
            {
                if (Num[i] == '1')
                    exponent += d;
                d *= 2;
            }
            if (exponent >= 127)
                exponent -= 127;//将阶码转换为指数
            else
            {
                exponent += 256;//补上指数变阶码溢出的最高位
                exponent -= 127;//阶码变指数,指数为补码
                exponent = 128 - (exponent - 128);//(exponent-128)去符号位,在讲补码变为指数绝对值
                exponent = exponent * (-1);//最终指数部分
            }

            if (Num[0] == '1')//浮点数符号位为1,说明为负数
                f = f * (-1);

            f = f * Math.Pow(2, exponent);//将小数部分和浮点部分组合

            return f;
        }
    }

 

综上:串口数据发送接收是比较简单的,难点在于数据类型转换。

需要怎么转换成字节发送出去,再如何接收字节转换成所需数据。

目录
相关文章
|
1月前
|
C# 数据库
c# dev Form1 gridview1使用Form2 gridview1的数据
c# dev Form1 gridview1使用Form2 gridview1的数据
|
2月前
|
开发框架 .NET C#
C#数据去重的这几种方式,你知道几种?
C#数据去重的这几种方式,你知道几种?
|
3月前
|
SQL 开发框架 .NET
EntityFramework数据持久化复习资料3、C#拓展方法与yield关键字使用
EntityFramework数据持久化复习资料3、C#拓展方法与yield关键字使用
25 0
|
4月前
|
编译器 数据处理 C#
C#中的异步流:使用IAsyncEnumerable<T>和await foreach实现异步数据迭代
【1月更文挑战第10天】本文介绍了C#中异步流的概念,并通过使用IAsyncEnumerable<T>接口和await foreach语句,详细阐述了如何异步地迭代数据流。异步流为处理大量数据或需要流式处理数据的场景提供了一种高效且非阻塞性的方法,使得开发者能够更优雅地处理并发和数据流问题。
|
4月前
|
存储 数据管理 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机本身的数据保存(CustomData)功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机本身的数据保存(CustomData)功能(C#)
31 0
|
5天前
|
XML 存储 开发框架
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
8 0
|
7天前
|
SQL 存储 开发框架
C# DataSet结合FlyTreeView显示树状模型数据
C# DataSet结合FlyTreeView显示树状模型数据
|
2月前
|
SQL C# 数据库
C# 读取多条数据记录导出到 Word 标签模板
C# 读取多条数据记录导出到 Word 标签模板
|
2月前
|
安全 数据处理 C#
C# Post数据或文件到指定的服务器进行接收
C# Post数据或文件到指定的服务器进行接收