嵌入式开发:STM32 硬件 CRC 使用

测试平台:STM32G474系列
        STM32硬件的CRC不占用MCU的资源,计算速度快。由于硬件CRC需要配置一些选项,配置不对就会导致计算结果错误,导致使用上没有软件计算CRC方便。但硬件CRC更快的速度在一些有时间资源要求的场合还是非常适合,没计算时间要求的还是用软件CRC更方便通用。

1.软件CRC16代码

//*****************************************************************************
//
//! 计算所选 CRC 多项式的 16 位 CRC。
//! \fn uint16_t calculateCRC(const uint8_t dataBytes[], uint8_t numberBytes, uint16_t initialValue)
//!
//! \param dataBytes[] 指向数据字节数组中第一个元素的指针
//! \param numberBytes CRC计算中使用的字节数
//! \param initialValue 初始值,第一次使用时使用0xFFFF,循环计算时输入上一次的结果
//! \return 16-bit  CRC16 结果
//
//*****************************************************************************
uint16_t calculateCRC(const uint8_t dataBytes[], uint8_t numberBytes, uint16_t initialValue)
{int         bitIndex, byteIndex;bool        dataMSb;						bool        crcMSb;						    uint8_t     bytesPerWord = wlength_byte_values[WLENGTH];uint16_t crc = initialValue;#ifdef CRC_CCITT  //多项式公式/* CCITT CRC polynomial = x^16 + x^12 + x^5 + 1 */const uint16_t poly = 0x1021;#endif#ifdef CRC_ANSI/* ANSI CRC polynomial = x^16 + x^15 + x^2 + 1 */const uint16_t poly = 0x8005;#endiffor (byteIndex = 0; byteIndex < numberBytes; byteIndex++){bitIndex = 0x80u;while (bitIndex > 0){dataMSb = (bool) (dataBytes[byteIndex] & bitIndex);crcMSb  = (bool) (crc & 0x8000u);crc <<= 1;              if (dataMSb ^ crcMSb){crc ^= poly;        }bitIndex >>= 1;}}return crc;
}

2.STM32CubeMX CRC配置

①选择 CRC 并开启

②这里选择以CRC16来测试

③多项式,用于计算CRC16时的多项式,这个可以后面在生成的代码里面直接改。

④计算时的初始值,软件计算代码那边对应的是 initialValue 参数。

配置完成后生成代码

\Core\Src 路径下找到生成的工程里面的 crc.c文件

在以下代码中修改多项式的参数:

多项式参数,根据多项式公式算成对应的 16进制值然后赋值。

void MX_CRC_Init(void)
{/* USER CODE BEGIN CRC_Init 0 *//* USER CODE END CRC_Init 0 *//* USER CODE BEGIN CRC_Init 1 *//* USER CODE END CRC_Init 1 */hcrc.Instance = CRC;hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;hcrc.Init.GeneratingPolynomial = 0x1021;                     //在这里修改多项式hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;hcrc.Init.InitValue = 0xFFFF;                                //在这里修改初始值hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;if (HAL_CRC_Init(&hcrc) != HAL_OK){Error_Handler();}/* USER CODE BEGIN CRC_Init 2 *//* USER CODE END CRC_Init 2 */}

多项式值的计算或获取

直接获取:http://www.ip33.com/crc.html

可以通过以上网站直接计算CRC值,和获取对应多项式的16进制值。

如这次实验使用的多项式: CRC-16/CCITT   :  x16 + x12 + x5 + 1

自己计算:CRC-16/CCITT   :  x16 + x12 + x5 + 1

x16 + x12 + x5 + 1: 表示的是一个二进制数, x16表示第16位是1, x12表示第12位是1,x5表示第5位是1,其余的位置都是0。 二进制位值是从0开始计数。对应二进制值如下

x16 + x12 + x5 = 1   0001   0000  0010  0000 = 0x11020

x16 + x12 + x5 + 1 = 0x11020 +1 = 0x11021

由于是CRC16 所以取2个字节值 = 0x1021

3.CRC 库函数

参考链接:https://blog.csdn.net/usjjjsj/article/details/141832938

uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)

 以上一次CRC校验的结果作为初始值继续进行校验 (适用于连续多次校验的第2、3、4... ...次)


*hcrc: 指向 CRC_HandleTypeDef CRC 校验总控制结构体的指针
pBuffer:待校验的数据
BufferLength:待校验的数据长度
返回值:校验结果
        该函数在第一使用时需要调用HAL_CRC_Calculate,计算出第一次数据的校验位,然后由第一位的数据位的校验位作为下一位的的初始值。计算出最后一位的数据位作为整个传递数据的校验位。

uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)

使用默认初始值进行校验计算 (适用于单次校验 或 多次校验的第一次)

该函数一次性将全部数据的校验位检测出来,且初值仍为0xFFFFFFFF,或者CRC初始化时配置的初始值。

HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)

获取状态的函数

HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc
返回值:CRC校验总控制结构体内的 State 值
HAL_CRC_STATE_RESET  尚未初始化
HAL_CRC_STATE_READY 初始化并准备使用
HAL_CRC_STATE_BUSY 忙
HAL_CRC_STATE_TIMEOUT 超时
HAL_CRC_STATE_ERROR 错误

4.CRC计算

经过以上配置后,通过软件计算的CRC和硬件计算的CRC将获得相同的结果,如果有高低字节不同,可以自己调整一下。

HAL_CRC_Calculate(); //硬件计算

calculateCRC(); //软件计算,文章开始有对应的代码。

网站在线计算可作计算结果的对照:http://www.ip33.com/crc.html

感谢这两位博主的文章,在这两份文章的帮助下我成功的通过硬件CRC计算出了正确的值。

https://blog.csdn.net/usjjjsj/article/details/141832938

https://blog.csdn.net/13011803189/article/details/122366072

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/444028.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从 Reno TCP 到 Scalable TCP,HighSpeed TCP

前文 Scalable TCP 如何优化长肥管道 介绍了 Scalable TCP&#xff0c;但联系另一个类似的算法 HighSpeed TCP(简称 HSTCP)&#xff0c;就会看到一个类似从 Reno TCP 经 BIC 到 CUBIC 的路线&#xff0c;但采用了不同的策略。 Reno TCP 经 BIC 到 CUBIC 路线的核心在于 “在长…

4反馈、LC、石英、RC振荡器

1什么是振荡器&#xff1f; 我们看看振荡器在无线通信中扮演什么角色&#xff1f; 1&#xff09;无线通信的波是指电磁波‌。 2‌&#xff09;电磁波的频率高于100KHz才能在空气中传播。‌ 3&#xff09;空气中的高频电磁波的相位和振幅可以排列组合包含信息。 4&#xff09;无…

DBMS-3.4 SQL(4)——存储过程和函数触发器

本文章的素材与知识来自李国良老师和王珊老师。 存储过程和函数 一.存储过程 1.语法 2.示例 &#xff08;1&#xff09; 使用DELIMITER更换终止符后用于编写存储过程语句后&#xff0c;在下次执行SQL语句时记得再使用DELIMITER将终止符再换回分号。 使用DELIMITER更换终止符…

Ubuntu 22.04.4 LTS更换下载源

方法1&#xff1a;使用图形界面更换下载源 1. 打开软件和更新应用 2. 在Ubuntu 软件标签中&#xff0c;点击“下载自”旁边的下拉菜单&#xff0c;选择“其他” 3. 点击“选择最佳服务器”来自动选择最快的服务器 4. 选择服务器 5. 确定并关闭窗口&#xff0c;系统会提示您重新…

ElasticSearch备考 -- Multi match

一、题目 索引task有3个字段a、b、c&#xff0c;写一个查询去匹配这三个字段为mom&#xff0c;其中b的字段评分比a、c字段大一倍&#xff0c;将他们的分数相加作为最后的总分数 二、思考 通过题目要求对多个字段进行匹配查询&#xff0c;可以考虑multi match、bool query操作。…

【C++第十八章】Map和Set

Map和Set map和set的介绍 容器分为两种&#xff0c;序列式容器和关联式容器&#xff0c;序列式容器因为底层是线性序列的数据结构&#xff0c;存储的是元素本身&#xff0c;而关联式容器中不单是为了存储数据&#xff0c;还要进行查找&#xff0c;所以存储的是键值对&#xff…

网络编程(17)——asio多线程模型IOThreadPool

十七、day17 之前我们介绍了IOServicePool的方式&#xff0c;一个IOServicePool开启n个线程和n个iocontext&#xff0c;每个线程内独立运行iocontext, 各个iocontext监听各自绑定的socket是否就绪&#xff0c;如果就绪就在各自线程里触发回调函数。为避免线程安全问题&#xf…

腾讯云SDK点播播放数据

点播播放质量监控提供点播播放全链路的数据统计、质量监控及可视化分析服务。支持实时数据上报、数据聚合、多维筛选和精细化定向分析&#xff0c;可帮助企业实时掌控大盘运营状况、了解用户习惯和行为特征&#xff0c;有效指导运营决策、驱动业务增长。 注意事项 点播播放质…

Python 工具库每日推荐 【Pandas】

文章目录 引言Python数据处理库的重要性今日推荐:Pandas工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:销售数据分析案例分析高级特性数据合并和连接时间序列处理数据透视表扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 TypeScrip…

基于 CSS Grid 的简易拖拉拽 Vue3 组件,从代码到NPM发布(1)- 拖拉拽交互

基于特定的应用场景&#xff0c;需要在页面中以网格的方式&#xff0c;实现目标组件在网格中可以进行拖拉拽、修改大小等交互。本章开始分享如何一步步从代码设计&#xff0c;最后到如何在 NPM 上发布。 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug…

探索未来:mosquitto-python,AI领域的新宠

文章目录 探索未来&#xff1a;mosquitto-python&#xff0c;AI领域的新宠背景&#xff1a;为何选择mosquitto-python&#xff1f;库简介&#xff1a;mosquitto-python是什么&#xff1f;安装指南&#xff1a;如何安装mosquitto-python&#xff1f;函数用法&#xff1a;5个简单…

代码随想录算法训练营第四十六天 | 647. 回文子串,516.最长回文子序列

四十六天打卡&#xff0c;今天用动态规划解决回文问题&#xff0c;回文问题需要用二维dp解决 647.回文子串 题目链接 解题思路 没做出来&#xff0c;布尔类型的dp[i][j]&#xff1a;表示区间范围[i,j] &#xff08;注意是左闭右闭&#xff09;的子串是否是回文子串&#xff0…

深入理解Transformer的笔记记录(精简版本)---- Transformer

自注意力机制开启大规模预训练时代 1 从机器翻译模型举例 1.1把编码器和解码器联合起来看待的话,则整个流程就是(如下图从左至右所示): 1.首先,从编码器输入的句子会先经过一个自注意力层(即self-attention),它会帮助编码器在对每个单词编码时关注输入句子中的的其他单…

【JavaEE】——回显服务器的实现

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;引入 1&#xff1a;基本概念 二&#xff1a;UDP socket API使用 1&#xff1a;socke…

2-118 基于matlab的六面体建模和掉落仿真

基于matlab的六面体建模和掉落仿真&#xff0c;将对象建模为刚体来模拟将立方体扔到地面上。同时考虑地面摩擦力、刚度和阻尼所施加的力&#xff0c;在三个维度上跟踪平移运动和旋转运动。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-118 基于matla…

基于SpringBoot“花开富贵”花园管理系统【附源码】

效果如下&#xff1a; 系统注册页面 系统首页界面 植物信息详细页面 后台登录界面 管理员主界面 植物分类管理界面 植物信息管理界面 园艺记录管理界面 研究背景 随着城市化进程的加快和人们生活质量的提升&#xff0c;越来越多的人开始追求与自然和谐共生的生活方式&#xf…

使用激光跟踪仪提升码垛机器人精度

标题1.背景 码垛机器人是一种用于工业自动化的机器人&#xff0c;专门设计用来将物品按照一定的顺序和结构堆叠起来&#xff0c;通常用于仓库、物流中心和生产线上&#xff0c;它们可以自动执行重复的、高强度的搬运和堆垛任务。 图1 码垛机器人 传统调整码垛机器人的方法&a…

通信工程学习:什么是DIP数据集成点

DIP&#xff1a;数据集成点 DIP数据集成点&#xff08;Data Integration Point&#xff09;&#xff0c;简称DIP&#xff0c;是物联网技术&#xff08;IoT&#xff09;和机器到机器&#xff08;M2M&#xff09;通信中的一个重要组成部分。DIP在数据集成和传输过程中扮演着关键角…

【笔记】6.2 玻璃的成型

玻璃熔体的成型方法,有压制法(例如,制作水杯、烟灰缸等)、压延法(例如,制作压花玻璃等)、浇铸法(例如,制作光学玻璃、熔铸耐火材料、铸石等) 、吹制法(例如,制作瓶罐等空心玻璃)、拉制法(例如,制作窗用玻璃、玻璃管、玻璃纤维等)、离心法(例如,制作玻璃棉等)、喷吹法(例如,制作…

Ansible 工具从入门到使用

1. Ansible概述 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主…