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

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

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

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
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值