1 /****************************************************** 2 *函数名称:CheckSumSum16 3 *输 入:buf 要校验的数据 4 len 校验数据的长 5 *输 出:校验和 6 *功 能:校验和-16 7 *******************************************************/ 8 uint16_t CheckSum16(uint8_t *buf,uint32_t len) 9 { 10 uint32_t i=0; 11 uint32_t Sum=0; 12 uint16_t CheckSum=0; 13 14 for (i=0;i<len;i++) 15 { 16 Sum+=*buf++; 17 } 18 CheckSum = (Sum >>16) + (Sum & 0xffff); 19 return CheckSum; 20 } 21 22 /****************************************************** 23 *函数名称:BCCVerify 24 *输 入:buf 要校验的数据 25 len 校验数据的长 26 *输 出:校验值 27 *功 能:异或校验 28 *******************************************************/ 29 uint8_t BCCVerify(uint8_t *buf,uint32_t len) 30 { 31 uint8_t s = 0; 32 uint32_t i = 0; 33 34 for(i=0;i<len;i++) 35 { 36 s = s^(*(buf+i)); 37 } 38 39 return s; 40 } 41 42 /****************************************************** 43 *函数名称:DataBCCVerify 44 *输 入:data 异或校验值 45 buf 要校验的数据 46 len 校验数据的长 47 *输 出:校验值 48 *功 能:异或校验 49 *******************************************************/ 50 uint8_t DataBCCVerify(uint8_t data,uint8_t *buf,uint32_t len) 51 { 52 uint8_t s = 0; 53 uint32_t i = 0; 54 55 s = data; 56 57 for(i=0;i<len;i++) 58 { 59 s = s^(*(buf+i)); 60 } 61 62 return s; 63 } 64 65 66 // 注意:因最高位一定为“1”,故略去 67 const unsigned short cnCRC_16 = 0x8005; 68 // CRC-16 = X16 + X15 + X2 + X0 69 const unsigned short cnCRC_CCITT = 0x1021; 70 // CRC-CCITT = X16 + X12 + X5 + X0,据说这个 16 位 CRC 多项式比上一个要好 71 const unsigned long cnCRC_32 = 0x04C10DB7; 72 // CRC-32 = X32 + X26 + X23 + X22 + X16 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + X0 73 74 /****************************************************** 75 *函数名称:BuildTable16 76 *输 入:aPoly 多项式 取值【0x8005, 0x1021 】 77 *功 能:根据多项式,生成查找表 78 (美国标准-0x8005)(CCITT-0x1021) 79 *******************************************************/ 80 void BuildTable16( unsigned short aPoly ) 81 { 82 unsigned short i, j; 83 unsigned short nData; 84 unsigned short nAccum; 85 unsigned long Table_CRC[256]; // CRC 表 86 87 for ( i = 0; i < 256; i++ ) 88 { 89 nData = ( unsigned short )( i << 8 ); 90 nAccum = 0; 91 for ( j = 0; j < 8; j++ ) 92 { 93 if ( ( nData ^ nAccum ) & 0x8000 ) 94 nAccum = ( nAccum << 1 ) ^ aPoly; 95 else 96 nAccum <<= 1; 97 nData <<= 1; 98 } 99 Table_CRC[i] = ( unsigned long )nAccum; 100 } 101 102 for(int i=0;i<256;i++) 103 printf("0x%04x, ",Table_CRC[i]); 104 } 105 106 /*CRC-16/IBM: 多项式:X16+X15+X2+1, 生成码为 0x8005.*/ 107 const unsigned short CRC16Table[256] = { 108 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 109 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 110 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 111 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, 112 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, 0x00a0, 0x80a5, 113 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, 114 0x0088, 0x808d, 0x8087, 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 115 0x8197, 0x0192, 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 116 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6, 117 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 0x0140, 0x8145, 0x814f, 0x014a, 118 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 119 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, 120 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 0x8303, 0x0306, 121 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 122 0x832b, 0x032e, 0x0324, 0x8321, 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 123 0x0374, 0x8371, 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 124 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 0x83f3, 0x03f6, 125 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9, 126 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 127 0x0384, 0x8381, 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 128 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, 0x82e3, 0x02e6, 129 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, 0x02d0, 0x82d5, 0x82df, 0x02da, 130 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 131 0x8257, 0x0252, 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 132 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 133 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 134 }; 135 136 /*CRC16-CCITT, 多项式: X16+X12+X5+1, 生成码为 0x1021.*/ 137 const unsigned short CRC16Table_CCITT[256] = { /* CRC余式表 */ 138 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 139 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 140 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 141 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 142 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 143 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 144 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 145 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 146 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 147 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 148 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 149 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 150 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 151 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 152 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 153 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 154 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 155 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 156 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 157 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 158 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 159 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 160 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 161 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 162 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 163 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 164 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 165 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 166 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 167 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 168 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 169 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 170 }; 171 172 /****************************************************** 173 *函数名称:CRC16_TABLE 174 *输 入:pszBuf 要校验的数据 175 unLength 校验数据的长 176 *输 出:校验值 【已验证】 177 *功 能:查表法计算CRC16 178 (美国标准-0x8005) 179 *******************************************************/ 180 unsigned short CRC16_TABLE( unsigned char * aData, unsigned long aSize ) 181 { 182 unsigned long i; 183 unsigned short nAccum = 0; 184 185 for ( i = 0; i < aSize; i++ ) 186 nAccum = ( nAccum << 8 ) ^ ( unsigned short )CRC16Table[( nAccum >> 8 ) ^ *aData++]; 187 return nAccum; 188 } 189 190 191 /******************************************************************************* 192 *函数名称: CRC16_BIT 193 * 功能描述: 按bit计算CRC16.(美国标准-0x8005) 【已验证】 194 * 输入参数: addr -- 待校验数据 195 * num -- 数据长度 196 * 返 回 值: 校验值 197 *******************************************************************************/ 198 unsigned short CRC16_BIT(unsigned char *addr, unsigned int num) 199 { 200 int i; 201 unsigned short POLY = 0x8005; 202 unsigned short crc = 0; 203 204 for (; num > 0; num--) /* Step through bytes in memory */ 205 { 206 crc = crc ^ (*addr++ << 8); /* Fetch byte from memory, XOR into CRC top byte*/ 207 for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */ 208 { 209 if (crc & 0x8000) /* b15 is set... */ 210 crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */ 211 else /* b15 is clear... */ 212 crc <<= 1; /* just rotate */ 213 } /* Loop for 8 bits */ 214 crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */ 215 } /* Loop until num=0 */ 216 return(crc); /* Return updated CRC */ 217 } 218 219 220 221 /****************************************************** 222 *函数名称:CRC16_CCITT_TABLE 223 *输 入:pszBuf 要校验的数据 224 unLength 校验数据的长 225 *输 出:校验值 226 *功 能:循环冗余校验-16 【已验证】 227 (CCITT标准-0x1021) 228 *******************************************************/ 229 unsigned short CRC16_CCITT_TABLE( unsigned char * aData, unsigned long aSize ) 230 { 231 unsigned long i; 232 unsigned short nAccum = 0; 233 234 for ( i = 0; i < aSize; i++ ) 235 nAccum = ( nAccum << 8 ) ^ ( unsigned short )CRC16Table_CCITT[( nAccum >> 8 ) ^ *aData++]; 236 return nAccum; 237 } 238 /******************************************************************************* 239 *函数名称: CRC16_CCITT_BIT 240 * 功能描述: 按bit计算CRC16-CCITT.(CCITT-0x1021)【已验证】 241 * 输入参数: dataIn -- 待校验数据 242 * length -- 数据长度 243 * 返 回 值: 校验值 244 *******************************************************************************/ 245 unsigned short CRC16_CCITT_BIT(unsigned char *addr, unsigned int num) 246 { 247 int i; 248 unsigned short POLY = 0x1021; 249 unsigned short crc = 0; 250 251 for (; num > 0; num--) /* Step through bytes in memory */ 252 { 253 crc = crc ^ (*addr++ << 8); /* Fetch byte from memory, XOR into CRC top byte*/ 254 for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */ 255 { 256 if (crc & 0x8000) /* b15 is set... */ 257 crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */ 258 else /* b15 is clear... */ 259 crc <<= 1; /* just rotate */ 260 } /* Loop for 8 bits */ 261 crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */ 262 } /* Loop until num=0 */ 263 return(crc); /* Return updated CRC */ 264 } 265 266 267 /* CRC32 查找表 */ 268 uint32 Crc32Table[256]= 269 { 270 0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005, 271 0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD, 272 0x4C11DB70,0x48D0C6C7,0x4593E01E,0x4152FDA9,0x5F15ADAC,0x5BD4B01B,0x569796C2,0x52568B75, 273 0x6A1936C8,0x6ED82B7F,0x639B0DA6,0x675A1011,0x791D4014,0x7DDC5DA3,0x709F7B7A,0x745E66CD, 274 0x9823B6E0,0x9CE2AB57,0x91A18D8E,0x95609039,0x8B27C03C,0x8FE6DD8B,0x82A5FB52,0x8664E6E5, 275 0xBE2B5B58,0xBAEA46EF,0xB7A96036,0xB3687D81,0xAD2F2D84,0xA9EE3033,0xA4AD16EA,0xA06C0B5D, 276 0xD4326D90,0xD0F37027,0xDDB056FE,0xD9714B49,0xC7361B4C,0xC3F706FB,0xCEB42022,0xCA753D95, 277 0xF23A8028,0xF6FB9D9F,0xFBB8BB46,0xFF79A6F1,0xE13EF6F4,0xE5FFEB43,0xE8BCCD9A,0xEC7DD02D, 278 0x34867077,0x30476DC0,0x3D044B19,0x39C556AE,0x278206AB,0x23431B1C,0x2E003DC5,0x2AC12072, 279 0x128E9DCF,0x164F8078,0x1B0CA6A1,0x1FCDBB16,0x018AEB13,0x054BF6A4,0x0808D07D,0x0CC9CDCA, 280 0x7897AB07,0x7C56B6B0,0x71159069,0x75D48DDE,0x6B93DDDB,0x6F52C06C,0x6211E6B5,0x66D0FB02, 281 0x5E9F46BF,0x5A5E5B08,0x571D7DD1,0x53DC6066,0x4D9B3063,0x495A2DD4,0x44190B0D,0x40D816BA, 282 0xACA5C697,0xA864DB20,0xA527FDF9,0xA1E6E04E,0xBFA1B04B,0xBB60ADFC,0xB6238B25,0xB2E29692, 283 0x8AAD2B2F,0x8E6C3698,0x832F1041,0x87EE0DF6,0x99A95DF3,0x9D684044,0x902B669D,0x94EA7B2A, 284 0xE0B41DE7,0xE4750050,0xE9362689,0xEDF73B3E,0xF3B06B3B,0xF771768C,0xFA325055,0xFEF34DE2, 285 0xC6BCF05F,0xC27DEDE8,0xCF3ECB31,0xCBFFD686,0xD5B88683,0xD1799B34,0xDC3ABDED,0xD8FBA05A, 286 0x690CE0EE,0x6DCDFD59,0x608EDB80,0x644FC637,0x7A089632,0x7EC98B85,0x738AAD5C,0x774BB0EB, 287 0x4F040D56,0x4BC510E1,0x46863638,0x42472B8F,0x5C007B8A,0x58C1663D,0x558240E4,0x51435D53, 288 0x251D3B9E,0x21DC2629,0x2C9F00F0,0x285E1D47,0x36194D42,0x32D850F5,0x3F9B762C,0x3B5A6B9B, 289 0x0315D626,0x07D4CB91,0x0A97ED48,0x0E56F0FF,0x1011A0FA,0x14D0BD4D,0x19939B94,0x1D528623, 290 0xF12F560E,0xF5EE4BB9,0xF8AD6D60,0xFC6C70D7,0xE22B20D2,0xE6EA3D65,0xEBA91BBC,0xEF68060B, 291 0xD727BBB6,0xD3E6A601,0xDEA580D8,0xDA649D6F,0xC423CD6A,0xC0E2D0DD,0xCDA1F604,0xC960EBB3, 292 0xBD3E8D7E,0xB9FF90C9,0xB4BCB610,0xB07DABA7,0xAE3AFBA2,0xAAFBE615,0xA7B8C0CC,0xA379DD7B, 293 0x9B3660C6,0x9FF77D71,0x92B45BA8,0x9675461F,0x8832161A,0x8CF30BAD,0x81B02D74,0x857130C3, 294 0x5D8A9099,0x594B8D2E,0x5408ABF7,0x50C9B640,0x4E8EE645,0x4A4FFBF2,0x470CDD2B,0x43CDC09C, 295 0x7B827D21,0x7F436096,0x7200464F,0x76C15BF8,0x68860BFD,0x6C47164A,0x61043093,0x65C52D24, 296 0x119B4BE9,0x155A565E,0x18197087,0x1CD86D30,0x029F3D35,0x065E2082,0x0B1D065B,0x0FDC1BEC, 297 0x3793A651,0x3352BBE6,0x3E119D3F,0x3AD08088,0x2497D08D,0x2056CD3A,0x2D15EBE3,0x29D4F654, 298 0xC5A92679,0xC1683BCE,0xCC2B1D17,0xC8EA00A0,0xD6AD50A5,0xD26C4D12,0xDF2F6BCB,0xDBEE767C, 299 0xE3A1CBC1,0xE760D676,0xEA23F0AF,0xEEE2ED18,0xF0A5BD1D,0xF464A0AA,0xF9278673,0xFDE69BC4, 300 0x89B8FD09,0x8D79E0BE,0x803AC667,0x84FBDBD0,0x9ABC8BD5,0x9E7D9662,0x933EB0BB,0x97FFAD0C, 301 0xAFB010B1,0xAB710D06,0xA6322BDF,0xA2F33668,0xBCB4666D,0xB8757BDA,0xB5365D03,0xB1F740B4 302 }; 303 304 /* 查表法计算 CRC32 / 经验证和STM32硬件CRC计算结果一致 */ 305 uint32 CRC32Software(uint8 *pData,uint16 Length) 306 { 307 308 uint32 nReg;//CRC寄存器 309 uint32 nTemp=0; 310 uint16 i, n; 311 312 nReg = 0xFFFFFFFF;// 313 for(n=0; n<Length; n++) 314 { 315 nReg ^= (uint32)pData[n]; 316 317 for(i=0; i<4; i++) 318 { 319 nTemp = Crc32Table[(uint8)(( nReg >> 24 ) & 0xff)]; //取一个字节,查表 320 nReg <<= 8; //丢掉计算过的头一个BYTE 321 nReg ^= nTemp; //与前一个BYTE的计算结果异或 322 } 323 } 324 return nReg; 325 } 326 /* STM32 的 CRC */ 327 uint32 CRC32(uint8 *pBuf, uint16 nSize) 328 { 329 uint32 index = 0; 330 CRC_ResetDR(); //复位CRC 331 for(index = 0; index < nSize; index++) 332 { 333 CRC->DR = (uint32)pBuf[index]; 334 } 335 return (CRC->DR); 336 }