SerialPort 串口编程知识整理(二)

mac2022-06-30  34

   在进行串口编程时,经常会涉及到进制转换、计算协议校验码以及数据格式化的操作,本文整理了在实际项目中可能会用到的公共方法,分享给需要的朋友。

一、以下包含了三部分的内容:

1、进制转换:

主要包括了串口通讯中比较常用的16进制、byte、压缩BCD码、long、ASCII、Float等之间的转换方法。

ConvertHelper.cs 进制转换 /* ----------------------------------------------------------------           // Copyright (C) 北京****科技有限公司           // 版权所有。            //           // 文件名:ConvertHelper           // 文件功能描述:进制转换           //           //            // 创建标识:** 2008-05-04           //           // 修改标识:           // 修改描述:           //           // 修改标识:           // 修改描述://---------------------------------------------------------------- */ using  System; using  System.Collections.Generic; using  System.Text; using  System.IO; namespace  LY{     ///   <summary>      ///  进制转换     ///   </summary>      public   static   class  ConvertHelper    {         #region  进制转换          ///   <summary>          ///  整形转化成字节         ///   </summary>          ///   <param name="i"></param>          ///   <returns></returns>          public   static   byte  IntToByte( int  i)        {             return  Convert.ToByte(i  %   0x100 );        }         ///   <summary>          ///  16进制转化成BCD         ///   </summary>          ///   <param name="b"> byte </param>          ///   <returns> 返回BCD码 </returns>          public   static   byte  HexToBCD( byte  b)        {             int  r1  =  b  %   0x10 ;      //  b = 0x12 -> r1 = 0x02              int  r2  =  b  /   0x10 ;      //  b = 0x12 -> r2 = 0x01              if  (r1  >   9 )              // r1 = 0x0A -> r1 = 0x00                 r1  =   0 ;             if  (r2  >   9 )              // r2 = 0x0A -> r2 = 0x00                 r2  =   0 ;             return  Convert.ToByte(r1  +   10   *  r2);     // 0x12 -> 12         }         ///   <summary>          ///  16进制转化成BCD         ///   </summary>          ///   <param name="i"> int </param>          ///   <returns> 返回BCD码 </returns>          public   static   byte  HexToBCD( int  i)        {             return  HexToBCD(IntToByte(i));        }         ///   <summary>          ///  Double转换为压缩BCD         ///   </summary>          ///   <param name="d"> 0-100内的双精度浮点数字 </param>          ///   <returns> 返回压缩BCD码 </returns>          public   static   string  DoubleToBCD( double  d)        {             string [] strs  =  d.ToString( " F2 " ).Split( ' . ' );             string  temp1  =   int .Parse(strs[ 0 ]).ToString( " D2 " );             string  temp2  =   int .Parse(strs[ 1 ]).ToString( " D2 " );             return   string .Format( " {0} {1} " , temp1, temp2);        }         ///   <summary>          ///  long转换为BCD         ///   </summary>          ///   <param name="val"></param>          ///   <returns></returns>          public   static   long  ToBCD( long  val)        {             long  res  =   0 ;             int  bit  =   0 ;             while  (val  >=   10 )            {                res  |=  (val  %   10   <<  bit);                val  /=   10 ;                bit  +=   4 ;            }            res  |=  val  <<  bit;             return  res;        }         ///   <summary>          ///  BCD转换为long         ///   </summary>          ///   <param name="vals"></param>          ///   <returns></returns>          public   static   long  FromBCD( long  vals)        {             long  c  =   1 ;             long  b  =   0 ;             while  (vals  >   0 )            {                b  +=  ((vals  &   0xf *  c);                c  *=   10 ;                vals  >>=   4 ;            }             return  b;        }         ///   <summary>          ///  BCD转化成16进制         ///   </summary>          ///   <param name="b"></param>          ///   <returns></returns>          public   static   byte  BCDToHex( byte  b)        {             int  r2  =  b  %   100 ;       //  b = 12 -> r2 = 12         // 123 -> r2 = 23              int  r1  =  r2  %   10 ;       // r2 = 12 -> r1 = 2                  r2  =  r2  /   10 ;            // r2 = 12 -> r2 =1              return  Convert.ToByte(r1  +   0x10   *  r2);        }         ///   <summary>          ///  BCD转化成16进制         ///   </summary>          ///   <param name="i"></param>          ///   <returns></returns>          public   static   byte  BCDToHex( int  i)        {             return  BCDToHex(IntToByte(i));        }         ///   <summary>          ///  btye转化成16进制字符         ///   </summary>          ///   <param name="b"> byte </param>          ///   <returns></returns>          public   static   string  ToHexString( byte  b)        {             return  Convert.ToString(b,  16 );        }         ///   <summary>          ///  int转化成16进制字符         ///   </summary>          ///   <param name="num"> int </param>          ///   <returns></returns>          public   static   string  ToHexString( int  num)        {             return  Convert.ToString(num,  16 );        }         ///   <summary>          ///  16进制字符串转换成字节数组         ///   </summary>          ///   <param name="s"></param>          ///   <returns></returns>          public   static   byte [] HexStringToByteArray( string  s)        {            s  =  s.Replace( "   " "" );             byte [] buffer  =   new   byte [s.Length  /   2 ];             for  ( int  i  =   0 ; i  <  s.Length; i  +=   2 )            {                buffer[i  /   2 =  ( byte )Convert.ToByte(s.Substring(i,  2 ),  16 );            }             return  buffer;        }         ///   <summary>           ///  字节数组转换成16进制字符串         ///   </summary>          ///   <param name="data"></param>          ///   <returns></returns>          public   static   string  ByteArrayToHexString( byte [] data)        {            StringBuilder sb  =   new  StringBuilder(data.Length  *   3 );             foreach  ( byte  b  in  data)            {                sb.Append(Convert.ToString(b,  16 ).PadLeft( 2 ' 0 ' ).PadRight( 3 '   ' ));            }             return  sb.ToString().Trim().ToUpper();        }         ///   <summary>          ///  ASCII转16进制         ///   </summary>          ///   <param name="ascii"> ASCII </param>          ///   <returns></returns>          public   static   string  ASCIIToHex( string  ascii)        {             char [] cs  =  ascii.ToCharArray();            StringBuilder sb  =   new  StringBuilder();             for  ( int  i  =   0 ; i  <  cs.Length; i ++ )            {                 string  hex  =  (( int )cs[i]).ToString( " X " );                sb.AppendFormat( " {0}  " , hex);            }             return  sb.ToString().TrimEnd( '   ' );        }         ///   <summary>          ///  HEX to ASCII         ///   </summary>          ///   <param name="hex"></param>          ///   <returns></returns>          public   static   string  HexToASCII( string  hex)        {             if  (hex.Length  %   2   ==   0 )            {                 int  iValue;                 byte [] bs;                 string  sValue  =   string .Empty;                 string  result  =   string .Empty;                 int  length  =  hex.Length  /   2 ;                 for  ( int  i  =   0 ; i  <  length; i ++ )                {                    iValue  =  Convert.ToInt32(hex.Substring(i  *   2 2 ),  16 );  //  16进制->10进制                     bs  =  System.BitConverter.GetBytes(iValue);  // int->byte[]                     sValue  =  System.Text.Encoding.ASCII.GetString(bs,  0 1 );   // byte[]-> ASCII                     result  +=   char .Parse(sValue).ToString();                }                 return  result.PadLeft(length,  ' 0 ' );            }             return   string .Empty;        }         ///   <summary>          ///  ASCII To Float         ///   </summary>          ///   <param name="ascii"></param>          ///   <returns></returns>          public   static   float  ASCIIToFloat( string  ascii)        {             if  (ascii.Length  ==   8 )            {                 byte [] arr  =   new   byte [ 4 ];                 for  ( int  i  =   0 ; i  <   4 ; i ++ )                {                    arr[i]  =  Convert.ToByte(ascii.Substring(( 3   -  i)  *   2 2 ),  16 );                }                 float  f  =  BitConverter.ToSingle(arr,  0 );                 return  f;            }             return  0f;        }         ///   <summary>          ///  Hex to Float         ///   </summary>          ///   <param name="hex"></param>          ///   <returns></returns>          public   static   float  HexToFloat( string  hex)        {             string  ascii  =  HexToASCII(hex);             float  f  =  ASCIIToFloat(ascii);             return  f;        }         #endregion     }}

2、校验码计算:

包括了16进制异或和、16进制累加、16进制ASCII累加三种类型的校验码计算方法。

CheckHelper.cs 代码校验码计算 /* ----------------------------------------------------------------           // Copyright (C) 北京****科技有限公司           // 版权所有。            //           // 文件名:CheckHelper           // 文件功能描述:校验码计算           //           //            // 创建标识:** 2008-05-04           //           // 修改标识:           // 修改描述:           //           // 修改标识:           // 修改描述://---------------------------------------------------------------- */ using  System; using  System.Collections.Generic; using  System.Linq; using  System.Text; namespace  LY{     ///   <summary>      ///  校验码计算     ///   </summary>      public   static   class  CheckHelper    {            #region  校验码计算的方法          ///   <summary>          ///  返回协议验证码,默认命令字的开始位置为第二位         ///   </summary>          ///   <param name="hex"> 协议串/param>         ///   <returns> 16进制字符串表示的异或计算结果 </returns>          private   static   string  HexXorToString( string  hex)        {             string [] hexTemp  =  hex.Split( '   ' );             int  k  =   0 ;             for  ( int  i  =   0 ; i  <  hexTemp.Length; i ++ )            {                 int  j  =  Convert.ToInt32(hexTemp[i],  16 );                 if  (i  ==   1 )                {                    k  =  j;                }                 else   if  (i  >   1 )                {                    k  =  k  ^  j;                }            }             string  hexResult  =   string .Format( " {0:X} " , k  %   256 ); // 保证得到一个字节长度的值              if  (hexResult.Length  ==   1 )            {                hexResult  =   string .Format( " 0{0} " , hexResult);            }             return  hexResult;        }         ///   <summary>          ///  返回协议验证码         ///   </summary>          ///   <param name="hex"> 协议串 </param>          ///   <param name="cmdIndex"> 命令字的开始位置 </param>          ///   <returns> 验证码 </returns>          private   static   string  HexXorToString( string  hex,  int  cmdIndex)        {             string [] hexTemp  =  hex.Split( '   ' );             int  k  =   0 ;             for  ( int  i  =  cmdIndex; i  <  hexTemp.Length; i ++ )            {                 int  j  =  Convert.ToInt32(hexTemp[i],  16 );                 if  (i  ==  cmdIndex)                {                    k  =  j;                }                 else   if  (i  >  cmdIndex)                {                    k  =  k  ^  j;                }            }             string  hexResult  =   string .Format( " {0:X} " , k  %   256 ); // 保证得到一个字节长度的值              if  (hexResult.Length  ==   1 )            {                hexResult  =   string .Format( " 0{0} " , hexResult);            }             return  hexResult;        }         ///   <summary>          ///  16进制相加的值         ///   </summary>          ///   <param name="hex1"></param>          ///   <param name="hex2"></param>          ///   <returns></returns>          private   static   string  HexAddToString( string  hex1,  string  hex2)        {             int  h1  =  Convert.ToInt32(hex1,  16 );             int  h2  =  Convert.ToInt32(hex2,  16 );             int  sum  =  (h1  +  h2)  %   256 ; // 保证得到一个字节长度的值              string  hexResult  =   string .Format( " {0:X} " , sum);             if  (hexResult.Length  ==   1 )            {                hexResult  =   string .Format( " 0{0} " , hexResult);            }             return  hexResult;        }         ///   <summary>          ///  返回带验证码的协议命令         ///   </summary>          ///   <param name="hex"> 协议串 </param>          ///   <returns> 带验证码的协议命 </returns>          public   static   string  GetSendProtocol( string  hex)        {             string  hexTemp  =   string .Empty;            hexTemp  =  HexXorToString(hex);             string  hexResult  =   string .Empty;             string  hexTemp1  =  HexAddToString(hexTemp,  " 37 " );             string  hexTemp2  =  HexAddToString(hexTemp,  " D5 " );             string  hexTemp3  =  HexAddToString(hexTemp,  " 9E " );            hexResult  =   string .Format( " {0} {1} {2} {3} " , hex, hexTemp1, hexTemp2, hexTemp3);             return  hexResult;        }         ///   <summary>          ///  返回带验证码的协议命令         ///   </summary>          ///   <param name="hex"> 协议串 </param>          ///   <param name="cmdIndex"> 命令字的开始位置 </param>          ///   <returns> 带验证码的协议命 </returns>          public   static   string  GetSendProtocol( string  hex,  int  cmdIndex)        {             string  hexTemp  =   string .Empty;            hexTemp  =  HexXorToString(hex, cmdIndex);             string  hexResult  =   string .Empty;             string  hexTemp1  =  HexAddToString(hexTemp,  " 37 " );             string  hexTemp2  =  HexAddToString(hexTemp,  " D5 " );             string  hexTemp3  =  HexAddToString(hexTemp,  " 9E " );            hexResult  =   string .Format( " {0} {1} {2} {3} " , hex, hexTemp1, hexTemp2, hexTemp3);             return  hexResult;        }         ///   <summary>          ///  得到校验码         ///   </summary>          ///   <param name="message"> 16进制ASCII </param>          ///   <returns></returns>          private   static   string  GetChecksum( string  message)        {             char [] chars  =  message.ToCharArray();             ushort  c;             ushort  total  =   0 ;             for  ( int  i  =   0 ; i  <  chars.Length; i ++ )            {                total  +=  ( ushort )chars[i];            }            c  =  ( ushort )( 0   -  total);             string  hex  =  Convert.ToString(c,  16 );             return  hex.ToUpper();        }         ///   <summary>          ///  检查校验码是否相等         ///   </summary>          ///   <param name="message"> 16进制ASCII </param>          ///   <param name="checksum"> 16进制校验码 </param>          ///   <returns> 是否相等 </returns>          private   static   bool  CalculateChecksum( string  message,  string  checksum)        {             char [] chars  =  message.ToCharArray();             ushort  c  =  Convert.ToUInt16(checksum,  16 );             ushort  total  =   0 ;             for  ( int  i  =   0 ; i  <  chars.Length; i ++ )            {                total  +=  ( ushort )chars[i];            }             if  (( ushort )(c  +  total)  ==   0 return   true ;             return   false ;        }         #endregion     }}

3、字符串格式化:

主要是针对协议中涉及到的金额、数量、时间等字符串的处理。 

FormatHelper.cs 字符串格式化 /* ----------------------------------------------------------------           // Copyright (C) 北京****科技有限公司           // 版权所有。            //           // 文件名:FormatHelper           // 文件功能描述:字符串格式化           //           //            // 创建标识:** 2008-05-04           //           // 修改标识:           // 修改描述:           //           // 修改标识:           // 修改描述://---------------------------------------------------------------- */ using  System; using  System.Collections.Generic; using  System.Linq; using  System.Text; namespace  Test{     ///   <summary>      ///  字符串格式化     ///   </summary>      public   static   class  FormatHelper    {             #region  格式化字符串          ///   <summary>          ///  将字符数组装换成字符串         ///   </summary>          ///   <param name="array"> 数组 </param>          ///   <param name="startIndex"> 开始位置 </param>          ///   <param name="count"> 长度 </param>          ///   <returns> 拼接字符串 </returns>          public   static   string  GetStringByArray( string [] array,  int  startIndex,  int  count)        {             int  index  =  array.Length;             if  (startIndex  <   0   ||  startIndex  >  index)            {                 return   string .Empty;            }             int  endIndex  =  startIndex  +  count;             if  (endIndex  <   0   ||  endIndex  >  index)            {                 return   string .Empty;            }             if  (startIndex  >  endIndex)            {                 return   string .Empty;            }             string  result  =   string .Empty;            result  =   string .Join( "   " , array, startIndex, count);             return  result;        }         ///   <summary>          ///  将BCDto日期         ///   </summary>          ///   <param name="now"></param>          ///   <returns></returns>          public   static  DateTime GetDateTimeByBCD( string  now)        {             string [] tempNow  =  now.TrimEnd( '   ' ).Split( '   ' );             string  dt  =   string .Format( " {6}{0}-{1}-{2} {3}:{4}:{5} " , tempNow[ 0 ], tempNow[ 1 ], tempNow[ 2 ], tempNow[ 3 ], tempNow[ 4 ], tempNow[ 5 ], DateTime.Now.Year.ToString().Substring( 0 2 ));            DateTime result;             bool  done  =  DateTime.TryParse(dt,  out  result);             if  (done)            {                 return  result;            }             return  DateTime.Now;        }         ///   <summary>          ///  返回格式化的日期时间字符串         ///   </summary>          ///   <param name="current"></param>          ///   <returns></returns>          public   static   string  GetBCDDateTime(DateTime current)        {             string  result  =  current.ToString( " yy MM dd HH mm ss " );             return  result;        }         ///   <summary>          ///  将字符串转换成对应的数值/100         ///   </summary>          ///   <param name="value"></param>          ///   <returns></returns>          public   static   decimal  GetValueByString( string  value)        {             string  tempValue  =  value.Replace( "   " "" );             return   decimal .Divide( decimal .Parse(tempValue),  100 );        }         ///   <summary>          ///  返回对应的整型字符串         ///   </summary>          ///   <param name="i"></param>          ///   <returns></returns>          public   static   string  BinaryToIntString( int  i)        {             string  result  =   string .Empty;             if  (i  <   0   ||  i  >   999999 )            {                 return   " 00 00 00 " ;            }             else   if  (i  <   100 )            {                 return   string .Format( " 00 00 {0} " , i.ToString( " D2 " ));            }             else   if  (i  >=   100   &&  i  <   1000 )            {                 return   string .Format( " 00 0{0} {1} " , i.ToString().Substring( 0 1 ), i.ToString().Substring( 1 2 ));            }             else   if  (i  >=   1000   &&  i  <   10000 )            {                 return   string .Format( " 00 {0} {1} " , i.ToString().Substring( 0 2 ), i.ToString().Substring( 2 2 ));            }             else   if  (i  >=   10000   &&  i  <   100000 )            {                 return   string .Format( " 0{0} {1} {2} " , i.ToString().Substring( 0 1 ), i.ToString().Substring( 1 2 ), i.ToString().Substring( 3 2 ));            }             else   if  (i  >=   100000   &&  i  <   1000000 )            {                 return   string .Format( " {0} {1} {2} " , i.ToString().Substring( 0 2 ), i.ToString().Substring( 2 2 ), i.ToString().Substring( 4 2 ));            }             return   " 00 00 " ;        }         ///   <summary>          ///  整形格式化为两位小数         ///   </summary>          ///   <param name="value"></param>          ///   <returns></returns>          public   static   string  IntFormatString( int  value)        {             return  value.ToString( " D2 " );        }         #endregion     }}

转载于:https://www.cnblogs.com/deepwishly/archive/2010/04/23/2551247.html

相关资源:串口编程中SerialPort类介绍以及应用
最新回复(0)