STM32G474硬件CRC16和软件CRC16校验

1、硬件CRC校验和软件CRC校验的多项式,以及初始值

#define CRC_Hardware_POLYNOMIAL_16B  0x8005
//硬件CRC多项式为0x8005
//CRC16=x^16 + x^15 + x^2 + 1,因为bit15=1,bit2=1,bit0=1,所以正向校验的多项式的值为0x8005
//CRC校验分为正向校验和反向校验,而软件CRC使用的是反向校验,其多项式为0xA001,其原因如下:
//uint32_t d;
//d= __RBIT(CRC_Hardware_POLYNOMIAL_16B)>>16;
//执行后d=0xA001,所以软件CRC使用的是反向校验。

#define CRC_SoftWare_POLYNOMIAL_16B      0xA001
#define CRC16_INIT_VALUE      0xFFFF

2、软件CRC校验

1)、通过计算得到CRC校验值

CRC(Cyclic Redundancy Check),即CRC循环冗余校验;
先向“多项式寄存器”写入0xA001,再向“CRC寄存器”存入0xFFFF,
第1个8位字符优先和“CRC寄存器”的值进行相异或(XOR),更新“CRC寄存器”,然后判断“CRC寄存器”的bit0,
如果bit0=1,则将“CRC寄存器”右移一位,最高为补0,接着将“多项式寄存器”和“CRC寄存器”的值进行相异或(XOR),更新“CRC寄存器”;
如果bit0=0,则将“CRC寄存器”右移一位,最高为补0;
判断“CRC寄存器”的bit0总计8次,所以“CRC寄存器”右移是8次;
第1个8位字符处理完后,就将第2个8位字符和“CRC寄存器”的值进行相异或(XOR),然后更新“CRC寄存器”,最后判断“CRC寄存器”的bit0,
处理方法同上。
直至将所有字节处理完,最后将“CRC寄存器”的值返回,这就是CRC校验值。

//函数功能:CRC循环冗余校验
uint16_t FrequencyConverter_Crc16(uint8_t *data,uint8_t len)
{
    uint16_t ccitt16 = CRC_SoftWare_POLYNOMIAL_16B; //向“多项式寄存器”写入0xA001
    uint16_t crc = CRC16_INIT_VALUE;     //向“CRC寄存器”存入0xFFFF
    int i;

    for(;len>0;len--)
  {
        crc^=*data;                  //异或
        for(i=0;i<8;i++)
        {
            if(crc & 0x0001)    //最低位为1
            {
                crc>>=1;            //将最低位的1移出,剩下的数与0xA001异或
                crc^=ccitt16;
            }
            else                          //最高位为0
            {
                crc>>=1;                 //直接移位
            }
        }
        data++;
    }
    return crc;
}

2)、通过查表得到CRC校验值

union
{ uint8_t b[2];
  uint16_t d; //b[1]和d的高8位值相等;b[0]和d的低8位值相等;小端存储方式
}modbus_serial_crc;

/* Table of CRC values for high byte */
const unsigned char modbus_auchCRCHi[] = {
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,
0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,
0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,
0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,
0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,
0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,
0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,
0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,
0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,
0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,
0x40
};
/* Table of CRC values for low byte */
const char modbus_auchCRCLo[] = {
0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,
0x04,0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,
0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,
0x1D,0x1C,0xDC,0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,
0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,
0x37,0xF5,0x35,0x34,0xF4,0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,
0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,
0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,
0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,
0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,
0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,0x78,0xB8,0xB9,0x79,0xBB,
0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5,
0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,0x50,0x90,0x91,
0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C,
0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,0x88,
0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,
0x40
};
//函数功能:计算CRC16,其CRC值存放在modbus_serial_crc.d中;
//这是小端计算方法

void modbus_calc_crc(uint8_t *buf,uint8_t len)
{ uint8_t i;
    uint8_t uIndex;
    uint8_t data;

  modbus_serial_crc.d=0xFFFF;

//设置modbus_serial_crc.d的初始值,为计算发送数据的CRC做准备;
  for(i=0;i<len;i++)
  {
        data=buf[i];
    uIndex = (modbus_serial_crc.b[0]) ^ data; // calculate the CRC
    modbus_serial_crc.b[0] = (modbus_serial_crc.b[1]) ^ modbus_auchCRCHi[uIndex];
    modbus_serial_crc.b[1] = modbus_auchCRCLo[uIndex];
  }
}

3、硬件CRC校验

CRC_HandleTypeDef hcrc;

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

  hcrc.Instance = CRC;

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

  hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
    //CRC_CR寄存器Bit4:3(REV_IN[1:0]),POLYSIZE[1:0]=01b,指定“多项式”长度为16位

    hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;//告诉编译器将使用用户定义的“CRC初始值”
    hcrc.Init.InitValue=CRC16_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_BYTE;
    //CRC_CR寄存器Bit6:5(REV_IN[1:0]),REV_IN[1:0]=01b,输入8位数据执行“位反转”
  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
    //CRC_CR寄存器Bit7(REV_OUT),令REV_OUT=1,输出数据执行“位反转”

  HAL_CRC_Init(&hcrc);//初始化硬件CRC
}

4、测试程序

void Test_CRC16(void)
{
    uint32_t uwCRCValue;

  uwCRCValue= __RBIT(CRC_Hardware_POLYNOMIAL_16B)>>16;

//执行后uwCRCValue=0xA001
    printf("CRC_Hardware_POLYNOMIAL_16B=0x%X\r\n",CRC_Hardware_POLYNOMIAL_16B);
    printf("uwCRCValue=0x%X\r\n",uwCRCValue);

    printf("CRC_Hardware_POLYNOMIAL_16B=0x%X\r\n",CRC_Hardware_POLYNOMIAL_16B);
    //软件计算CRC
    printf("SoftwareCRC1=0x%X\r\n",uwCRCValue);


    modbus_calc_crc( (uint8_t *)&CRC16_DATA8,BUFFER_SIZE );//查表计算CRC
    printf("SoftwareCRC2=0x%X\r\n",modbus_serial_crc.d);

    CRC16_Init();//在使用硬件CRC计算CRC之前,必须初始化一次
    uwCRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t *)&CRC16_DATA8, BUFFER_SIZE);
    //硬件计算CRC
    printf("hCRC1=0x%X\r\n",uwCRCValue);
    if (uwCRCValue != uwExpectedCRCValue)
    {
        printf("hCRC1 Error!\r\n");
    }

    CRC16_Init();//在使用硬件CRC计算CRC之前,必须初始化一次
    uwCRCValue = HAL_CRC_Accumulate(&hcrc, (uint32_t *)&CRC16_DATA8, BUFFER_SIZE);
    //硬件计算CRC
    printf("hCRC2=0x%X\r\n",uwCRCValue);
    if (uwCRCValue != uwExpectedCRCValue)
    {
        printf("hCRC2 Error!\r\n");
    }
}

5、测试结果和验证

6、CRC在线计算器

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

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

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

相关文章

UWA Gears:Frame Capture模式 - 着色器查看器

UWA Gears 是UWA最新发布的无SDK性能分析工具。针对移动平台&#xff0c;提供了实时监测和截帧分析功能&#xff0c;帮助您精准定位性能热点&#xff0c;提升应用的整体表现。 在上周的文章中&#xff0c;我们详细介绍了网格查看器的功能&#xff0c;介绍如何通过网格数据优化…

微服务电商平台课程三:基础环境搭建

后端基础环境 工具版本号功能说明下载JDK1.8java编译运行的基本环境Java Downloads | Oracledocker27.0.3容器化部署Windows | Docker Docsgit2.46.2代码版本管理&#xff0c;多人协作代码开发Git for Windowsmaven3.9.9服务的依赖管理Maven – Download Apache MavenMySQL5.7…

第十四章 章节练习echarts饼图渲染

目录 一、引言 二、完整代码 三、总结 一、引言 通过前面几个章节的学习&#xff0c;再结合日常项目中经常会使用到的echarts图&#xff0c;来完整以下功能需求&#xff0c;增强对知识点的巩固&#xff1a; 1. 基本渲染 2. 添加功能 3. 删除功能 4. 饼图渲染 运行效果图…

厨艺爱好者的在线互动平台:Spring Boot实现

摘 要 使用旧方法对厨艺交流信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在厨艺交流信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的厨艺交流平台功能…

WUP-MY-POS-PRINTER 旻佑热敏打印机票据打印uniapp插件使用说明

插件地址&#xff1a;WUP-MY-POS-PRINTER 旻佑热敏打印机票据打印安卓库 简介 本插件主要用于旻佑热敏打印机打印票据&#xff0c;不支持标签打印。适用于旻佑的各型支持票据打印的热敏打印机。本插件开发时使用的打印机型号为MY-805嵌入式面板打印机&#xff0c;其他型号请先…

2006-2023年各地级市债务余额数据

2006-2023年各地级市债务余额数据 1、时间&#xff1a;2006-2023年 2、来源&#xff1a;整理自wind 3、指标&#xff1a;地区、地方政府债-债券数量(只)、地方政府债-债券余额(亿)、地方政府债-债券余额占比(%)、城投债-债券数量(只)、城投债-债券余额(亿)、城投债-债券余额…

CentOS7安装Docker-2024

CentOS7安装Docker-2024 安装 更新yum仓库&#xff1a; yum -y update安装yum-utils并配置阿里云的docker仓库和相关插件&#xff1a; sudo yum install -y yum-utilsyum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum i…

121.WEB渗透测试-信息收集-ARL(12)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;120.WEB渗透测试-信息收集-ARL&#xff08;11&#xff09; 点击管理控制台 连接成功&…

Java | Leetcode Java题解之第513题找树左下角的值

题目&#xff1a; 题解&#xff1a; class Solution {public int findBottomLeftValue(TreeNode root) {int ret 0;Queue<TreeNode> queue new ArrayDeque<TreeNode>();queue.offer(root);while (!queue.isEmpty()) {TreeNode p queue.poll();if (p.right ! nu…

w005基于Springboot学生心理咨询评估系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

SpringCloud接入nacos配置中心

这里写自定义目录标题 版本选择项目搭建pom.xml本地的 application.ymlchenfu-miniapp-dev.yml 中的配置项接收配置的实体类 版本选择 spring-cloud-Alibaba版本依赖关系 本文章&#xff0c;采用的 springboot 版本是 2.6.13&#xff0c;spring-cloud-alibaba 版本是 2021.0.5…

(二十二)、k8s 中的关键概念

文章目录 1、总体概览2、第一层&#xff1a;物理机、集群、Node、Pod 之间的关系2、第二层&#xff1a;命名空间 Namespace3、定义4、控制平面&#xff08;Control Plane&#xff09;5、特别的概念 Service6、Deployment 经过 之前几篇文章对 k8s 的实践&#xff0c;结合实践&…

AI模型库 : 下一个大型供应链攻击目标

像 Hugging Face 这样的AI模型平台&#xff0c;很容易受到攻击者多年来通过 npm、PyPI 和其他开源存储库成功执行的同类攻击的影响 Hugging Face 等AI模型存储库为攻击者提供了与 npm 和 PyPI 等开源公共存储库相同的将恶意代码植入开发环境的机会。 在今年 4 月即将举行的 Bl…

元学习-学习笔记

学习视频&#xff1a;火炉课堂 | 元学习(meta-learning)到底是什么鬼&#xff1f;_哔哩哔哩_bilibili 一、从传统机器学习到元学习 我们传统的机器学习&#xff0c;是手工设计一个模型&#xff0c;然后将训练数据投进模型中进行训练&#xff0c;得到一个最优的模型参数&#x…

文件inode

磁盘结构&#xff1a; 众所周知扇面是磁盘存储数据的地方&#xff0c;而一个磁盘有个6个磁盘面&#xff0c;而磁头指向都是相同半径的扇面&#xff0c;所以我们可以抽象出来一个三维指针&#xff1b; 这样我们就抽象出来了一个磁盘&#xff0c;而我们的每个磁盘面都有相同名字…

MES系列- 统计过程分析(SPC)实现

MES系列文章目录 ISA-95制造业中企业和控制系统的集成的国际标准-(1) ISA-95制造业中企业和控制系统的集成的国际标准-(2) ISA-95制造业中企业和控制系统的集成的国际标准-(3) ISA-95制造业中企业和控制系统的集成的国际标准-(4) ISA-95制造业中企业和控制系统的集成的国际标准…

MMA: Multi-Modal Adapter for Vision-Language Models

两个观察 图1所示。各种基于transformer的CLIP模型中不同层的数据集级识别精度。这个实验是为了确定样本属于哪个数据集。我们用不同的种子运行了三次&#xff0c;并报告了每层识别精度的平均值和标准差。 X E m b e d XEmbed XEmbed是指变压器块之前的文本或图像嵌入层&#x…

外包干了7天,技术明显退步。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;22年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

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

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

.NET 8 Web API 中的身份验证和授权

本次介绍分为3篇文章&#xff1a; 1&#xff1a;.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2&#xff1a;在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3&#xff1a;.NET …