首页 > 代码库 > C# ---- 串口数据YSI实例

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

原文: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 = http://www.mamicode.com/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;        }    }

 

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

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