1. 程式人生 > >51核心微控制器實現CRC-16校驗,同樣適用於51核心的其他晶片(只要稍微修改一下PIC晶片同樣適用)

51核心微控制器實現CRC-16校驗,同樣適用於51核心的其他晶片(只要稍微修改一下PIC晶片同樣適用)

#include "reg52.h"

#define uint8  unsigned char
#define uint16 unsigned int

unsigned char str[]={0x28,0x6D,0x00,0x85,0x00,0x00,0x00,0xCF};

uint16 CRC_16_UP_Bit(uint8 * dat, uint8 len, uint16 oldcrc);
uint16 CRC_16_UP_NiByte(uint8 * dat, uint8 len, uint16 oldcrc);
uint16 CRC_16_UP_Byte(uint8 * dat, uint8 len, uint16 oldcrc);
/*CRC的初始值為0x00,多項式為0xff00,高位在先 */

/*方法一 */
//---------------------------------------
// 功能:逐位計算CRC16(UP_左移正序)
// 輸入:
//      uint8 * dat:要計算CRC的資料指標
//      uint8 len  :資料長度
//      uint16 oldcrc:CRC初始值
// 輸出:生成的新CRC值
//---------------------------------------
uint16 CRC_16_UP_Bit(uint8 * dat, uint8 len, uint16 oldcrc)
{
   uint8 idata i,j;
   uint16 idata x,crc = oldcrc;
   for(i = 0;i < len;i ++)
   {
       crc = crc ^ (dat[i] << 8);
       for (j = 8;j > 0;j --)
       {
           x = crc & 0x8000;
           crc <<= 1;
           if (x != 0)crc ^= 0xFF00;
       }
   }
   return crc;
}

/*方法二 */
//---------------------------------------
// 半位元組CRC16(UP_左移正序) 0xFF00 餘式表
//---------------------------------------
uint16 code CRC_16_UP_NiByte_Tab[ 16 ] = {
0x0000 , 0xFF00 , 0x0100 , 0xFE00 ,
0x0200 , 0xFD00 , 0x0300 , 0xFC00 ,
0x0400 , 0xFB00 , 0x0500 , 0xFA00 ,
0x0600 , 0xF900 , 0x0700 , 0xF800
};

//---------------------------------------
// 功能:半位元組查表計算CRC16(UP_左移正序)
// 輸入:
//      uint8 * dat:要計算CRC的資料指標
//      uint8 len  :資料長度
//      uint16 oldcrc:CRC初始值
// 輸出:生成的新CRC值
//---------------------------------------
uint16 CRC_16_UP_NiByte(uint8 * dat, uint8 len, uint16 oldcrc)
{
   uint8 idata i,temp;
   uint16 idata crc = oldcrc;
   for(i = 0;i < len;i ++)
   {
       temp = ((uint8)(crc >> 12)) ^ (dat[i] >> 4);
       crc <<= 4;
       crc ^= CRC_16_UP_NiByte_Tab[temp];
       temp = ((uint8)(crc >> 12)) ^ (dat[i] & 0x0F);
       crc <<= 4;
       crc ^= CRC_16_UP_NiByte_Tab[temp];
   }
   return crc;
}

/*方法三 */
//---------------------------------------
// 單位元組CRC16(UP_左移正序) 0xFF00 餘式表
//---------------------------------------
uint16 code CRC_16_UP_ByteTab[ 256 ] = {
0x0000 , 0xFF00 , 0x0100 , 0xFE00 , 0x0200 , 0xFD00 , 0x0300 , 0xFC00 ,
0x0400 , 0xFB00 , 0x0500 , 0xFA00 , 0x0600 , 0xF900 , 0x0700 , 0xF800 ,
0x0800 , 0xF700 , 0x0900 , 0xF600 , 0x0A00 , 0xF500 , 0x0B00 , 0xF400 ,
0x0C00 , 0xF300 , 0x0D00 , 0xF200 , 0x0E00 , 0xF100 , 0x0F00 , 0xF000 ,
0x1000 , 0xEF00 , 0x1100 , 0xEE00 , 0x1200 , 0xED00 , 0x1300 , 0xEC00 ,
0x1400 , 0xEB00 , 0x1500 , 0xEA00 , 0x1600 , 0xE900 , 0x1700 , 0xE800 ,
0x1800 , 0xE700 , 0x1900 , 0xE600 , 0x1A00 , 0xE500 , 0x1B00 , 0xE400 ,
0x1C00 , 0xE300 , 0x1D00 , 0xE200 , 0x1E00 , 0xE100 , 0x1F00 , 0xE000 ,
0x2000 , 0xDF00 , 0x2100 , 0xDE00 , 0x2200 , 0xDD00 , 0x2300 , 0xDC00 ,
0x2400 , 0xDB00 , 0x2500 , 0xDA00 , 0x2600 , 0xD900 , 0x2700 , 0xD800 ,
0x2800 , 0xD700 , 0x2900 , 0xD600 , 0x2A00 , 0xD500 , 0x2B00 , 0xD400 ,
0x2C00 , 0xD300 , 0x2D00 , 0xD200 , 0x2E00 , 0xD100 , 0x2F00 , 0xD000 ,
0x3000 , 0xCF00 , 0x3100 , 0xCE00 , 0x3200 , 0xCD00 , 0x3300 , 0xCC00 ,
0x3400 , 0xCB00 , 0x3500 , 0xCA00 , 0x3600 , 0xC900 , 0x3700 , 0xC800 ,
0x3800 , 0xC700 , 0x3900 , 0xC600 , 0x3A00 , 0xC500 , 0x3B00 , 0xC400 ,
0x3C00 , 0xC300 , 0x3D00 , 0xC200 , 0x3E00 , 0xC100 , 0x3F00 , 0xC000 ,
0x4000 , 0xBF00 , 0x4100 , 0xBE00 , 0x4200 , 0xBD00 , 0x4300 , 0xBC00 ,
0x4400 , 0xBB00 , 0x4500 , 0xBA00 , 0x4600 , 0xB900 , 0x4700 , 0xB800 ,
0x4800 , 0xB700 , 0x4900 , 0xB600 , 0x4A00 , 0xB500 , 0x4B00 , 0xB400 ,
0x4C00 , 0xB300 , 0x4D00 , 0xB200 , 0x4E00 , 0xB100 , 0x4F00 , 0xB000 ,
0x5000 , 0xAF00 , 0x5100 , 0xAE00 , 0x5200 , 0xAD00 , 0x5300 , 0xAC00 ,
0x5400 , 0xAB00 , 0x5500 , 0xAA00 , 0x5600 , 0xA900 , 0x5700 , 0xA800 ,
0x5800 , 0xA700 , 0x5900 , 0xA600 , 0x5A00 , 0xA500 , 0x5B00 , 0xA400 ,
0x5C00 , 0xA300 , 0x5D00 , 0xA200 , 0x5E00 , 0xA100 , 0x5F00 , 0xA000 ,
0x6000 , 0x9F00 , 0x6100 , 0x9E00 , 0x6200 , 0x9D00 , 0x6300 , 0x9C00 ,
0x6400 , 0x9B00 , 0x6500 , 0x9A00 , 0x6600 , 0x9900 , 0x6700 , 0x9800 ,
0x6800 , 0x9700 , 0x6900 , 0x9600 , 0x6A00 , 0x9500 , 0x6B00 , 0x9400 ,
0x6C00 , 0x9300 , 0x6D00 , 0x9200 , 0x6E00 , 0x9100 , 0x6F00 , 0x9000 ,
0x7000 , 0x8F00 , 0x7100 , 0x8E00 , 0x7200 , 0x8D00 , 0x7300 , 0x8C00 ,
0x7400 , 0x8B00 , 0x7500 , 0x8A00 , 0x7600 , 0x8900 , 0x7700 , 0x8800 ,
0x7800 , 0x8700 , 0x7900 , 0x8600 , 0x7A00 , 0x8500 , 0x7B00 , 0x8400 ,
0x7C00 , 0x8300 , 0x7D00 , 0x8200 , 0x7E00 , 0x8100 , 0x7F00 , 0x8000
};

//---------------------------------------
// 功能:單位元組查表計算CRC16(UP_左移正序)
// 輸入:
//      uint8 * dat:要計算CRC的資料指標
//      uint8 len  :資料長度
//      uint16 oldcrc:CRC初始值
// 輸出:生成的新CRC值
//---------------------------------------
uint16 CRC_16_UP_Byte(uint8 * dat, uint8 len, uint16 oldcrc)
{
   uint8 idata i,temp;
   uint16 idata crc = oldcrc;
   for(i = 0;i < len;i ++)
   {
       temp=(uint8)(crc >> 8) ^ dat[i];
       crc <<= 8;
       crc ^= CRC_16_UP_ByteTab[temp];
   }
   return crc;
}

void main (void)
{
  uint8 *d;
  uint16 crctest=0;
  d=&str[0];
  crctest=CRC_16_UP_Bit(d, 7, 0x0000);
  crctest=0;
  crctest=CRC_16_UP_NiByte(d, 7, 0x0000);
  crctest=0;
  crctest=CRC_16_UP_Byte(d, 7, 0x0000);

  while(1)
  {
  ;
  }
}

上面給出了3種方法,可以根據自己所使用的微控制器來選擇不同的方法,

方法一:微控制器的運算速度快,ROM比較小的情況下適用;

方法三:微控制器的運算速度慢,ROM比較大的情況下適用;

方法二:是前面兩種方法的折中選擇,我比較推薦大家用的;

用Keil uVision3編譯的結果如下:

Program Size: data=32.0 xdata=0 code=1198

"CRC16" - 0 Error(s), 0 Warning(s).

在51核心的晶片上面已經通過驗證,大家可以放心使用,各位有什麼更好的方法可以發E-Mail:[email protected]

相關推薦

51核心微控制器實現CRC-16,同樣用於51核心其他晶片(只要稍微修改一下PIC晶片同樣適用)

#include "reg52.h" #define uint8  unsigned char#define uint16 unsigned int unsigned char str[]={0x28,0x6D,0x00,0x85,0x00,0x00,0x00,0xCF};

C#完整版CRC-16演算法 CRC-16/MODBUS x16+x15+x2+1

public UInt16 Cal_crc16(byte[] data, int size) { UInt32 i = 0; UIn

兩種CRC-16的方法

轉載自:http://www.51hei.com/bbs/dpj-51955-1.html  查表法 https://zhidao.baidu.com/question/463053928.html  計演算法 兩種CRC校驗方法:查表法和計演算法。 16位CRC的多項式0

CRC原理及硬體、軟體演算法實現

轉自:http://blog.163.com/yucheng_xiao/blog/static/76600192201393092918776/  一、基本原理     CRC檢驗原理實際上就是在一個p位二進位制資料序列之後附加一個r位二進位制檢驗碼(序列),從而構成一個總長為n=p+r位的二進位制序

CRC 實現,生成碼和驗證

class CrcClass { static ushort[] crc_table = { 0x0000 , 0x1021 , 0x2042 , 0x3063 , 0x

Android註解方式實現表單

view print tde try success lte ise rdb emp 在開發中總會遇到輸入框的輸入規則限制 比如 電話輸入框電話號碼的校驗,密碼規則的校驗等 ,我們通常做法是提交操作時對每個輸入框的輸入內容進行校驗,很多的if else ,代碼看起來很亂,

CRC分段

crc16 modbus分段校驗碼: const uint8_t ModbusCRCHighTab[] = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x4

服務閘道器 Zuul 與 Redis 結合實現 Token 許可權

這兩天在寫專案的全域性許可權校驗,用 Zuul 作為服務閘道器,在 Zuul 的前置過濾器裡做的校驗。 許可權校驗或者身份驗證就不得不提 Token,目前 Token 的驗證方式有很多種,有生成 Token 後將 Token 儲存在 Redis 或資料庫的,也有很多用 JWT(JSON Web Token)

java 程式碼實現身份證合法性(全國所有地方)

很多地方可能都會用到對身份證要進行判斷校驗的功能,這個是之前在網上看到的,具體的網址都忘了,現在專案完成了,有時間把其整理下,方便自己和大家日後使用!(直接複製貼上即可) package org.asyware.insurance.util; import java.te

java實現CRC16 MODBUS演算法

最近做通訊開發,遇到了校驗碼的問題 我在這個網站上試了試 裡面有各種crc16的校驗碼 廢話不多說,直接上程式碼 /** * 計算CRC16校驗碼 * * @param bytes * @return

CRC 32

CRC即迴圈冗餘校驗碼(Cyclic Redundancy Check[1] )。它是一類重要的線性分組碼,編碼和解碼方法簡單,檢錯和糾錯能力強,在通訊領域廣泛地用於實現差錯控制。 引數模型  這個很重要,計算CRC值時,不僅僅是生成項POLY會

基於Verilog的CRC-CCITT

由於筆者在自己設計CRC模組時遇到很多問題,在網上並未找到一篇具有實際指導意義的文章,在經過多次模擬修改再模擬之後得到了正確的結果,故願意在本文中為大家提供整個設計流程供大家快速完成設計。本文章主要針對具體的實際應用給出一套親測可行的實現辦法,給出設計程式碼並提供模擬結果,供各位參考。 一.CRC概述 CRC

easyui實現輸入格式功能

首先保證easyui環境配置好之後,在需要校驗輸入的jsp頁面定義如下的function: //擴充套件校驗規則 $(function(){ var reg = /^1[3|4|5|7|8|9][0-9]{9}$/; //正則表示式 $.extend

validate實現表單

<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>validate表單校驗</title><script   type="text/jscript" src="js/j

springBoot整合CXF並實現使用者名稱密碼

話不多說直接上程式碼:準備工作:建立springBoot專案webservice_server建立springBoot專案webservice_client分別新增CXF的依賴:<!-- CXF webservice --> <dependency>

Spring AOP 實現功能許可權功能

實現功能許可權校驗的功能有多種方法,其一使用攔截器攔截請求,其二是使用AOP拋異常。 首先用攔截器實現未登入時跳轉到登入介面的功能。注意這裡沒有使用AOP切入,而是用攔截器攔截,因為AOP一般切入的是service層方法,而攔截器是攔截控制器層的請求,它本身也

Python的學習(三十) ---- Python實現檔案md5

Linux下校驗檔案MD5值,最簡單的方法就是執行md5sum命令 md5sum filename 原本打算用subprocess呼叫系統命令來獲取md5值, import subprocess,shlex cmd = "md5sum filename" p = subpr

CRC原理以及例子

一、基本原理     CRC檢驗原理實際上就是在一個p位二進位制資料序列之後附加一個r位二進位制檢驗碼(序列),從而構成一個總長為n=p+r位的二進位制序列;附加在資料序列之後的這個檢驗碼與資料序列的

一種在客戶端利用js實現對資料的方法

   通常為了減輕伺服器端的壓力會在客戶端利用js或其他指令碼對使用者填寫的需要提交的資料進行校驗,同時也會帶來使用者體驗的提升。下面介紹一種在客戶端利用js實現對資料進行校驗的方法,僅供參考。      現在假設使用者需要在客戶端通過後臺進行對產品類別的新增操作,利用js

Java實現身份證演算法

每一個身份證號碼,都不是胡亂隨機生成的,而是按照國家的規定,有規則的生成的,具體規則點選這裡檢視。我們校驗使用者的身份證輸入,僅靠簡單的位數判斷、正則校驗是達不到測試要求的,因此就需要根據國家的規定,把身份證的生成規則轉變為演算法,通過演算法來校驗使用者的輸入是