STM32G474硬件CRC7和软件CRC7校验

news2024/11/29 0:36:35

1、CRC7的多项式和初始值

#define CRC_Hardware_POLYNOMIAL_7B  0x09
//硬件CRC多项式为0x09
//SD卡中的校验算法CRC7,生成多项式为x^7 + x^3 + 1,由于bit7不存在,只有bit3=1和bit0=1,所以多项式为0x09

#define CRC7_INIT_VALUE      0x00  //“CRC寄存器”的初始为0x00

2、软件CRC7校验

/* Table of CRC7 values */
const unsigned char CRC7_Table[] = {
0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,
0x19,0x10,0x0b,0x02,0x3d,0x34,0x2f,0x26,0x51,0x58,0x43,0x4a,0x75,0x7c,0x67,0x6e,
0x32,0x3b,0x20,0x29,0x16,0x1f,0x04,0x0d,0x7a,0x73,0x68,0x61,0x5e,0x57,0x4c,0x45,
0x2b,0x22,0x39,0x30,0x0f,0x06,0x1d,0x14,0x63,0x6a,0x71,0x78,0x47,0x4e,0x55,0x5c,
0x64,0x6d,0x76,0x7f,0x40,0x49,0x52,0x5b,0x2c,0x25,0x3e,0x37,0x08,0x01,0x1a,0x13,
0x7d,0x74,0x6f,0x66,0x59,0x50,0x4b,0x42,0x35,0x3c,0x27,0x2e,0x11,0x18,0x03,0x0a,
0x56,0x5f,0x44,0x4d,0x72,0x7b,0x60,0x69,0x1e,0x17,0x0c,0x05,0x3a,0x33,0x28,0x21,
0x4f,0x46,0x5d,0x54,0x6b,0x62,0x79,0x70,0x07,0x0e,0x15,0x1c,0x23,0x2a,0x31,0x38,
0x41,0x48,0x53,0x5a,0x65,0x6c,0x77,0x7e,0x09,0x00,0x1b,0x12,0x2d,0x24,0x3f,0x36,
0x58,0x51,0x4a,0x43,0x7c,0x75,0x6e,0x67,0x10,0x19,0x02,0x0b,0x34,0x3d,0x26,0x2f,
0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,
0x6a,0x63,0x78,0x71,0x4e,0x47,0x5c,0x55,0x22,0x2b,0x30,0x39,0x06,0x0f,0x14,0x1d,
0x25,0x2c,0x37,0x3e,0x01,0x08,0x13,0x1a,0x6d,0x64,0x7f,0x76,0x49,0x40,0x5b,0x52,
0x3c,0x35,0x2e,0x27,0x18,0x11,0x0a,0x03,0x74,0x7d,0x66,0x6f,0x50,0x59,0x42,0x4b,
0x17,0x1e,0x05,0x0c,0x33,0x3a,0x21,0x28,0x5f,0x56,0x4d,0x44,0x7b,0x72,0x69,0x60,
0x0e,0x07,0x1c,0x15,0x2a,0x23,0x38,0x31,0x46,0x4f,0x54,0x5d,0x62,0x6b,0x70,0x79
};
//函数功能:查表计算CRC7的值
unsigned char Get_CRC7( unsigned char *buff, int len)
{
    uint16_t crc = CRC7_INIT_VALUE;   //向“CRC寄存器”写入初始为0x00
    unsigned int i= 0;

    for (i=0;  i < len; i++)
    {
        crc = CRC7_Table[(crc << 1) ^ buff[i]];
    }

    return crc;
}

3、生成CRC7的表格

#define TAB_LEN 256
//函数功能:生成CRC7的表
void Table_Gen8(void)
{
    unsigned char ccitt7 = CRC_Hardware_POLYNOMIAL_7B;  //x^7+x^3+1多项式的值为0x09
    int i,j;
    unsigned char tmp;
    unsigned char data_Buff[TAB_LEN] = {0};

    for(i=0;i<TAB_LEN;i++)
    {
        tmp = i;
        for(j=0;j<8;j++)
        {
            if(tmp & 0x80) tmp ^= ccitt7;
            tmp <<= 1;
        }
        data_Buff[i] = tmp>>1; //余数为7bit,计算中用了8bit,结尾多一位0要去掉
    }

打印CRC7表//
    for(i=0;i<TAB_LEN/8;i++)
    {
        for(j=0;j<8;j++) printf("0x%02x   ",data_Buff[i*8+j]);
        printf("\r\n");
    }
    printf("\r\n");
}

4、硬件CRC7

uint8_t Get_CRC7_A(uint8_t pBuffer[], uint8_t BufferLength)
{
    CRC_HandleTypeDef hcrc;
    uint8_t uwCRCValue;

    __HAL_RCC_CRC_CLK_ENABLE();//使能CRC外设时钟

  hcrc.Instance = CRC;

  hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;//告诉编译器将使用用户定义的“多项式”
  hcrc.Init.GeneratingPolynomial = CRC_Hardware_POLYNOMIAL_7B;
    //设置CRC_POL寄存器的值
  //用户定义的“CRC多项式”,CRC_Hardware_POLYNOMIAL_16B是用户定义的“多项式”值

  hcrc.Init.CRCLength = CRC_POLYLENGTH_7B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=11b,7位多项式
//  hcrc.Init.CRCLength = CRC_POLYLENGTH_8B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=10b,8位多项式
//  hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=01b,16位多项式
//  hcrc.Init.CRCLength = CRC_POLYLENGTH_32B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=00b,32位多项式

    hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;//告诉编译器将使用用户定义的“CRC初始值”
    hcrc.Init.InitValue=CRC7_INIT_VALUE;
    //如果使用DEFAULT_INIT_VALUE_DISABLE,则使用hcrc.Init.InitValue的值配置RC_INIT寄存器Bits 31:0(CRC_INIT[31:0])
    //用户定义的“CRC初始值”,User-defined CRC init value

  hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
    //告诉后面的计算函数将对“16位字节的数据块”进行CRC计算,调用CRC_Handle_8()
  hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
    //CRC_CR寄存器Bit6:5(REV_IN[1:0]),REV_IN[1:0]=00b,输入8位数据不执行“位反转”
  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
    //CRC_CR寄存器Bit7(REV_OUT),令REV_OUT=0,输出数据不执行“位反转”

  HAL_CRC_Init(&hcrc);
    uwCRCValue = HAL_CRC_Accumulate(&hcrc, (uint32_t *)pBuffer, BufferLength);

    return(uwCRCValue);
}

uint8_t Get_CRC7_B(uint8_t pBuffer[], uint8_t BufferLength)
{
    CRC_HandleTypeDef hcrc;
    uint8_t uwCRCValue;

    __HAL_RCC_CRC_CLK_ENABLE();//使能CRC外设时钟

  hcrc.Instance = CRC;

  hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;//告诉编译器将使用用户定义的“多项式”
  hcrc.Init.GeneratingPolynomial = CRC_Hardware_POLYNOMIAL_7B;
    //设置CRC_POL寄存器的值
  //用户定义的“CRC多项式”,CRC_Hardware_POLYNOMIAL_16B是用户定义的“多项式”值

  hcrc.Init.CRCLength = CRC_POLYLENGTH_7B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=11b,7位多项式
//  hcrc.Init.CRCLength = CRC_POLYLENGTH_8B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=10b,8位多项式
//  hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=01b,16位多项式
//  hcrc.Init.CRCLength = CRC_POLYLENGTH_32B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=00b,32位多项式

    hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;//告诉编译器将使用用户定义的“CRC初始值”
    hcrc.Init.InitValue=CRC7_INIT_VALUE;
    //如果使用DEFAULT_INIT_VALUE_DISABLE,则使用hcrc.Init.InitValue的值配置RC_INIT寄存器Bits 31:0(CRC_INIT[31:0])
    //用户定义的“CRC初始值”,User-defined CRC init value

  hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
    //告诉后面的计算函数将对“16位字节的数据块”进行CRC计算,调用CRC_Handle_8()
  hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
    //CRC_CR寄存器Bit6:5(REV_IN[1:0]),REV_IN[1:0]=00b,输入8位数据不执行“位反转”
  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
    //CRC_CR寄存器Bit7(REV_OUT),令REV_OUT=0,输出数据不执行“位反转”

  HAL_CRC_Init(&hcrc);
    uwCRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t *)pBuffer, BufferLength);
 

    return(uwCRCValue);
}

5、测试结果

#define CRC7_DATA8_Size  9
uint8_t CRC7_DATA8[CRC7_DATA8_Size]   = {0x4D,0x3C,0x2B,0x1A,0xBE,0x71,0xC9,0x8A,0x5E};
uint8_t uwExpectedCRCValue = 0x54;

void Test_CRC7(void)
{
    uint32_t uwCRCValue;

    uwCRCValue = Get_CRC7_A(CRC7_DATA8, CRC7_DATA8_Size);
    printf("hCRC1=0x%x\r\n",uwCRCValue);
    if (uwCRCValue != uwExpectedCRCValue)
    {
        printf("hCRC1 Error!\r\n");
    }

    uwCRCValue = Get_CRC7_B(CRC7_DATA8, CRC7_DATA8_Size);
    printf("hCRC2=0x%x\r\n",uwCRCValue);
    if (uwCRCValue != uwExpectedCRCValue)
    {
        printf("hCRC2 Error!\r\n");
    }

    uwCRCValue = Get_CRC7( CRC7_DATA8, CRC7_DATA8_Size);
    printf("Software_CRC=0x%x\r\n",uwCRCValue);
    if (uwCRCValue != uwExpectedCRCValue)
    {
        printf("Software_CRC Error!\r\n");
    }

    Table_Gen8();
}

6、CRC(循环冗余校验)在线计算

工具连接:CRC(循环冗余校验)在线计算_ip33.com 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基础 —— IO流详解

IO流 在Java中&#xff0c;IO&#xff08;输入/输出&#xff09;流是用于在程序与外部世界&#xff08;如文件、网络、内存等&#xff09;之间传输数据的机制。IO流分为两大类&#xff1a;输入流&#xff08;InputStream/Reader&#xff09;和输出流&#xff08;OutputStream/…

【01初识】-初识 RabbitMQ

目录 学习背景1- 初识 MQ1-1 同步调用什么是同步调用&#xff1f;小结&#xff1a;同步调用优缺点 1-2 异步调用什么是异步调用&#xff1f;小结&#xff1a;异步调用的优缺点&#xff0c;什么时候使用异步调用&#xff1f; 1-3 MQ 技术选型 学习背景 异步通讯的特点&#xff…

STK与MATLAB互联——仿真导航卫星与地面用户间距离和仰角参数

文章目录 构建GPS星座创建单个PRN的GPS卫星创建GPS星座&#xff0c;并为其添加发射机 北斗星座构建搭建低轨铱星星座构建一颗轨道高度为800km/1000km/1200km的低轨卫星构建一颗轨道高度为800km/1000km/1200km的低轨卫星建立地面站&#xff0c;可见性分析确定地面站坐标分析单颗…

Excel菜单选项无法点击?两种原因及解决方法全解析

在使用Excel处理数据时&#xff0c;有时会遇到菜单选项无法点击的情况。这种问题会影响到正常的操作和编辑。出现这种情况的原因可能有多种&#xff0c;本文将介绍两种常见的原因&#xff0c;并提供相应的解决方法&#xff0c;帮助小伙伴们快速恢复菜单选项的正常使用。 原因一…

【银河麒麟高级服务器操作系统·实例分享】裸金属服务器开机失败分析及处理建议

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 现象描述 裸金属物理服务器开机卡在EFI stub页面…

基于Spring Boot的在线摄影工作室开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…

UE5蓝图中整理节点的方法

UE5蓝图中整理节点的方法 第一种&#xff1a;子图 右键选中的节点&#xff0c;出现一个面板&#xff0c;点击 Collapse Nodes 既可折叠选中的所有节点 注意&#xff1a;子图不可以被复制使用。 双击子图可以查看节点&#xff0c;若不想折叠选中的节点为子图&#xff0c;右键点…

喜讯丨江苏省医药行业协会·中药饮片专业委员会2024年度三届五次会员代表大会暨《江苏中药饮片》通讯员年度表彰大会圆满举行

2024年10月25日&#xff0c;江苏省医药行业协会中药饮片专业委员会三届五次&#xff08;2024年度&#xff09;会员代表大会暨《江苏中药饮片》通讯员年度表彰大会在苏州香格里拉大酒店隆重召开。 江苏省药品监督管理局、药品生产监管局、江苏省医药行业协会、江苏省食品药品监督…

git push到远程怎么回退

git push到远程服务器想继续修改&#xff0c;你必须要回退然后在此提交。而且需要保留本地的修改文件。 下面给你一些git命令&#xff0c;回退很简单。 按照下面的流程操作就行&#xff1a; 1.查看提交历史 首先&#xff0c;使用git log命令查看提交历史。可以使用以下命令显…

回溯法 | 无限个for循环?

文章目录 起因实现 优化 起因 回溯算法&#xff0c;寻找问题的所有解或最优解 最开始遇到这样一个问题&#xff0c;认为可以用几个for循环暴力解决&#xff0c;然而仔细观察后发现&#xff0c;针对不同的输入&#xff0c;我需要的for循环的个数不一样&#xff0c;只能使用递归…

react18中react-thunk实现公共数据仓库的异步操作

redux及react-redux都只能实现数据的同步修改更新&#xff0c;有点类似于vue中的mutation&#xff0c;只能做同步操作&#xff0c;异步的话不用actions来实现。由于在项目始终不可避免要实现的异步数据的更新&#xff0c;这明显不够用了。是时候引入我们的异步中间件redux-thun…

原生js实现拖拽上传(拖拽时高亮上传区域)

文章目录 drop相关事件说明-MDN演示代码&#xff08;.html) drop相关事件说明-MDN 演示 代码&#xff08;.html) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"…

最新XL换脸术!EcomID,更像更强,结合InstantID和PuLID优点,200万训练集,6.6显存占用,ComfyUI

由阿里妈妈最新开源的换脸工具&#xff1a;EcomID&#xff0c;结合了InstantID和PuLID优点&#xff0c;以获得更好的背景一致性、面部关键点控制、更真实的面部以及更高的相似度。旨在从单个ID参考图像生成定制的保ID图像&#xff0c;优势在于很强的语义一致性&#xff0c;同时…

情感咨询小程序的市场需求大吗?

情感咨询小程序的市场需求较大&#xff0c;主要体现在以下几个方面&#xff1a; 情感问题普遍存在5&#xff1a; 恋爱关系困扰&#xff1a;在恋爱过程中&#xff0c;人们经常会遇到诸如沟通不畅、争吵频繁、信任危机等问题。例如&#xff0c;年轻人在恋爱初期可能会因为不了解…

技术分享 | 大语言模型增强灰盒模糊测试技术探索

大语言模型凭借其庞大的参数规模&#xff0c;能够通过无监督学习从海量文本中获取知识&#xff0c;从而不仅能够深刻理解文本语义&#xff0c;还能准确识别文本的格式和结构。凭借对不同数据结构的深度理解&#xff0c;大语言模型已在众多领域得到广泛应用。其中&#xff0c;尤…

Cmake Error:could not find any instance of Visual Studio.

出现以下错误 解决方案&#xff1a; 安装visual stuido 2017。 检查是否安装“使用C的桌面开发” 检查是否安装了扩展开发 点开“单个组件”是否安装了以下组件 编辑计算机环境变量&#xff0c;

linux查看文件命令

查看文件命令 显示命令 cat 语法&#xff1a;cat 【选项】 文件 选项 命令含义n显示行号包括空行b显示行号不包括空行s压缩空行为一行A显示隐藏字符 cat -n 文件&#xff1a;显示行号包括空行 cat -b 文件 cat -s 文件 cat -A 文件 more和less是 分页查看 tac和rev都…

使用Python统计目录下所有.txt文件中的字符数

前言 在日常开发或数据处理中&#xff0c;我们经常需要对大量文本文件进行各种统计操作&#xff0c;比如计算总字数。本文将介绍一种简单的方法&#xff0c;通过Python脚本遍历指定目录下的所有.txt文件&#xff0c;并统计这些文件中的字符总数。这个过程可以帮助开发者更好地…

【Kaggle | Pandas】练习2:索引,选择和分配

文章目录 数据总表1、读取列2、读取某列的第几行的值3、第一行数据4、读取列中前10个值5、读取索引标签为1 、 2 、 3 、 5和8的记录6、包含索引标签为0 、1 、10和100的记录的country 、province 、 region_1和region_2列7、 前 100 条记录的country和variety列8、包含Italy葡…

三款计算服务器配置→如何选择科学计算服务器?

科学计算在众多领域都扮演着关键角色&#xff0c;无论是基础科学研究还是实际工程应用&#xff0c;强大的计算能力都是不可或缺的。而选择一台合适的科学计算服务器&#xff0c;对于确保科研和工作的顺利进行至关重要。 首先&#xff0c;明确自身需求是重中之重。要仔细考虑计算…