目前,在嵌入式领域,智能家居、智能工业、智能公交等等控制中,WiFi已经成为了一种普遍被采用的技术。
笔者常年在嵌入式WiFi行业做一线技术开发。本文主要介绍,我们在应用串口WiFi中遇到的通讯错误等问题的解决方法。我们知道现有的串口转WiFi的模块产品,大都采用的透传模式进行数据传输,也就是说串口设备发送到模块上面的数据,模块是不进行任何加工或者校验的,如果中间出现了接收错误,串口设备也是不知道的。这样就让我们在使用这种产品的时候,需要增加一个通讯校验过程。我们选用了常用的CRC8校验方法进行介绍。
本文以SimpleWiFi的S2W-M02为例首页-SimpleWiFi-淘宝网,通过源码的方式介绍CRC8的查表方法。
CRC校验算法,说白了,就是把需要校验的数据与多项式进行循环异或(XOR), 但进行XOR的方式与实际中数据传输时,是高位先传、还是低位先传有关。对于数据 高位先传的方式,XOR从数据的高位开始,我们就叫它顺序异或吧;对于数据低位先传的方式,XOR从数据的低位开始,我们就叫它反序异或吧。两种不同的异或方式,即使对应相同的多项式,计算出来的结果也是不一样的。
下面以顺序异或的例子说明一些计算的过程: 使用多项式:x8+x5+x4+1(二进制为:100110001) 计算一个字节:0x11(二进制为:00010001)
计算步骤:
A、 因为采用顺序异或,所以需要计算的数据左移8位, 移位后数据为:0001 0001 0000 000
B、 先进行高9bit异或(多项式为9bit),0001 0001 0000 0000,因为高9bit的最高bit为0,不需要进行异或,同理,接 下来的两bit也是0,也不需要进行进行异或。这样处理后数据为:1 0001 0000 0000;
C、 接下来最高位为1,需要进行异或操作了

从上面的计算过程可以看到,多项式最高位为1,遇到需要异或数据最高位为1时, 才进行异或计算,并且异或后,最高位就为0了,最高位为0,下次也不需要异或了, 这样需要采用代码计算的方式,就可以把最高位去掉,不需要异或,最后结果也是一样的。
我们为了减少计算步骤,或者加快计算速度。我们通常使用查表法进行。在SimpleWiFi模块中,我们就使用的查表法进行CRC8的计算。源码如下所示:
CRC-8算法参考实现
unsigned char __crc8_tbl[256]=
{
0x00,0x91,0xe3,0x72,0x07,0x96,0xe4,0x75,
0x0e,0x9f,0xed,0x7c,0x09,0x98,0xea,0x7b,
0x1c,0x8d,0xff,0x6e,0x1b,0x8a,0xf8,0x69,
0x12,0x83,0xf1,0x60,0x15,0x84,0xf6,0x67,
0x38,0xa9,0xdb,0x4a,0x3f,0xae,0xdc,0x4d,
0x36,0xa7,0xd5,0x44,0x31,0xa0,0xd2,0x43,
0x24,0xb5,0xc7,0x56,0x23,0xb2,0xc0,0x51,
0x2a,0xbb,0xc9,0x58,0x2d,0xbc,0xce,0x5f,
0x70,0xe1,0x93,0x02,0x77,0xe6,0x94,0x05,
0x7e,0xef,0x9d,0x0c,0x79,0xe8,0x9a,0x0b,
0x6c,0xfd,0x8f,0x1e,0x6b,0xfa,0x88,0x19,
0x62,0xf3,0x81,0x10,0x65,0xf4,0x86,0x17,
0x48,0xd9,0xab,0x3a,0x4f,0xde,0xac,0x3d,
0x46,0xd7,0xa5,0x34,0x41,0xd0,0xa2,0x33,
0x54,0xc5,0xb7,0x26,0x53,0xc2,0xb0,0x21,
0x5a,0xcb,0xb9,0x28,0x5d,0xcc,0xbe,0x2f,
0xe0,0x71,0x03,0x92,0xe7,0x76,0x04,0x95,
0xee,0x7f,0x0d,0x9c,0xe9,0x78,0x0a,0x9b,
0xfc,0x6d,0x1f,0x8e,0xfb,0x6a,0x18,0x89,
0xf2,0x63,0x11,0x80,0xf5,0x64,0x16,0x87,
0xd8,0x49,0x3b,0xaa,0xdf,0x4e,0x3c,0xad,
0xd6,0x47,0x35,0xa4,0xd1,0x40,0x32,0xa3,
0xc4,0x55,0x27,0xb6,0xc3,0x52,0x20,0xb1,
0xca,0x5b,0x29,0xb8,0xcd,0x5c,0x2e,0xbf,
0x90,0x01,0x73,0xe2,0x97,0x06,0x74,0xe5,
0x9e,0x0f,0x7d,0xec,0x99,0x08,0x7a,0xeb,
0x8c,0x1d,0x6f,0xfe,0x8b,0x1a,0x68,0xf9,
0x82,0x13,0x61,0xf0,0x85,0x14,0x66,0xf7,
0xa8,0x39,0x4b,0xda,0xaf,0x3e,0x4c,0xdd,
0xa6,0x37,0x45,0xd4,0xa1,0x30,0x42,0xd3,
0xb4,0x25,0x57,0xc6,0xb3,0x22,0x50,0xc1,
0xba,0x2b,0x59,0xc8,0xbd,0x2c,0x5e,0xcf
};
unsigned char GetCrc8(unsigned char *ptr, unsigned int len)
{
unsigned char crc8,data;
crc8=0;
while(len--!=0)
{
data = *ptr++;
crc8=__crc8_tbl[crc8^data];
}
return crc8;
}
通讯的双方都通过该查表法计算所要校验的数据,那么我们就很容易的识别通讯过程中出现的错误。这个就是为什么现在使用透传WiFi模块中我们经常采用的通讯校验了。

1万+

被折叠的 条评论
为什么被折叠?



