【HC32L196PCTA测评】5.CRC校验+AES加密解密+TRNG测试

5.1CRC校验
CRC(Cyclic Redundancy Check)即循环冗余校验码,是数据通信领域中最常用的一种查错校验码,常用于验证接收到的数据是否完整,例如之前用到的DHTC12在接收到数据后就要用CRC来校验。
HC32L196拥有硬件CRC校验模块,支持计算CRC值(编码模式)和检验CRC值(校验模式),CRC16和CRC32的多项式
 


接下来写个程序,用CRC编码模式计算串口发送的数据的CRC,并将结果用串口返回,代码示例
 

复制

void crc_cal()

{

    uint16_t crc16;

    uint32_t crc32;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralCrc, TRUE);

    crc16 = CRC16_Get8(uart_buffer, uart_rxlen);

    crc32 = CRC32_Get8(uart_buffer, uart_rxlen);

    uart_rxlen = 0;

    uart_rxindex = 0;

    printf("crc16:%04X   crc32:%08X\r\n",crc16,crc32);

}

在timer0中判断接收完成后调用这个函数

复制

void Tim0_IRQHandler(void)

{

    //Timer0 模式0 溢出中断

    if(TRUE == Bt_GetIntFlag(TIM0, BtUevIrq))

    {

        if(uartrx_timeout > 0)

        {

            uartrx_timeout -= 1;

            if(uartrx_timeout == 0)

                crc_cal();

        }

        Bt_ClearIntFlag(TIM0,BtUevIrq); //中断标志清零

    }

}

运行效果
 

 


接下来再测试一下校验模式,用串口发送数据和CRC校验值,返回校验值是否匹配,收到的第一位为0进行CRC16检查否则进行CRC32检查,检验函数CRC16_Check和CRC32_Check在crc匹配时返回0
 

复制

void crc_cal()

{

    uint8_t crcchekresult;

    uint16_t crc16,crc16in;

    uint32_t crc32,crc32in;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralCrc, TRUE);

    if(uart_buffer[0] == 0)

    {

        crc16 = CRC16_Get8(uart_buffer+1, uart_rxlen-3);

        crc16in = (uart_buffer[uart_rxlen-2]<<8)|uart_buffer[uart_rxlen-1];

        crcchekresult = CRC16_Check8(uart_buffer+1, uart_rxlen-3,crc16in);

        printf("输入crc16:%04X 计算crc16:%04X 校验结果:%d\r\n",crc16in,crc16,crcchekresult);

    }

    else

    {

        crc32 = CRC32_Get8(uart_buffer+1, uart_rxlen-5);

        crc32in = (uart_buffer[uart_rxlen-4]<<24)|(uart_buffer[uart_rxlen-3]<<16)|(uart_buffer[uart_rxlen-2]<<8)|uart_buffer[uart_rxlen-1];

        crcchekresult = CRC32_Check8(uart_buffer+1, uart_rxlen-5,crc32in);

        printf("输入crc32:%04X 计算crc32:%04X 校验结果:%d\r\n",crc32in,crc32,crcchekresult);

    }

    uart_rxlen = 0;

    uart_rxindex = 0;

}

运行效果
 


5.2AES加密解密
AES(Advanced Encryption Standard)意思是高级加密标准,它的出现主要是为了取代DES加密算法
HC32L196拥有硬件AES模块,支持128、192和256位密钥
 


接下来使用这个模块测试一下AES加密解密,从串口接收数据第一位是0则加密否则解密,后续最长16位数据
 

复制

uint32_t aes128key[4] = {0x33221100, 0x77665544, 0xBBAA9988, 0xFFEEDDCC};

uint32_t plaindata[4] = {0};

uint32_t chiperdata[4] = {0};

void aes_test()

{

    uint8_t i=0;

    stc_aes_cfg_t stcAesCfg;    

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAes, TRUE);

    memset(plaindata,0,sizeof(plaindata));

    memset(chiperdata,0,sizeof(chiperdata));

    stcAesCfg.pu32Plaintext = (uint32_t *)plaindata;       ///< AES 明文指针

    stcAesCfg.pu32Cipher    = (uint32_t *)chiperdata;       ///< AES 密文指针

    stcAesCfg.pu32Key       = aes128key;        ///< AES 密钥指针

    stcAesCfg.enKeyLen      = AesKey128;            ///< AES 密钥长度类型

    if(uart_buffer[0] == 0)

    {

        uart_rxlen -= 1;

        while(i<uart_rxlen && i<16)

        {

            ((uint8_t *)plaindata)[i] = uart_buffer[i+1];

            i+=1;

        }

        AES_Encrypt(&stcAesCfg);

        i = 0;

        while(i<16)

        {

            Uart_SendDataPoll(M0P_UART0,((uint8_t *)chiperdata)[i]);

            i++;

        }

    }

    else

    {

        uart_rxlen -= 1;

        while(i<uart_rxlen && i<16)

        {

            ((uint8_t *)chiperdata)[i] = uart_buffer[i+1];

            i+=1;

        }

        AES_Decrypt(&stcAesCfg);

        i = 0;

        while(i<16)

        {

            Uart_SendDataPoll(M0P_UART0,((uint8_t *)plaindata)[i]);

            i++;

        }

    }

    

    uart_rxlen = 0;

    uart_rxindex = 0;

}

加密
 


解密

 


5.3TRNG测试
TRNG(True Random Number Generator)真随机数发生器,通常使用的随机函数是通过一定算法生成的伪随机数,是有规律可循的,只不过重复的周期很大
HC32L196拥有真随机数发生器模块可以产生64bits真随机数,接下来使用HC32L196的TRNG模块生成随机数,TRNG在上电时会自动生成一个随机数,之后可以调用Trng_Generate重新生成随机数
 

复制

int32_t main(void)

{

    xth_init();

    //时钟分频设置

    Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);

    Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);

    uart0_io_init();

    uart0_init();

    Sysctrl_SetPeripheralGate(SysctrlPeripheralRng, TRUE);

    Trng_Init();

    printf("上电生成随机数%08X%08X",Trng_GetData1(),Trng_GetData0());

    while(1)

    {

        yuyy_delay_ms(1000);

        Trng_Generate();

        printf("生成随机数%08X%08X",Trng_GetData1(),Trng_GetData0());

    }

}

运行效果
 


不过不知道怎么去验证生成的是不是真随机数
---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3319624-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值