[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
CRCとは巡回冗長検査といい誤り検出符号の一種で主にデータ転送に伴うエラーの検出に使われています。よく使われるパリティチェック(データ内のビットが1の個数が偶数か奇数かでエラー判定する手法)や合計値チェック(すべてのバイトの合計値を使いエラーを判定する手法)よりも検出精度が高いのが特徴です。 dsPIC33CHには32bit幅まで扱えるCRCモジュールが1ch搭載されており、各種アルゴリズムに対応可能となっております。
今回はCRC-8-ATM 「x^8+x^2+x+1」という多項式を用い、4バイト長のデータから1バイトのCRCデータを算出します。
/*----------------------------------------------------------------------------------*/
/*【INC】インクルードファイル*/
/*----------------------------------------------------------------------------------*/
#include
#include
#include
/*----------------------------------------------------------------------------------*/
/*【CONST】定数定義*/
/*----------------------------------------------------------------------------------*/
#define CRC_8 0
#define CRC_8_DVB_S2 1
#define CRC_ALGORITHM CRC_8_ATM
#if (CRC_ALGORITHM == CRC_8_ATM)
#define CRC_POLYNOMIAL ((unsigned int)0x0007)
#define CRC_SEED_VALUE ((unsigned short)0x0000)// non-direct of 0x0000
#elif (CRC_ALGORITHM == CRC_8_DVB_S2)
#define CRC_POLYNOMIAL ((unsigned int)0x00D5)
#define CRC_SEED_VALUE ((unsigned short)0x0000)// non-direct of 0x0000
#endif
/*-------------------------------------------------------------------*/
/*【VARI】変数定義*/
/*-------------------------------------------------------------------*/
volatile unsigned char message[] = {0x44,0x43,0x42,0x41}; //送信メッセージ
volatile unsigned short crcResultCRC16 = 0;
/*-------------------------------------------------------------------*/
/*【PROTO】プロトタイプ宣言*/
/*-------------------------------------------------------------------*/
static unsigned short CRC_Calc(unsigned char *u1pa_Data,unsigned int u1a_Length);
/*-------------------------------------------------------------------*/
/* Main関数 */
/*-------------------------------------------------------------------*/
int main(void)
{
uint32_t u4l_Result[4];
/*------------------------------------------------------------------------------*/
/* クロック初期化*/
/*------------------------------------------------------------------------------*/
vds_Main_Init_Clock_Register(); /* クロック初期化 */
/*------------------------------------------------------------------------------*/
/* メインルーチン*/
/*------------------------------------------------------------------------------*/
while (1)
{
u4l_Result[0] = CRC_Calc(message , 4); //1回目
u4l_Result[1] = CRC_Calc(message , 4); //2回目
u4l_Result[2] = CRC_Calc(message , 4); //3回目
while (1)
{
Nop() ;
}
}
return 1;
}
CRC_Calc(unsigned char *u1pa_Data,unsigned int u1a_Length)
{
/*-------------------------------------------------------------------*/
/* CRCレジスタ設定*/
/*-------------------------------------------------------------------*/
CRCCONL = 0x00u;
CRCCONH = 0x707u;
CRCCONLbits.CRCEN = 1u;
CRCXORL = CRC_POLYNOMIAL;
CRCXORH = 0x00u;
CRCWDATL = 0x00u;
CRCWDATH = 0x00u;
CRCCONLbits.CRCGO = 1;
/*-------------------------------------------------------------------*/
/* CRCデータレジスタにデータ転送*/
/*-------------------------------------------------------------------*/
while(u1a_Length > 0)
{
*((uint8_t *)&CRCDATL) = *u1pa_Data++;
u1a_Length --;
}
CRCCONLbits.CRCGO = 1;
/*-------------------------------------------------------------------*/
/* データフラッシュ*/
/*-------------------------------------------------------------------*/
while(IFS3bits.CRCIF == 0u){;}
CRCCONLbits.CRCGO = 0u;
IFS3bits.CRCIF = 0u;
*((uint8_t *)&CRCDATL) = 0x00u;
CRCCONLbits.CRCGO = 1u;
/*-------------------------------------------------------------------*/
/* データクリーンナップ*/
/*-------------------------------------------------------------------*/
while(IFS3bits.CRCIF == 0u){;}
CRCCONHbits.DWIDTH = 8 - 1;
CRCCONLbits.CRCGO = 0u;
IFS3bits.CRCIF = 0u;
return((uint32_t)CRCWDATL & 0xFF);
}