uint16_t CRC16_Mbus( uint8_t *ptr, int len ) { unsigned int i; uint16_t crc = 0xFFFF; while(len--) { crc ^= *ptr++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } } return crc; }将其改为CCITTCRC16
时间: 2023-06-14 18:06:31 浏览: 174
可以按照下面的方式修改代码以计算CCITT CRC16:
```c
uint16_t CRC16_CCITT(uint8_t *ptr, int len) {
uint16_t crc = 0xFFFF;
while (len--) {
crc ^= (*ptr++) << 8;
for (int i = 0; i < 8; ++i) {
if (crc & 0x8000) {
crc = (crc << 1) ^ 0x1021;
} else {
crc <<= 1;
}
}
}
return crc;
}
```
修改点包括:
1. 将初始值设置为0xFFFF。
2. 将每个字节(8位)左移8位,然后进行异或运算。
3. 将多项式设置为0x1021。
需要注意的是,CCITT CRC16 与 Modbus CRC16 算法不同,如果在通信中使用错误的算法进行校验,可能会导致通信错误。
相关问题
将uint16_t crc16_modbus_8005(unsigned char *buf, unsigned int len) { uint16_t crc16 = crc16_modbus_a001(buf, len); return ((crc16 & 0x00ff) << 8) | ((crc16 & 0xff00) >> 8); //high-low convert } uint16_t crc16_modbus_a001(unsigned char *buf, unsigned int len) { uint16_t crc16 = 0xffff; uint16_t tmp; int i, j; for (j=0; j<len; j++) { crc16 = buf[j] ^ crc16; for (i=0; i<8; i++) { tmp = crc16 & 0x0001; crc16 = crc16 >> 1; if (tmp) crc16 = crc16 ^ 0xa001; } } return crc16; }这段程序改写成MK22FN512VLH12单片机使用官方库的fsl_crc.h文件中
以下是使用fsl_crc.h文件中的CRC模块实现的代码:
```c
#include "fsl_crc.h"
uint16_t crc16_modbus_8005(unsigned char *buf, unsigned int len)
{
crc_config_t config;
uint16_t crc16;
/* 初始化CRC模块配置 */
CRC_GetDefaultConfig(&config);
config.polynomial = 0xA001;
config.seed = 0xFFFF;
config.reflectIn = true;
config.reflectOut = true;
/* 计算CRC16 */
CRC_Init(CRC0, &config);
CRC_WriteData(CRC0, buf, len);
crc16 = CRC_Get16bitResult(CRC0);
/* 高低位转换 */
return ((crc16 & 0x00ff) << 8) | ((crc16 & 0xff00) >> 8);
}
```
需要注意的是,该代码中使用了CRC模块的反射输入和反射输出功能,因为Modbus协议中使用的CRC算法是反向的。同时,CRC模块的多项式和种子值也需要设置为对应的值。
uint16_t CRC16_Modbus(unsigned char *ptr, int len) { unsigned int i; uint16_t crc = 0xFFFF; while(len--) { crc ^= *ptr++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } } return crc; }
这是一个计算CRC16-Modbus校验值的函数,输入是一个指向unsigned char类型数组的指针和数组长度,输出是一个uint16_t类型的CRC校验值。
函数使用的是多项式为0xA001的CRC算法,该算法也被称为CRC16-IBM或CRC16-ANSI。具体实现方法是,首先将crc的初值设置为0xFFFF,然后对于每个字节,按位异或后再进行8次循环,每次循环将crc右移一位并根据最低位是否为1进行异或。循环结束后,crc的值即为该数组的CRC16-Modbus校验值。
该函数可以用于串行通信、网络通信等场合中数据完整性校验。
阅读全文