動作環境
ideone C (gcc 6.3)
概要
I2C通信のCRC(CRC-8-CCITT)を計算する。
- Name: CRC-8
- Protected Data: read data
- Width: 8bits
- Polynomial 0x31 ($x^8 + x^5 + x^4 + 1$)
- Initialization: 0xFF
- Reflect Input: false
- Reflect Output: false
- Final XOR: 0x00
- Example: CRC(0xBEEF) = 0x92
参考
- CRC8の計算 @ プログラミングのメモ帳
情報感謝です。
実装 > ideone
上記の実装をI2C通信用のCRC-8-CCITTに変更したのが以下。
#include <stdio.h>
#include <stdint.h>
#include <limits.h> // CHAR_BIT
#define MSB_CRCS (0x31) // x8 + x5 + x4 + 1
static uint8_t calcCRC8CCITT(char *buff, size_t size)
{
uint8_t crc8;
for(crc8 = 0xFF; size != 0; size--) {
crc8 ^= *buff++;
for(int idx=0; idx < CHAR_BIT; idx++) {
if (crc8 & 0x80) {
crc8 <<=1;
crc8 ^= MSB_CRCS;
} else {
crc8 <<=1;
}
}
}
return crc8;
}
int main(void) {
uint8_t data[] = { 0xBE, 0xEF };
uint8_t crc;
crc = calcCRC8CCITT(data, 2);
printf("0x%x\n", crc);
return 0;
}
run
0x92
冒頭のExampleの通りになった。
関連
- CRC(巡回冗長検査)で適正なデータ通信を実現 @ Analog Dialogue
実装 > 組込み用Cファイル
実装中のソフトで使えるようにcファイル実装した。
単体動作時にはDEBUG_RUN マクロをアンコメントする。
crc8ccitt_180801.c
#include <stdio.h>
#include <stdint.h>
#include <limits.h> // CHAR_BIT
#include <stdbool.h>
#define MSB_CRCS (0x31) // x8 + x5 + x4 + 1
//#define DEBUG_RUN // use main() for debug
/*
* v0.1 Aug. 01, 2018
* - add [DEBUG_RUN] macro
* - add main()
* - add Test_calcCRC8CCITT()
* - add calcCRC8CCITT()
*/
// Acknowledgement:
// https://blog.goo.ne.jp/masaki_goo_2006/e/69f286d90e6140e6e8c021e43a11c815
/*
- Name: CRC-8
- Protected Data: read data
- Width: 8bits
- Polynomial 0x31 ($x^8 + x^5 + x^4 + 1$)
- Initialization: 0xFF
- Reflect Input: false
- Reflect Output: false
- Final XOR: 0x00
- Example: CRC(0xBEEF) = 0x92
*/
uint8_t calcCRC8CCITT(char *buff, size_t size)
{
uint8_t crc8;
int idx;
for(crc8 = 0xFF; size != 0; size--) {
crc8 ^= *buff++;
for(idx=0; idx < CHAR_BIT; idx++) {
if (crc8 & 0x80) {
crc8 <<=1;
crc8 ^= MSB_CRCS;
} else {
crc8 <<=1;
}
}
}
return crc8;
}
static bool Test_calcCRC8CCITT(void)
{
uint8_t data[] = { 0xBE, 0xEF };
uint8_t crc;
crc = calcCRC8CCITT(data, 2);
printf("0x%x\n", crc);
return (crc == 0x92);
}
#ifdef DEBUG_RUN
int main(void)
{
if (Test_calcCRC8CCITT()) {
printf("Test: pass\n");
} else {
printf("Test: fail\n");
}
return 0;
}
#endif
crc8ccitt_180801.h
#ifndef CRC8_CCITT_H
#define CRC8_CCITT_H
uint8_t calcCRC8CCITT(char *buff, size_t size);
#endif
stdint.hを使わない環境を考慮した方がいいかもしれない。