程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# ---- 串口數據YSI實例

C# ---- 串口數據YSI實例

編輯:C#入門知識

C# ---- 串口數據YSI實例


本次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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved