嵌入式开发: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
相关文章:
嵌入式开发:STM32 硬件 CRC 使用
测试平台:STM32G474系列 STM32硬件的CRC不占用MCU的资源,计算速度快。由于硬件CRC需要配置一些选项,配置不对就会导致计算结果错误,导致使用上没有软件计算CRC方便。但硬件CRC更快的速度在一些有时间资源要求的场合还是非…...
基于STM32的智能家居语音控制系统:集成LD3320、ESP8266设计流程
一、项目概述 项目目标和用途 近年来,智能家居产品逐渐成为家庭生活中不可或缺的一部分。为了提升家庭生活的便捷性和舒适度,本项目旨在设计一款基于STM32F407VGT6(Cortex-M4内核)微控制器的多功能智能家居语音控制系统。该系统…...
【docker】要将容器中的 livox_to_pointcloud2 文件夹复制到宿主机上
复制文件夹 使用 docker cp 命令从容器复制文件夹到宿主机: docker cp <container_id_or_name>:/ws_livox/src/livox_to_pointcloud2 /path/to/host/folder sudo docker cp dandong_orin_docker:/ws_livox/src/livox_to_pointcloud2 /home...
网络编程(17)——asio多线程模型IOThreadPool
十七、day17 之前我们介绍了IOServicePool的方式,一个IOServicePool开启n个线程和n个iocontext,每个线程内独立运行iocontext, 各个iocontext监听各自绑定的socket是否就绪,如果就绪就在各自线程里触发回调函数。为避免线程安全问题…...
【rust/egui/android】在android中使用egui库
文章目录 说在前面AndroidStudio安装编译安装运行问题 说在前面 操作系统:windows11java版本:23android sdk版本:35android ndk版本:22rust版本: AndroidStudio安装 安装AndroidStudio是为了安装sdk、ndk,…...
Git---Git打标签
打标签 像其他版本控制系统(VCS)一样,Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)。 在本节中,你将会学习如…...
深入理解Transformer的笔记记录(精简版本)---- Transformer
自注意力机制开启大规模预训练时代 1 从机器翻译模型举例 1.1把编码器和解码器联合起来看待的话,则整个流程就是(如下图从左至右所示): 1.首先,从编码器输入的句子会先经过一个自注意力层(即self-attention),它会帮助编码器在对每个单词编码时关注输入句子中的的其他单…...
Ubuntu 更换内核版本
更换内核脚本 这里以更换 5.15.0-88-generic 版本内核为例 cat kernel.sh#!/bin/bashapt install linux-image-5.15.0-88-generic # Ubuntu内核切换脚本# 检查是否具有root权限 if [[ $(id -u) -ne 0 ]]; thenecho "请以root身份运行此脚本。"exit 1 fi# 检查系统是…...
博士找高校教职避坑指南:史上最全的避坑秘籍
在学术的海洋中遨游多年,博士们终于要踏上寻找高校教职的征程。这不仅是职业生涯的新起点,更是一场充满未知与挑战的冒险。今天,就让我们来聊聊那些在寻找高校教职时需要避开的坑,希望能为你的求职之路保驾护航。 1. 薪资结构&am…...
Study-Oracle-11-ORALCE19C-ADG集群搭建
一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。 一、ORACLE--ADG VS ORACLE--DG的区别 1、DG是Oracle数据库的一种灾难恢复和数据保护解决方案,它通过在主数据库和一个或多个备用数据库之间实时复制数据,提供了数据的冗余备份和故障切换功能。…...
【C++】map详解(键值对的概念,与multimap的不同)
目录 00.引言 set 和 map 的区别 键值对的概念 01.map容器 主要特性 常用操作 主要用途 02.multimap容器 特性 常用操作 用途 00.引言 set 和 map 的区别 set 和 map 都是C标准模板库(STL)中的容器,它们的区别如下:…...
私域电商新纪元:消费增值模式引领百万业绩飞跃
各位朋友,我是吴军,专注于带领大家深入探索私域电商领域的非凡魅力与潜在机会。 今天,我想与大家分享一个鼓舞人心的真实故事。在短短的一个月内,我们的合作伙伴实现了业绩的飞跃,突破百万大关,并且用户活跃…...
AAA Mysql与redis的主从复制原理
一 :Mysql主从复制 重要的两个日志文件:bin log 和 relay log bin log:二进制日志(binnary log)以事件形式记录了对MySQL数据库执行更改的所有操作。 relay log:用来保存从节点I/O线程接受的bin log日志…...
结合大语言模型的机械臂抓取操作学习
一、 大语言模型的机械臂抓取操作关键步骤 介绍如何基于大语言模型实现机械臂在PyBullet环境中的抓取操作,涵盖机器人运动学、坐标系转换、抓取候选位姿生成、开放词汇检测以及大语言模型代码生成等模块。 1. 机器人正逆运动学基本概念 正运动学: 已知机器人的关节…...
数据结构-二叉树_堆
一. 树的概念 树在我们的日常生活中随处可见,人们将生活中的树转换成存放数据的树形结构,就成了数据结构中的“树”。 如上图所示,自然界中的树有树根,有树枝,有树叶,当我们将其转换成树形结构时…...
Vscode+Pycharm+Vue.js+WEUI+django火锅(三)理解Vue
新创建的Vue项目里面很多文件,对于新手,老老实实做一下了解。 1.框架逻辑 框架的逻辑都是相通的,花点时间理一下就清晰了。 2.文件目录及文件 创建好的vue项目下,主要的文件和文件夹要先认识一下,并与框架逻辑对应起…...
溯变:守护天使 | OPENAIGC开发者大赛企业组优秀作品
在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给…...
android中byte[] buf没有结束符,new String(buf)会不会出错?
答案是:不会 看例子: 这和c是不一样的,不需要特别的在字符串后面添加一个\0结束....
鸿蒙harmonyos next flutter混合开发之开发plugin(获取操作系统版本号)
创建Plugin为my_plugin flutter create --org com.example --templateplugin --platformsandroid,ios,ohos my_plugin 创建Application为my_application flutter create --org com.example my_application flutter_application引用flutter_plugin,在pubspec.yam…...
介绍一款开源的 Modern GUI PySide6 / PyQt6的使用
首先附上大神的开源地址(自行克隆吧): https://github.com/Wanderson-Magalhaes/Modern_GUI_PyDracula_PySide6_or_PyQt6 步骤一:安装PySide6库 pip install PySide6 步骤二:运行main文件 python main.py 就得…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
