LoginSignup
0
1

More than 1 year has passed since last update.

STM32L010でmodbusのCRCを計算

Last updated at Posted at 2022-05-26

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

x Mbed2です。

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

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

o_con494.jpg

o_con495.jpg

参考

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

引用元



// 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;
}


名前は、まだない



//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, ...) {}


0
1
0

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
0
1