C语言实现查表8位SAE J1850 CRC

背景:
在做霍尔采集电流的时候,CSSV1500N 系列电流传感器通过can数据输出的报文需要做crc校验,嵌入式常用查表的方式,所以就问了下deepseek怎么算这个CRC.
在这里插入图片描述

以下是使用 查表法(Lookup Table) 在C语言中高效计算8位SAE J1850 CRC的实现方法。查表法通过预先生成CRC表,避免了逐位计算,显著提升计算速度,特别适合嵌入式系统或实时性要求高的场景。


1. SAE J1850 CRC参数

  • 多项式(Polynomial)0x1D (对应多项式 ( x^8 + x^4 + x^3 + x^2 + 1 ))
  • 初始值(Initial Value)0xFF
  • 结果异或(Final XOR)0xFF
  • 输入反转(Input Reflect):无
  • 输出反转(Output Reflect):无

2. 查表法实现代码

(1) 预生成CRC表

首先生成256个元素的CRC表(每个字节值对应一个CRC值):

#include <stdint.h>// 生成SAE J1850 CRC表
static void generate_crc_table(uint8_t table[256]) {const uint8_t poly = 0x1D;for (uint16_t i = 0; i < 256; i++) {uint8_t crc = i;for (uint8_t j = 0; j < 8; j++) {if (crc & 0x80) {crc = (crc << 1) ^ poly;} else {crc <<= 1;}}table[i] = crc;}
}// 全局CRC表
static uint8_t crc_table[256];
static int is_table_generated = 0;// 初始化CRC表(只需调用一次)
void init_crc_table() {if (!is_table_generated) {generate_crc_table(crc_table);is_table_generated = 1;}
}
(2) 查表计算CRC
uint8_t crc8_sae_j1850_table(uint8_t *data, uint16_t length) {if (!is_table_generated) {init_crc_table(); // 确保表已生成}uint8_t crc = 0xFF; // 初始值for (uint16_t i = 0; i < length; i++) {crc = crc_table[crc ^ data[i]]; // 查表更新CRC}return crc ^ 0xFF; // 最终异或
}

3. 代码解释

(1) CRC表生成逻辑
  • 逐字节生成:遍历所有可能的8位值(0x00~0xFF)。
  • 逐位计算:对每个字节模拟8次位移,根据多项式决定是否异或。
  • 表格内容crc_table[i] 表示字节 i 的CRC值。
(2) 查表计算步骤
  1. 初始化CRC:初始值为 0xFF
  2. 逐字节处理
    • 将当前数据字节与CRC值异或,得到索引。
    • 通过索引直接查表获取新的CRC值。
  3. 最终异或:返回结果前异或 0xFF

4. 性能对比

方法计算复杂度内存占用适用场景
逐位计算O(n×8)极小低速或资源受限系统
查表法O(n)256字节高速、实时性要求高的系统

5. 示例测试

#include <stdio.h>int main() {uint8_t data[] = {0x12, 0x34};uint16_t length = sizeof(data) / sizeof(data[0]);init_crc_table(); // 初始化表(只需一次)uint8_t crc = crc8_sae_j1850_table(data, length);printf("CRC8 SAE J1850: 0x%02X\n", crc);return 0;
}

输出结果

CRC8 SAE J1850: 0x4B    //自己算了下,结果不一样,可能使用的环境不一样。

6. 查表法的优化原理

查表法的核心思想是 空间换时间

  • 预计算:提前将所有可能的8位输入对应的CRC值存储在表中。
  • 直接映射:运行时只需一次异或和查表操作即可处理一个字节,无需逐位计算。

7. 验证表正确性

可以通过对比查表法与逐位计算的结果来验证表的正确性:

// 逐位计算的函数(参考之前的实现)
uint8_t crc8_sae_j1850_bitwise(uint8_t *data, uint16_t length) {uint8_t crc = 0xFF;for (uint16_t i = 0; i < length; i++) {crc ^= data[i];for (uint8_t j = 0; j < 8; j++) {if (crc & 0x80) {crc = (crc << 1) ^ 0x1D;} else {crc <<= 1;}}}return crc ^ 0xFF;
}// 验证函数
void validate_table() {uint8_t test_data[] = {0x00, 0x55, 0xAA, 0xFF};for (int i = 0; i < 4; i++) {uint8_t crc_table = crc8_sae_j1850_table(&test_data[i], 1);uint8_t crc_bitwise = crc8_sae_j1850_bitwise(&test_data[i], 1);printf("Data=0x%02X, Table=0x%02X, Bitwise=0x%02X\n", test_data[i], crc_table, crc_bitwise);}
}

8. 总结

通过查表法实现SAE J1850 CRC的优点是 速度快、代码简洁,缺点是需占用256字节内存。在实际嵌入式开发中,若内存允许,推荐使用查表法提升效率。

9. 代码

#include <stdint.h>
#include <stdio.h>// 全局CRC表
static uint8_t crc_table[256];
static int is_table_generated = 0;// 生成SAE J1850 CRC表
static void generate_crc_table(uint8_t table[256]) 
{const uint8_t poly = 0x1D;for (uint16_t i = 0; i < 256; i++) {uint8_t crc = i;for (uint8_t j = 0; j < 8; j++) {if (crc & 0x80) {crc = (crc << 1) ^ poly;} else {crc <<= 1;}}table[i] = crc;}
}// 初始化CRC表(只需调用一次)
void init_crc_table() 
{if (!is_table_generated) {generate_crc_table(crc_table);is_table_generated = 1;}
}uint8_t crc8_sae_j1850_table(uint8_t *data, uint16_t length) 
{if (!is_table_generated){init_crc_table(); // 确保表已生成}uint8_t crc = 0xFF; // 初始值for (uint16_t i = 0; i < length; i++) {crc = crc_table[crc ^ data[i]]; // 查表更新CRC}return crc ^ 0xFF; // 最终异或
}int main() 
{uint8_t data[] = {0x12, 0x34};uint16_t length = sizeof(data) / sizeof(data[0]);init_crc_table(); // 初始化表(只需一次)//打印出crc表for(int i=0; i<(sizeof(crc_table)/sizeof(crc_table[0])); i++){printf("0x%02x ", crc_table[i]);if((i/8==0) && (i!=0)){printf("\r\n");} }uint8_t crc = crc8_sae_j1850_table(data, length);printf("CRC8 SAE J1850: 0x%02X\n", crc);return 0;
}

10. 运行结果

0x00 0x1d 0x3a 0x27 0x74 0x69 0x4e 0x53 
0xe8 0xf5 0xd2 0xcf 0x9c 0x81 0xa6 0xbb 
0xcd 0xd0 0xf7 0xea 0xb9 0xa4 0x83 0x9e 
0x25 0x38 0x1f 0x02 0x51 0x4c 0x6b 0x76 
0x87 0x9a 0xbd 0xa0 0xf3 0xee 0xc9 0xd4 
0x6f 0x72 0x55 0x48 0x1b 0x06 0x21 0x3c 
0x4a 0x57 0x70 0x6d 0x3e 0x23 0x04 0x19 
0xa2 0xbf 0x98 0x85 0xd6 0xcb 0xec 0xf1
0x13 0x0e 0x29 0x34 0x67 0x7a 0x5d 0x40 
0xfb 0xe6 0xc1 0xdc 0x8f 0x92 0xb5 0xa8 
0xde 0xc3 0xe4 0xf9 0xaa 0xb7 0x90 0x8d 
0x36 0x2b 0x0c 0x11 0x42 0x5f 0x78 0x65 
0x94 0x89 0xae 0xb3 0xe0 0xfd 0xda 0xc7 
0x7c 0x61 0x46 0x5b 0x08 0x15 0x32 0x2f 
0x59 0x44 0x63 0x7e 0x2d 0x30 0x17 0x0a 
0xb1 0xac 0x8b 0x96 0xc5 0xd8 0xff 0xe2 
0x26 0x3b 0x1c 0x01 0x52 0x4f 0x68 0x75 
0xce 0xd3 0xf4 0xe9 0xba 0xa7 0x80 0x9d 
0xeb 0xf6 0xd1 0xcc 0x9f 0x82 0xa5 0xb8 
0x03 0x1e 0x39 0x24 0x77 0x6a 0x4d 0x50 
0xa1 0xbc 0x9b 0x86 0xd5 0xc8 0xef 0xf2 
0x49 0x54 0x73 0x6e 0x3d 0x20 0x07 0x1a 
0x6c 0x71 0x56 0x4b 0x18 0x05 0x22 0x3f 
0x84 0x99 0xbe 0xa3 0xf0 0xed 0xca 0xd7 
0x35 0x28 0x0f 0x12 0x41 0x5c 0x7b 0x66 
0xdd 0xc0 0xe7 0xfa 0xa9 0xb4 0x93 0x8e 
0xf8 0xe5 0xc2 0xdf 0x8c 0x91 0xb6 0xab 
0x10 0x0d 0x2a 0x37 0x64 0x79 0x5e 0x43 
0xb2 0xaf 0x88 0x95 0xc6 0xdb 0xfc 0xe1 
0x5a 0x47 0x60 0x7d 0x2e 0x33 0x14 0x09 
0x7f 0x62 0x45 0x58 0x0b 0x16 0x31 0x2c 
0x97 0x8a 0xad 0xb0 0xe3 0xfe 0xd9 0xc4 CRC8 SAE J1850: 0xAC

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

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

相关文章

【UE5.3.2】初学1:适合初学者的入门路线图和建议

3D人物的动作制作 大神分析:3D人物的动作制作通常可以分为以下几个步骤: 角色绑定(Rigging):将3D人物模型绑定到一个骨骼结构上,使得模型能够进行动画控制。 动画制作(Animation):通过控制骨骼结构,制作出人物的各种动作,例如走路、跳跃、打斗等。 动画编辑(Ani…

mapreduce的工作原理

MapReduce 是 Hadoop 中实现分布式并行计算的核心框架&#xff0c;其工作原理基于“分而治之”的思想&#xff0c;将大规模数据处理任务分解为 Map&#xff08;映射&#xff09; 和 Reduce&#xff08;归约&#xff09; 两个阶段。 一、MapReduce 核心流程 1. Input 阶段 - 输…

换季推广不好做?DeepBI用一键托管的方式,让广告投放跑得快、准、稳

每年换季&#xff0c;尤其是春夏、秋冬交替的节点&#xff0c;都是电商平台上各类季节性商品扎堆上新的高峰期。无论是服饰鞋包、家居户外&#xff0c;还是母婴用品、美妆护肤&#xff0c;许多商品都有着强烈的“时间窗口效应”——一旦错过了热卖期&#xff0c;流量下滑迅速&a…

Qt5.14.2+Cmake使用mingw64位编译opencv4.5成功图文教程

​ 一、下载安装相关编译环境软件 1.1 Python3.8&#xff1a;安装路径:C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32 安装包&#xff1a;python3.8.exe 1.2 QT5.14.2&#xff1a;安装路径:C:\Qt\Qt5.14.2 1.3 opencv4.5&#xff1a;解压路径D:\o…

OpenBMC:BmcWeb 处理http请求3 字典树查找节点

OpenBMC:BmcWeb 处理http请求2 查找路由对象-CSDN博客 findRouteByPerMethod实际上是调用了perMethod.trie.find(url);来查找路由对象的 class Trie {struct FindResult{unsigned ruleIndex;std::vector<std::string> params;};FindResult findHelper(const std::string…

Openssl自签证书相关知识

1.前提 检查是否已安装 openssl $ which openssl /usr/bin/openssl 2.建立CA授权中心 2.1.生成ca私钥(ca-prikey.pem) 初始化 OpenSSL 证书颁发机构(CA)的序列号文件 在生成证书时,ca.srl 的初始序列号需正确初始化(如 01),否则可能导致证书冲突 这会将 01 显示在屏幕…

K个一组翻转链表--囊括半数链表题的思想

K 个一组翻转链表 这道算法题就是链表多个算法思想的结合&#xff0c;解决这一道leetcodehot100的链表题至少能做一半了 大概有一下几个点 1.链表定位 2.链表翻转 3.哨兵节点 4.链表合并 看看题目 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff…

Flutter敏感词过滤实战:基于AC自动机的高效解决方案

Flutter敏感词过滤实战&#xff1a;基于AC自动机的高效解决方案 在社交、直播、论坛等UGC场景中&#xff0c;敏感词过滤是保障平台安全的关键防线。本文将深入解析基于AC自动机的Flutter敏感词过滤实现方案&#xff0c;通过原理剖析实战代码性能对比&#xff0c;带你打造毫秒级…

UML中的用例图和类图

在UML&#xff08;统一建模语言&#xff09;中&#xff0c;**用例图&#xff08;Use Case Diagram&#xff09;和类图&#xff08;Class Diagram&#xff09;**是两种最常用的图表类型&#xff0c;分别用于描述系统的高层功能和静态结构。以下是它们的核心概念、用途及区别&…

深入解析:HarmonyOS Design设计语言的核心理念

深入解析&#xff1a;HarmonyOS Design设计语言的核心理念 在当今数字化迅速发展的时代&#xff0c;用户对操作系统的体验要求越来越高。华为的HarmonyOS&#xff08;鸿蒙操作系统&#xff09;应运而生&#xff0c;旨在为用户提供全场景、全设备的智慧体验。其背后的设计语言—…

Vue 类与样式

数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是 attribute&#xff0c;我们可以和其他 attribute 一样使用 v-bind 将它们和动态的字符串绑定。但是&#xff0c;在处理比较复杂的绑定时&#xff0c;通过拼接生成字符串是麻烦且易…

Android 中获取颜色资源

在 Android 开发中&#xff0c;资源&#xff08;如字符串、颜色等&#xff09;通常存储在 res 文件夹中&#xff0c;并通过资源 ID 进行访问。资源 ID 是一个整型值&#xff0c;用于唯一标识资源&#xff0c;若需要将资源转换为整型值&#xff0c;通常是指获取资源 ID 或从资源…

Linux中的文件寻址

Linux的层级结构 在Linux中一切皆文件 其中 要注意在命令行中看实际选择写哪一种路径 相对路径 绝对路径名称的简写&#xff0c;省略了用户当前所在的系统位置此名称只有在管理当前所在系统目录中子文件时才能使用系统中不以/开有的文件名称都为相对路径在程序操作时会自动…

洛谷: P1825 [USACO11OPEN] Corn Maze S

原题链接:P1825 [USACO11OPEN] Corn Maze S - 洛谷 题目描述 This past fall, Farmer John took the cows to visit a corn maze. But this wasnt just any corn maze: it featured several gravity-powered teleporter slides, which cause cows to teleport instantly from…

探秘DeepSeek:开源AI领域的创新先锋

一、引言 在人工智能迅猛发展的当下&#xff0c;众多先进的模型如雨后春笋般涌现&#xff0c;而 DeepSeek 无疑是其中备受瞩目的一颗新星。它以独特的技术优势和广泛的应用场景&#xff0c;在 AI 领域崭露头角。 二、DeepSeek 的诞生与背景 DeepSeek 由来自广东省的中国企业…

Spring Boot启动流程

1. 启动类与main方法 入口点&#xff1a;Spring Boot应用通常有一个带有SpringBootApplication注解的主类&#xff0c;并包含一个public static void main(String[] args)方法。 SpringBootApplication是一个组合注解&#xff0c;包含了&#xff1a; Configuration: 标记该类为…

设计模式——设计模式理念

文章目录 参考&#xff1a;[设计模式——设计模式理念](https://mp.weixin.qq.com/s/IEduZFF6SaeAthWFFV6zKQ)参考&#xff1a;[设计模式——工厂方法模式](https://mp.weixin.qq.com/s/7tKIPtjvDxDJm4uFnqGsgQ)参考&#xff1a;[设计模式——抽象工厂模式](https://mp.weixin.…

Android 16开发实战指南|锁屏交互+Vulkan优化全解析

一、环境搭建与项目初始化 1. 安装Android Studio Ladybug 下载地址:Android Studio官网关键配置: # 安装后立即更新SDK SDK Manager → SDK Platforms → 安装Android 16 (Preview) SDK Manager → SDK Tools → 更新Android SDK Build-Tools至34.0.0 # 通过命令行安装SDK组…

selenium应用测试场景

Selenium 是主流的 Web 自动化测试框架&#xff0c;主要用于基于浏览器的 Web 应用测试。以下是 Selenium 的典型测试场景和适用场景&#xff0c;以及与 Appium 的对比&#xff1a; 1. Selenium 的核心测试场景 (1) Web 功能测试&#xff08;Functional Testing&#xff09; 表…

[Vue]生命周期

在编程领域生命周期指的即一个对象从创建到销毁的过程。 Vue的生命周期大概分为四个阶段&#xff1a; 创建阶段 在该阶段&#xff0c;vue的主要工作是为渲染模板做准备工作。比如处理data中的数据&#xff0c;使其变为响应式数据。在html中普通的数据往往不具备响应式等一系列…