5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CRC-15-CANを計算するプログラムを書いた

Last updated at Posted at 2021-02-16

#はじめに
仕事でCAN通信のプログラムを書いているんだけど、CRCエラーの表示が出る。
デバッグのために、CRCの変換プログラムが必要になっった。
CANのCRCはCRC-15という特殊なフォーマットでネット上に資料が少ない。
ソースや調べたことをまとめておくことにした。

#実装例
言語はcを使用。
(追記)コメントでint_to_binstr()の終端処理等の記述が抜けていたという指摘があり、修正した。


#include <stdio.h>
#include <stdint.h>

//  int to bin
char* int_to_binstr(char buff[], int bin, int len)
{
    int i;

    for (i = 0; i < len; i++) {
        if (bin & (1UL << (len - i - 1))) {
            buff[i] = '1';
        }
        else {
            buff[i] = '0';
        }
    }
    buff[len] = '\0';
    return buff;
}

uint16_t can_crc_next(uint16_t crc, uint8_t data)
{
    uint8_t i;
    crc ^= (uint16_t)data << 7;

    for (i = 0; i < 8; i++) {
        crc <<= 1;
        if (crc & 0x8000) {
            crc ^= 0xc599;
        }
    }
    return crc & 0x7fff;
}

void cal_crc15(unsigned char* buff, int len) {
    uint16_t crc;
    crc = 0;

    printf("crc15 0x");
    for (int i = 0; i < len; i++) {
        printf("%02X ", buff[i]);
    }

    printf("\n-> "); 

    for (int i = 0; i < len; i++) {
        crc = can_crc_next(crc, buff[i]);
    }
    char binstr[16];
    printf("0x%04X(%s)\n", crc, int_to_binstr(binstr, (int)crc, 15));
}

int main()
{
    uint8_t data[] = { 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    cal_crc15(data, 11);
}

#CRC元データについて

CRCの元データはSOFからデータまで。スタッフビットは除く。
バイナリはHEXにする。
SOF側が半端なビットになるようにする。

CRC元データ.png

uint8_t data[] = { 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

#プログラムの動作

CRCの初期値は0。


crc = 0;

データをHEXごとに取り出して7ビット左シフトしてCRCと排他的論理和をとる。


crc ^= (uint16_t)data << 7;

CRCを1ビット左シフト


crc <<= 1;

CRCの最上位ビットが1なら、CRC15の生成多項式x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1(=0xc599)との排他的論理和を取る。


        if (crc & 0x8000) {
            crc ^= 0xc599;
        }

15ビットなので16ビットの最上位ビットを省く。


return crc & 0x7fff;

#注意

CANコントローラ(MCP2515)の吐き出した値と一致することは確認できているが、CAN15の仕様と完全に一致しているかは確認できていない。
おそらく大丈夫だとは思うが。

#参考URL
http://forum.easyelectronics.ru/viewtopic.php?f=49&t=34508
https://qiita.com/niQSun/items/5bf1d8d9ceea16d83951
https://qiita.com/dearblue/items/669e2ce2fae57baf1e90
https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E5%86%97%E9%95%B7%E6%A4%9C%E6%9F%BB
https://reveng.sourceforge.io/crc-catalogue/1-15.htm#crc.cat-bits.15

5
0
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?