C# 中上下位机通讯常用进制转换、编码转换、校验和方法汇总

一、进制转换

  1. 十进制 ↔ 二进制
// 十进制转二进制字符串
int decValue = 42;
string binaryStr = Convert.ToString(decValue, 2); // "101010"

// 二进制字符串转十进制
string binaryStr = "101010";
int decValue = Convert.ToInt32(binaryStr, 2); // 42
  1. 十进制 ↔ 十六进制
// 十进制转十六进制字符串
int decValue = 255;
string hexStr = decValue.ToString("X"); // "FF"
string hexStr2 = Convert.ToString(decValue, 16); // "ff"

// 十六进制字符串转十进制
string hexStr = "FF";
int decValue = Convert.ToInt32(hexStr, 16); // 255
  1. 字节数组 ↔ 十六进制字符串
// 字节数组转十六进制字符串
byte[] bytes = { 0x12, 0xAB, 0xFF };
string hexStr = BitConverter.ToString(bytes).Replace("-", ""); // "12ABFF"

// 十六进制字符串转字节数组
string hexStr = "12ABFF";
byte[] bytes = Enumerable.Range(0, hexStr.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hexStr.Substring(x, 2), 16))
                         .ToArray();

二、编码转换

  1. 字符串 ↔ 字节数组
// 字符串转字节数组
string text = "上下位机通讯";
byte[] utf8Bytes = Encoding.UTF8.GetBytes(text);
byte[] gb2312Bytes = Encoding.GetEncoding("GB2312").GetBytes(text);

// 字节数组转字符串
byte[] bytes = { 0xE4, 0xB8, 0x8A, 0xE4, 0xB8, 0x8B }; // UTF-8编码的"上下"
string utf8Str = Encoding.UTF8.GetString(bytes);
string gb2312Str = Encoding.GetEncoding("GB2312").GetString(bytes);
  1. 编码转换(不同编码间转换)
// GB2312转UTF-8
string gb2312Text = "通讯测试";
byte[] gb2312Bytes = Encoding.GetEncoding("GB2312").GetBytes(gb2312Text);
byte[] utf8Bytes = Encoding.Convert(Encoding.GetEncoding("GB2312"), Encoding.UTF8, gb2312Bytes);
string utf8Text = Encoding.UTF8.GetString(utf8Bytes);
  1. ASCII编码处理
// 字符串转ASCII字节数组
string asciiText = "Hello";
byte[] asciiBytes = Encoding.ASCII.GetBytes(asciiText);

// ASCII字节数组转字符串
byte[] asciiBytes = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
string asciiText = Encoding.ASCII.GetString(asciiBytes);

三、常用数值转换

  1. 字节 ↔ 数值类型
// 字节数组转整型
byte[] intBytes = { 0x00, 0x00, 0x01, 0x00 };
int intValue = BitConverter.ToInt32(intBytes, 0); // 256

// 整型转字节数组
int intValue = 256;
byte[] intBytes = BitConverter.GetBytes(intValue); // [0x00, 0x00, 0x01, 0x00]

// 注意字节序问题
if (BitConverter.IsLittleEndian)
{
    Array.Reverse(intBytes); // 大端模式下需要反转
}
  1. 浮点数转换
// 浮点数转字节数组
float floatValue = 3.14f;
byte[] floatBytes = BitConverter.GetBytes(floatValue);

// 字节数组转浮点数
byte[] floatBytes = { 0xC3, 0xF5, 0x48, 0x40 };
float floatValue = BitConverter.ToSingle(floatBytes, 0); // 3.14f

四、常用校验方法

  1. CRC校验
public static ushort CalculateCRC16(byte[] data)
{
    ushort crc = 0xFFFF;
    for (int i = 0; i < data.Length; i++)
    {
        crc ^= data[i];
        for (int j = 0; j < 8; j++)
        {
            if ((crc & 0x0001) != 0)
            {
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
                crc >>= 1;
            }
        }
    }
    return crc;
}
  1. 累加和校验
public static byte CalculateChecksum(byte[] data)
{
    byte checksum = 0;
    foreach (byte b in data)
    {
        checksum += b;
    }
    return checksum;
}

五、特殊格式处理

  1. BCD码转换
// 字节转BCD码字符串
byte bcdByte = 0x34;
string bcdStr = (bcdByte >> 4).ToString() + (bcdByte & 0x0F).ToString(); // "34"

// BCD字符串转字节
string bcdStr = "34";
byte bcdByte = (byte)(((bcdStr[0] - '0') << 4) | (bcdStr[1] - '0')); // 0x34
  1. 二进制位操作
// 设置位
byte value = 0;
value |= (1 << 3); // 设置第3位为1

// 清除位
value &= ~(1 << 3); // 清除第3位

// 检查位
bool isSet = (value & (1 << 3)) != 0; // 检查第3位是否设置

六、实际应用示例

  1. 构建Modbus RTU请求帧
public byte[] BuildModbusRTURequest(byte slaveAddress, byte functionCode, ushort startAddress, ushort numberOfRegisters)
{
    List<byte> frame = new List<byte>();
    frame.Add(slaveAddress);
    frame.Add(functionCode);
    frame.AddRange(BitConverter.GetBytes(startAddress).Reverse()); // Modbus使用大端序
    frame.AddRange(BitConverter.GetBytes(numberOfRegisters).Reverse());
    
    // 计算CRC
    ushort crc = CalculateCRC16(frame.ToArray());
    frame.AddRange(BitConverter.GetBytes(crc));
    
    return frame.ToArray();
}
  1. 解析Modbus RTU响应
public bool ParseModbusRTUResponse(byte[] response, out byte[] data)
{
    data = null;
    
    // 检查最小长度和CRC
    if (response.Length < 4)
        return false;
        
    ushort receivedCRC = BitConverter.ToUInt16(new byte[] { response[response.Length - 1], response[response.Length - 2] }, 0);
    ushort calculatedCRC = CalculateCRC16(response.Take(response.Length - 2).ToArray());
    
    if (receivedCRC != calculatedCRC)
        return false;
        
    // 提取数据部分
    data = response.Skip(2).Take(response.Length - 4).ToArray();
    return true;
}

创作不易,点颗小星星

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值