[AT32F437] 使用AT32F437硬件CRC外设计算Modbus-RTU

[复制链接]
437|0
亿年回响 发表于 2025-10-24 17:30 | 显示全部楼层 |阅读模式
AT32F437的CRC外设非常强大,可以支持输入数据按字节、半字、字格式逆转,输出数据按字格式逆转的特性可配,可以设置初始化值,可以设置多项式。感觉可以计算所有的基于CRC算法的校验公式了,但我只关心能否支持CRC32和CRC16-Modbus。前者是AT32F437默认支持,而后都则需要自己配置CRC外设参数来实现了。
根据手册与示例代码,简单研究了一下。可以确定可以使用CRC硬件外设来实现Modbus-RTU的帧完整性校验。
先来看看Modbus-RTU使用的CRC16的参数:
  • 多项式:0x8005
  • 多项式长度:16位
  • 初始值:0xFFFF
  • 按字节输入
  • 结果异或值:0x0000
  • 输入字节反转
  • 输出字节反转

基于上述理论参数,我们接下来配置AT32F437的CRC外设,初始化代码如下:
  1. static void crc16_init(void)
  2. {
  3.   crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);
  4.   crc_poly_size_set(CRC_POLY_SIZE_16B);
  5.   crc_init_data_set(0xFFFF);
  6.   crc_poly_value_set(0x8005);
  7.   crc_reverse_output_data_set(CRC_REVERSE_OUTPUT_DATA);
  8.   crc_reverse_input_data_set(CRC_REVERSE_INPUT_BY_BYTE);
  9.   crc_data_reset();
  10. }
在初始化完成之后,只需要每次往CRC_DT寄存器里面写数就可以了。
  1. static uint16_t crc16_calc(uint8_t *buf, uint16_t len)
  2. {
  3.   uint16_t i;
  4.   uint16_t ret = 0;
  5.   crc_data_reset();
  6.   for (i = 0; i < len; i++)
  7.   {
  8.     CRC->dt = buf[i];
  9.   }
  10.   ret = CRC->dt;
  11.   return (ret);
  12. }

硬件CRC支持CRC16-MobusRTU算法之后,再也不需要自己编写算法了,也不需要保存CRC16校验表了。又可以节省一部分软件开销,整体系统性能也有所提升。
在使用硬件CRC算法实现之后,我把完整性校验放到了串口接收中断中完成,当帧结束后,直接读出CRC_DT的值即可得到帧完整性的结果。





您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

23

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部