STM32L010でmodbusのCRCを計算


x 動作確認済み2022/5/26 18:36

x Mbed2です。

x 非営利、研究調査目的で引用します。


目的
modbusも使ってみたいので
「一番難しい」CRCの計算をする


![o_con494.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e27a495c-6121-13c3-38cd-46a4971d6236.jpeg)


![o_con495.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5d631c78-c0d8-d431-9c4d-e73e1d0919a9.jpeg)



参考


https://mcommit.hatenadiary.com/entry/2015/04/08/224244



https://qiita.com/ELIXIR/items/10810fed963fdddbf431



いろいろ
意味のない情報　軽くなんか食ってくるわー　2022/5/26 14:18
arduino版をそのままmbedに移植するはず?



引用元



```c++


// buf    受信データ
// length 受信データ長(CRCを除く)
unsigned short calc_crc(unsigned char *buf, int length) {
  unsigned short crc = 0xFFFF;
  int i,j;
  unsigned char carrayFlag;
  for (i = 0; i < length; i++) {
    crc ^= buf[i];
    for (j = 0; j < 8; j++) {
      carrayFlag = crc & 1;
      crc = crc >> 1;
      if (carrayFlag) {
        crc ^= 0xA001;
      }
    }
  }
  return crc;
}


```


名前は、まだない



```c++


//modbus_RTU_CRC_010_1

#include "mbed.h"

//プロトタイプ宣言
unsigned short calc_crc(unsigned char *buf, int length);


//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)


#define UART_DELAY 101 //  1/9600 98-105

DigitalOut TX(PA_2);

//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch)
{

    TX=1;
    TX=0;//Start
    wait_us(UART_DELAY);

    for(int ii=0; ii<8; ii++) { //Data x 8
        TX=(ch>>ii)&1;
        wait_us(UART_DELAY);
    }; //for

    TX=1;//Stop
    wait_us(UART_DELAY);

    return(0);

} //pc_putc



//文字列の表示
int pc_printf(char *str1)
{

    //文字の中身がゼロか
    while (*str1) {

        //一文字出力
        pc_putc(*str1 ++);

    } //while

    //戻り値
    return (0);
}//pc_printf


void pc_printf_num(int num1)
{

    //表示 debug
    char out_buff[8];
    out_buff[3] = 0;
    out_buff[2] = '0' + (  num1 - (DIV10(num1) * 10)  );  // '0'+(b%10)
    num1 = DIV10(num1);
    out_buff[1] = '0' + (  num1 - (DIV10(num1) * 10)  );  // '0'+(b%10)
    out_buff[0] = '0' +  DIV10(num1);                  // '0'+(s/10)

    //送信処理
    //send 8 byte
    pc_printf(out_buff);
    //pc_printf("\r\n");

}// pc_printf_num


char c_hex[] = {
    '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};

void pc_printf_hex(char ch1)
{


    //デバッグ用出力に送信
    //ヘキサに値を設定
    // packet move
    char out_buff[8];
    out_buff[0] = '[';
    out_buff[1] = c_hex[(ch1 >> 4) & 0x0f];
    out_buff[2] = c_hex[ch1 & 0x0f];
    out_buff[3] = ']';
    out_buff[4] = 0x00;

    //送信処理
    //send 8 byte
    pc_printf(out_buff);
    //pc_printf("\r\n");

}//pc_printf_hex


//メイン関数
int main()
{

    pc_printf("<ST>\r\n");


    //無限ループ
    while(1) {

        pc_printf_num(123);
        pc_printf("\r\n");

        pc_printf_hex(0x12);
        pc_printf("\r\n");

        unsigned char buff1[] = { 0x01, 0x06, 0, 0, 1, 1 };

        int ret = calc_crc( buff1, 6);

        pc_printf("-01 06 00 00 01 01-");
        pc_printf_hex((char)  (  ret     & 0xff)   );
        pc_printf_hex((char)  ( (ret>>8) & 0xff)   );
        pc_printf("\r\n");
        pc_printf("-49--9a-\r\n");

        //2秒の待ち
        wait_ms(2000);    //debug

    }//whil


} //main


// buf    受信データ
// length 受信データ長(CRCを除く)
unsigned short calc_crc(unsigned char *buf, int length)
{
    unsigned short crc = 0xFFFF;
    int i,j;
    unsigned char carrayFlag;
    for (i = 0; i < length; i++) {
        crc ^= buf[i];
        for (j = 0; j < 8; j++) {
            carrayFlag = crc & 1;
            crc = crc >> 1;
            if (carrayFlag) {
                crc ^= 0xA001;
            }
        }
    }
    return crc;
}


void error(const char* format, ...) {}


```