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 10:06:31 浏览: 172
可以按照下面的方式修改代码以计算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_CCITT(uint8_t *ptr, int len) {return crc; }补全中间
### 回答1:
这个函数是求给定数据 ptr 的 CRC16 校验值,其中 len 是数据的长度。下面是具体的实现代码:
```c
uint16_t CRC16_CCITT(uint8_t *ptr, int len) {
uint16_t crc = 0xFFFF;
while (len--) {
crc ^= *ptr++;
for (int i = 0; i < 8; i++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0x8408;
} else {
crc >>= 1;
}
}
}
return crc;
}
```
注:CRC16_CCITT 是一种常用的 CRC16 算法,使用的多项式是 0x1021。
### 回答2:
uint16_t CRC16_CCITT(uint8_t *ptr, int len) {
uint16_t crc = 0xFFFF;
while (len--) {
crc ^= *ptr++; // 异或当前字节
for (int i = 0; i < 8; i++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0x8408; // 异或多项式0x8408
} else {
crc >>= 1;
}
}
}
return crc;
}
该函数是一个基于CCITT标准的16位CRC校验函数。传入的参数为一个指针和一个长度。函数会根据指针指向的数据以及长度计算得到一个16位的校验值,并将其返回。
函数中采用了CRC-CCITT的多项式0x8408,并初始化crc为0xFFFF。
随后,函数会将传入的数据逐个字节进行处理。每次处理一个字节时,会将当前字节与crc进行异或操作。
接下来,函数会对当前字节进行8次迭代,每次迭代判断最低位是否为1。如果为1,则将crc右移一位并与0x8408异或;如果不为1,则只向右移动一位。
最后,函数将得到的校验值返回。
这个CRC16_CCITT函数可以用于数据传输、错误检测、网络通信等领域,通过计算校验值可以判断数据是否传输错误或损坏。
### 回答3:
uint16_t CRC16_CCITT(uint8_t *ptr, int len) {
uint16_t crc = 0xFFFF;
for (int i = 0; i < len; i++) {
crc ^= (uint16_t)ptr[i] << 8;
for (int j = 0; j < 8; j++) {
if ((crc & 0x8000) != 0) {
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
}
}
return crc;
}
上述的函数是一个用于计算CRC16(循环冗余校验)的CCITT算法。传入参数为一个指向uint8_t类型数据的指针ptr和数据的长度len。函数通过遍历数据并进行位操作,计算得到最终的校验值crc,并将其返回。
具体来说,函数首先将crc初始化为0xFFFF。然后,对于每个数据字节ptr[i],将其与0xFF按位异或,并左移8位赋值给crc。接下来,通过一个循环迭代8次的for循环,对crc进行位处理。在循环中,首先判断crc最高位是否为1,如果是则将crc向左移动1位后与0x1021进行按位异或,否则只是向左移动1位。通过这样的位处理,最终得到的crc值就是进行CRC16-CCITT校验的结果。
整个函数的目的就是计算出一串数据的CRC16-CCITT校验值crc,并将其返回。
static uint16_t CRC16(const uint8_t *arr_buff,uint16_t len)根据函数原型写函数
这是一个C语言的函数原型,它计算给定数组(arr_buff)及其长度(len)的CRC16校验和。CRC16是一种常用的循环冗余校验算法,用于检测数据传输过程中的错误。函数返回一个16位的无符号整数,即CRC16的结果。
```c
static uint16_t CRC16(const uint8_t *arr_buff, uint16_t len) {
uint16_t crc = 0xFFFF; // 初始化CRC值为所有位全为1
const uint8_t* end = arr_buff + len;
for (; arr_buff != end; ++arr_buff) {
crc ^= (*arr_buff); // 现场异或当前字节
for (int i = 0; i < 8; ++i) {
if ((crc & 0x8000) != 0) { // 如果最低位为1
crc = (crc << 1) ^ CRCTable[0]; // 计算新的CRC值,表 lookup 和左移
} else {
crc <<= 1; // 否则只做左移
}
}
}
return crc; // 返回最终的CRC16结果
}
// 这里假设CRCTable是一个预定义的CRC16查表,例如CCITT标准的CRC16-CCITT
```
阅读全文