文章摘要
你是否在开发方控车牌识别系统时,被CRC16校验算法卡住?本文深度解析基于多项式X16+X15+X2+1的CRC16校验计算逻辑,揭秘数据帧中校验码的生成步骤与C语言实现细节。附完整代码示例,清晰演示如何填充高低字节、处理加密与非加密控制卡,助你快速实现稳定通信。
— 此摘要由停车技术员AI分析文章内容生成

附:校验算法

CRC16 //多项式公式X16+X15+X2+1(1100 0000 0000 0101)

算法举例:

加载第一行广告内容“第一行广告” 上位机下发的数据为:

AA55 01 64 00 11 00 0B 01 B5 DA D2 BB D0 D0 B9 E3 B8 E6 X1 X2AF

其中黄色部分X1 X2 为CRC16校验值,X1为校验值高字节,X2为校验值低字节

操作流程:

如果是没加密的控制卡,X1 X2 用00 00填充

如控制卡加密了则 X1 X2用密码填充 X1 = 高字节 X2=低字节

去掉数据头(AA 55 或 55 AA)和尾(AF)

对01 64 00 11 00 0B 01 B5 DA D2 BB D0 D0 B9 E3 B8 E6 X1 X2 共进行CRC16计算

得到的CRC16校验码 0XABCD

用低字节(CD)填充X2 用AB填充X1

举例:

没加密的时候,下发的数据为:

AA55 01 64 00 11 00 0B 01 B5 DA D2 BB D0 D0 B9 E3 B8 E6 X1 X2 AF

用00 00 填充 X1 X2

对01 64 00 11 00 0B 01 B5 DA D2 BB D0 D0 B9 E3 B8 E6 00 00

计算CRC = 0XE560 填充后得到

AA55 01 64 00 11 00 0B 01 B5 DA D2 BB D0 D0 B9 E3 B8 E6 e5 60 AF

代码参考

C语言代码

static const u8 aucCRCHi[] = {

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

};

static const u8 aucCRCLo[] = {

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

};

u16 usMBCRC16( u8 * pucFrame, u8 usLen )

{

u8 ucCRCHi = 0xFF;

u8 ucCRCLo = 0xFF;

int iIndex;

while( usLen– )

{

iIndex = ucCRCLo ^ *( pucFrame++ );

ucCRCLo = ( u8 )( ucCRCHi ^ aucCRCHi[iIndex] );

ucCRCHi = aucCRCLo[iIndex];

}

return ( u16 )( ucCRCHi << 8 | ucCRCLo );

}

特别声明: 有些内容设置了积分或者小金额收费,参与下方【限时活动】即可免费获取,目的在于增加网站互动性和站点推广,望参与!
版权声明
资源使用声明:本站资源仅供内部学习研究(含软件设计思想与原理学习),严禁用于商业及其他非法用途。学习研究后请自觉删除,请勿传播,未及时删除造成的一切后果由使用者自行承担。
建议您支持正版软件及原创作者,如需商业使用请购买正版授权。
侵权与反馈:厂商技术资源以及网友投稿等内容本站仅提供信息存储空间,不拥有所有权,不承担相关法律责任。若您认为「停车技术员」发布的内容侵犯您的合法权益,或发现云盘链接失效,请及时联系我们,我们将第一时间处理。


分享是美德,转发时请务必附带本文原始链接,感谢您的理解与支持!
评论 抢沙发

请登录后发表评论

    暂无评论内容