STM32G474硬件CRC7和软件CRC7校验

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 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

传输线临界长度

临界长度 临界长度是联结传输线长度与信号反射量之间的一个重要参数。如果用信号在传输线 上的时间延迟来表示传输线长度&#xff0c;临界长度在数值上可表示为 临界长度是传输线末端信号能否达到振铃的最大幅度的传输线长度临界值。传输线长度小于临界长度时&#xff0c;振铃…

微信小程序 - 动画(Animation)执行过程 / 实现过程 / 实现方式

前言 因官方文档描述不清晰,本文主要介绍微信小程序动画 实现过程 / 实现方式。 实现过程 推荐你对照 官方文档 来看本文章,这样更有利于理解。 简单来说,整个动画实现过程就三步: 创建一个动画实例 animation。调用实例的方法来描述动画。最后通过动画实例的 export 方法…

UI设计软件全景:13款工具助力创意实现

选择恰当的UI设计工具对于创建美观且用户体验良好的应用程序界面至关重要。不同的APP功能可能需要不同的界面设计软件&#xff0c;但并非所有工具都需要精通&#xff0c;熟练掌握几个常用的就足够了。以下是13款APP界面设计软件&#xff0c;它们能够为你的团队提供绘制APP界面所…

【动手学强化学习】part2-动态规划算法

阐述、总结【动手学强化学习】章节内容的学习情况&#xff0c;复现并理解代码。 文章目录 一、什么是动态规划&#xff1f;1.1概念1.2适用条件 二、算法示例2.1问题建模2.2策略迭代&#xff08;policyiteration&#xff09;算法2.2.1伪代码2.2.2完整代码2.2.3运行结果2.2.4代码…

2024年【焊工(中级)】最新解析及焊工(中级)考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 焊工&#xff08;中级&#xff09;最新解析参考答案及焊工&#xff08;中级&#xff09;考试试题解析是安全生产模拟考试一点通题库老师及焊工&#xff08;中级&#xff09;操作证已考过的学员汇总&#xff0c;相对有…

Java题集练习4

Java题集练习4 1 异常有什么用&#xff1f; 用来找到代码中产生的错误 防止运行出错2 异常在java中以什么形式存在&#xff1f; 异常在java中以类的形式存在&#xff0c;分为运行时异常和编译期异常&#xff0c;他们都在类Exception中3 异常是否可以自定义&#xff1f;如何自…

2024年【金属非金属矿山(地下矿山)安全管理人员】考试报名及金属非金属矿山(地下矿山)安全管理人员复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 金属非金属矿山&#xff08;地下矿山&#xff09;安全管理人员考试报名是安全生产模拟考试一点通生成的&#xff0c;金属非金属矿山&#xff08;地下矿山&#xff09;安全管理人员证模拟考试题库是根据金属非金属矿山…

海洋生物图像分割系统:一键训练

海洋生物图像分割系统源码&#xff06;数据集分享 [yolov8-seg-C2f-EMSCP&#xff06;yolov8-seg-dyhead等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al l…

基于SpringBoot+Vue+MySQL的房屋租赁系统

系统展示 系统背景 随着城市化进程的加速和人口流动性的增加&#xff0c;房屋租赁市场逐渐成为城市生活的重要组成部分。然而&#xff0c;传统的房屋租赁方式存在诸多问题&#xff0c;如信息不对称、交易成本高、租赁关系不稳定等&#xff0c;这些问题严重影响了租赁市场的健康…

第三届“基于模型的系统工程及数字工程大会”盛况回顾,同元软控发表精彩演讲

2024年10月27日&#xff0c;第三届“基于模型的系统工程及数字工程大会”&#xff08;MBSE&DE 2024&#xff09;在合肥召开。本届大会是中国系统工程学会第23届学术年会重点分会场论坛之一&#xff0c;由中国系统工程学会科技系统工程专业委员会联合中国图学学会数字化设计…

云原生笔记

#1024程序员节|征文# 单页应用(Single-Page Application&#xff0c;SPA) 云原生基础 云原生全景内容宽泛&#xff0c;以至于刚开始就极具挑战性。 云原生应用是高度分布式系统&#xff0c;它们存在于云中&#xff0c;并且能够对变化保持韧性。系统是由多个服务组成的&#…

在 AMD GPU 上构建解码器 Transformer 模型

Building a decoder transformer model on AMD GPU(s) — ROCm Blogs 2024年3月12日 作者 Phillip Dang. 在这篇博客中&#xff0c;我们展示了如何使用 PyTorch 2.0 和 ROCm 在单个节点上的单个和多个 AMD GPU 上运行Andrej Karpathy’s beautiful PyTorch re-implementation …

LabVIEW Modbus通讯稳定性提升

在LabVIEW开发Modbus通讯程序时&#xff0c;通讯不稳定是一个常见问题&#xff0c;可能导致数据丢失、延迟或错误。为了确保通讯的可靠性&#xff0c;可以从多个角度进行优化&#xff0c;以下是一些有效的解决方案&#xff0c;结合实际案例进行分析。 1. 优化通讯参数设置 通讯…

rtp协议:rtcp包发送和接收规则和报告!

RTCP Packet Send and Receive Rules&#xff1a; 发送和接收 RTCP 包的规则在此列出。允许在多播环境或多点单播环境中运行的实现必须满足第 6.2 节中的要求。这样的实现可以使用本节定义的算法来满足这些要求&#xff0c;或者可以使用其他算法&#xff0c;只要其性能等同或更…

泄密?不可能!谨记10个确保公司数据不泄密的措施,你必须了解!(企业防泄密的最佳选择)

泄密&#xff1f;不可能&#xff01;这10个确保公司数据不泄密的措施&#xff0c;你必须谨记&#xff01; 在数据为王的时代&#xff0c;企业信息的保密性直接关系到其核心竞争力与市场地位。 然而&#xff0c;数据泄露事件却屡见不鲜&#xff0c;给企业的声誉和利益带来巨大…

Nacos异地备份方案

Nacos sync的实现样例 项目地址 软件下载&#xff1a;https://github.com/nacos-group/nacos-sync/releases 官方文档&#xff1a;https://nacos.io/docs/v2/ecology/use-nacos-sync/#_top 介绍 NacosSync是一个支持多种注册中心的同步组件&#xff0c;基于Spring boot开发…

STL-常用容器-list

1list基本概念 **功能&#xff1a;**将数据进行链式存储 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成&#xff1a;链表由一系列结点组成 结点的组成&#xff1a;一个是存储…

qt配置https请求

qt应用版本 windows 32位 先说下心理路程&#xff0c;你能遇到的我都遇到了&#xff0c;你能想到的我都想到了&#xff0c;怎么解决看这一篇就够了&#xff0c;从上午12点到晚上12点几乎没离开电脑&#xff08;除了吃饭&#xff09;&#xff0c;对于openssl这种用的时候无感&am…

Outlook域名邮箱设置教程:配置烽火邮箱?

Outlook域名邮箱同步技巧&#xff1f;如何注册outlook域名邮箱&#xff1f; Outlook域名邮箱不仅提供了高效的邮件管理功能&#xff0c;还能与企业的域名相结合&#xff0c;提升品牌形象。烽火将详细介绍如何在Outlook中配置烽火邮箱&#xff0c;确保您能够顺利使用Outlook域名…

RabbitMQ替换默认端口

前提&#xff1a;客户通过漏洞扫描&#xff0c;发现rabbitmq中的erlang是默认端口4369&#xff0c;出于安全的考虑&#xff0c;需要将erlang的端口修改为其他的端口。 1.查看默认erlang的默认端口 netstat -plnt | grep 4369 2.关闭rabbitmq rabbitmqctl stop&#xff08;注…