马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在进行串口编程时,经常会涉及到进制转换、计算协议校验码以及数据格式化的操作,本文整理了在实际项目中可能会用到的公共方法,分享给需要的朋友。一、以下包含了三部分的内容:
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).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 = 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, 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, 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;
}
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;
}
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
}
}
二、声明
本文的内容大部分方法经过了项目测试,少量没有用到的方法不保证其正确性,希望各位朋友在使用之前测试一下。
如果发现问题,请及时反馈给本人,谢谢!
|