DS28EC20 32字节扩展读取CRC16计算不符,求多语言实现修正
DS28EC20 0xA5命令CRC16计算修正方案
问题背景
使用AD(原Maxim)DS28EC20 1-Wire EEPROM的0xA5扩展读取命令,需对0xA5命令字节 + 2个0x00地址字节 + 32字节数据共35字节计算CRC,设备返回正确CRC为0x1181,但原有Perl脚本计算结果不符。
错误分析
原有脚本存在3个核心问题:
- 循环仅处理34字节,遗漏最后1字节(索引34)
- CRC初始值错误,1-Wire CRC16要求初始值为
0xFFFF而非0 - 位处理逻辑错误,未按1-Wire CRC16的**LSB优先(反射输入)**规则处理字节
修正后的实现方案
Perl 实现
#!/usr/bin/env perl use strict; use warnings; # 待计算的35字节数据 my @data = ( 0xA5, 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, 0x34 ); my $crc = 0xFFFF; my $poly = 0xA001; # 1-Wire CRC16反射多项式 foreach my $byte (@data) { $crc ^= $byte; for (my $bit = 0; $bit < 8; $bit++) { if ($crc & 0x0001) { $crc = ($crc >> 1) ^ $poly; } else { $crc >>= 1; } } } # 最终结果取反并保留16位 $crc = ~$crc & 0xFFFF; printf("计算得到CRC: 0x%04X\n", $crc); # 输出应为0x1181
Python 实现
# 待计算的35字节数据 data = [ 0xA5, 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, 0x34 ] crc = 0xFFFF poly = 0xA001 for byte in data: crc ^= byte for _ in range(8): if crc & 0x0001: crc = (crc >> 1) ^ poly else: crc >>= 1 # 取反并保留16位 crc = (~crc) & 0xFFFF print(f"计算得到CRC: 0x{crc:04X}") # 输出应为0x1181
C 实现
#include <stdio.h> #include <stdint.h> int main() { // 待计算的35字节数据 uint8_t data[] = { 0xA5, 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, 0x34 }; uint16_t crc = 0xFFFF; const uint16_t poly = 0xA001; int i, j; for (i = 0; i < sizeof(data)/sizeof(data[0]); i++) { crc ^= data[i]; for (j = 0; j < 8; j++) { if (crc & 0x0001) { crc = (crc >> 1) ^ poly; } else { crc >>= 1; } } } // 取反并保留16位 crc = (~crc) & 0xFFFF; printf("计算得到CRC: 0x%04X\n", crc); // 输出应为0x1181 return 0; }
验证说明
以上实现严格遵循DS28EC20的1-Wire CRC16规范:
- 初始值:
0xFFFF - 多项式:反射形式
0xA001(对应标准多项式0x8005) - 输入处理:逐字节按LSB到MSB顺序处理
- 输出:最终CRC取反并保留16位
运行代码后将得到与设备一致的0x1181结果。
内容的提问来源于stack exchange,提问作者M T
相关产品推荐
相关产品推荐

