|
AT32F437的CRC外设非常强大,可以支持输入数据按字节、半字、字格式逆转,输出数据按字格式逆转的特性可配,可以设置初始化值,可以设置多项式。感觉可以计算所有的基于CRC算法的校验公式了,但我只关心能否支持CRC32和CRC16-Modbus。前者是AT32F437默认支持,而后都则需要自己配置CRC外设参数来实现了。 根据手册与示例代码,简单研究了一下。可以确定可以使用CRC硬件外设来实现Modbus-RTU的帧完整性校验。 先来看看Modbus-RTU使用的CRC16的参数: 多项式:0x8005 多项式长度:16位 初始值:0xFFFF 按字节输入 结果异或值:0x0000 输入字节反转 输出字节反转
基于上述理论参数,我们接下来配置AT32F437的CRC外设,初始化代码如下: - static void crc16_init(void)
- {
- crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);
- crc_poly_size_set(CRC_POLY_SIZE_16B);
- crc_init_data_set(0xFFFF);
- crc_poly_value_set(0x8005);
- crc_reverse_output_data_set(CRC_REVERSE_OUTPUT_DATA);
- crc_reverse_input_data_set(CRC_REVERSE_INPUT_BY_BYTE);
- crc_data_reset();
- }
在初始化完成之后,只需要每次往CRC_DT寄存器里面写数就可以了。
- static uint16_t crc16_calc(uint8_t *buf, uint16_t len)
- {
- uint16_t i;
- uint16_t ret = 0;
- crc_data_reset();
- for (i = 0; i < len; i++)
- {
- CRC->dt = buf[i];
- }
- ret = CRC->dt;
- return (ret);
- }
硬件CRC支持CRC16-MobusRTU算法之后,再也不需要自己编写算法了,也不需要保存CRC16校验表了。又可以节省一部分软件开销,整体系统性能也有所提升。 在使用硬件CRC算法实现之后,我把完整性校验放到了串口接收中断中完成,当帧结束后,直接读出CRC_DT的值即可得到帧完整性的结果。
|