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.pswp.cn/web/74102.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74102.shtml
英文地址,請注明出處:http://en.pswp.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中普通的數據往往不具備響應式等一系列…