def modbus_crc(data: bytearray) -> int:
"""计算Modbus CRC16校验码"""
crc = 0xFFFF
for byte in data:
crc ^= byte
for i in range(8):
if (crc & 1) != 0:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc
def read_holding_registers():
"""读取保持寄存器"""
try:
# 构造请求帧
req = bytearray([
SLAVE_ADDR, # 从机地址
0x03, # 功能码
(START_REG >> 8) & 0xFF, # 起始地址高字节
START_REG & 0xFF, # 起始地址低字节
(REG_COUNT >> 8) & 0xFF, # 寄存器数量高字节
REG_COUNT & 0xFF # 寄存器数量低字节
])
# 计算并添加CRC
crc = modbus_crc(req)
req.append(crc & 0xFF)
req.append((crc >> 8) & 0xFF)
# 发送请求
uart.write(req)
# 等待响应(根据设备调整等待时间)
utime.sleep_ms(20)
resp = uart.read()
if not resp:
print("No response from device")
return None
# 校验响应
if len(resp) < 5:
print("Invalid response length")
return None
# 验证CRC
recv_crc = (resp[-1] << 8) | resp[-2]
calc_crc = modbus_crc(resp[:-2])
if recv_crc != calc_crc:
print("CRC error: {recv_crc:} vs {calc_crc:}", recv_crc, calc_crc)
return None
为什么CRC校验失败,给出修改后的代码