牛卧堂MCU技术交流

标题: M453的CRC模块计算CRC-16/MODBUS设置的问题请教 [打印本页]

作者: bsp0321    时间: 2015-12-9 11:14
标题: M453的CRC模块计算CRC-16/MODBUS设置的问题请教
本帖最后由 bsp0321 于 2015-12-9 11:18 编辑

大家好,最近在学习研讨会送的板子,有CRC模块,其中支持CRC-16: X16 + X15 + X2 + 1,我设置
CRC_CTL = ?和CRC_SEED = ?能够计算出485标准modbus的校验值。

我试验数据如下

以下是我试验的代码,几乎把所有的情况试了一遍,都没有出来,请教一下。


typedef struct Crc_Config_S
{
    uint8_t crcmode;
    /*
    This field indicates the CRC operation polynomial mode
    0 = CRC-CCITT Polynomial mode.
    1 = CRC-8 Polynomial mode.
    2 = CRC-16 Polynomial mode.
    3 = CRC-32 Polynomial mode.*/
    uint8_t datlen;
    /*
    This field indicates the write data length.
    0 = Data length is 8-bit mode.
    1 = Data length is 16-bit mode.
    2 = Data length is 32-bit mode.*/
    uint8_t chksfmt;
    /*This bit is used to enable the 1’s complement function for checksum result in CRC_CHECKSUM register
    0 = 1’s complement for CRC checksum Disabled.
    1 = 1’s complement for CRC checksum Enabled.
    */
    uint8_t datfmt;
    /*This bit is used to enable the 1’s complement function for write data value in CRC_DAT register.
    0 = 1’s complement for CRC writes data in Disabled.
    1 = 1’s complement for CRC writes data in Enabled.*/
    uint8_t chksrev;
    /*
    This bit is used to enable the bit order reverse function for write data value in CRC_CHECKSUM register.
    0 = Bit order reverse for CRC checksum Disabled.
    1 = Bit order reverse for CRC checksum Enabled.
    */
    uint8_t datrev;
    /*
    This bit is used to enable the bit order reverse function for write data value in CRC_DAT register.
    0 = Bit order reversed for CRC write data in Disabled.
    1 = Bit order reversed for CRC write data in Enabled (per byte).*/
    uint32_t seed;
   
}Crc_Config;

void Bsp_Crc_Config(Crc_Config Conf)
{
      CRC->CTL |= (Conf.crcmode<<CRC_CTL_CRCMODE_Pos)|(Conf.datlen<<CRC_CTL_DATLEN_Pos)|(Conf.chksfmt<<CRC_CTL_CHKSFMT_Pos)|(Conf.datfmt<<CRC_CTL_DATFMT_Pos)|(Conf.chksrev<<CRC_CTL_CHKSREV_Pos)|(Conf.datrev<<CRC_CTL_DATREV_Pos);
      CRC->SEED = Conf.seed;
}

void Bsp_Crc_Module_Enable(void)
{
    CLK_EnableModuleClock(CRC_MODULE);
    CRC->CTL = 1;
}


void Bsp_Crc_Module_Disable(void)
{
    CLK_DisableModuleClock(CRC_MODULE);
}

void Bsp_Crc_Controller_Reset(void)
{
    SYS_UnlockReg();
    SYS->IPRST0 |= 0x80;
    SYS->IPRST0 &= ~(0x80);
    SYS_LockReg();
}


int main()
{
    Crc_Config Conf;
    uint32_t res = 0;
    uint8_t a[8] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};
    uint8_t *b = (uint8_t *)a;
    uint32_t i,i1,i2,i3,i4,i5;
   
    /* Unlock protected registers */
    SYS_UnlockReg();

    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();


   
    Conf.crcmode = 2;
    Conf.datlen = 1;
   
    for(i1 = 0;i1<2;i1++)
    {
        if(i1 == 0)      Conf.seed = 0;
        else             Conf.seed = 0xFFFF;
        for(i2 = 0;i2<2;i2++)
        {
             Conf.chksfmt = i2;
             for(i3 = 0;i3<2;i3++)
             {
                  Conf.chksrev = i3;
                  for(i4 = 0;i4<2;i4++)
                   {
                        Conf.datfmt = i4;
                        for(i5 = 0;i5<2;i5++)
                         {
                              Conf.datrev = i5;
                              {
                                   Bsp_Crc_Controller_Reset();
                                    Bsp_Crc_Module_Enable();
                                    Bsp_Crc_Config(Conf);
                                    
                                    for(i = 0;i<8;i++)
                                    {
                                        CRC->DAT = a;
                                    }
                                    res = CRC_GetChecksum();
                                    Bsp_Crc_Module_Disable();
                              }
                         }
                   }
             }
        }
    }

    do
    {

    }
    while(1);

}

作者: bsp0321    时间: 2015-12-9 11:16
本帖最后由 bsp0321 于 2015-12-9 11:21 编辑

上面源代码中
CRC->DAT = a方括号内i;这里不知道为啥不显示方括号


作者: chhuang16    时间: 2015-12-10 11:19

CRC設定上開這兩個
CRC_WDATA_RVS
CRC_CHECKSUM_RVS
就可以跑出0x37DD的數值了

程式都幫你寫好了,你試看看吧
int main()
{
    const uint8_t acCRCSrcPattern[] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};
    uint32_t i,u32TargetChecksum = 0x37DD, u32CalChecksum = 0;


    /* Unlock protected registers */
    SYS_UnlockReg();

    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 to 115200-8n1 for print message */
    UART_Open(UART0, 115200);

Bsp_Crc_Controller_Reset();
Bsp_Crc_Module_Enable();
CRC_Open(CRC_16, CRC_WDATA_RVS|CRC_CHECKSUM_RVS, 0xFFFF, CRC_CPU_WDATA_8);
for(i = 0; i < sizeof(acCRCSrcPattern); i++)
{
        CRC_WRITE_DATA((acCRCSrcPattern[i] & 0xFF));
}
               
/* Get CRC-8 checksum value */
    u32CalChecksum = CRC_GetChecksum();
    printf("CRC checksum is 0x%X ... %s.\n", u32CalChecksum, (u32CalChecksum == u32TargetChecksum) ? "PASS" : "FAIL");

    while(1);

}


作者: bsp0321    时间: 2015-12-16 14:42
我试试,谢谢,出差好久没有来了




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2