STM32 CRC32 ( Delphi )
/* The CRC calculation unit mainly consists of a single 32-bit data register, which: is used as an input register to enter new data in the CRC calculator (when writing into the register) holds the result of the previous CRC calculation (when reading the register) Each write operation into the data register creates a combination of the previous CRC value and the new one (CRC computation is done on the whole 32-bit data word, and not byte per byte). The CPU is stalled during the computation, thus allowing back-to-back write accesses or consecutive write and read accesses, without having to insert software wait cycles. The CRC calculator can be reset to FFFF FFFFh with the RESET control bit in the CRC_CR register. This operation does not affect the contents of the CRC_IDR register POLY_USED_IN_STM32 0x04C11DB7 #define CRC_INITIALVALUE 0xFFFFFFFF 1. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); /* Enable CRC clock */ 2. // 00 01 02 03 --> 0x03020100 // 00 01 02 03 04 --> 0x03020100, 0x04000000 // 00 01 02 03 04 05 --> 0x03020100, 0x05040000 // 00 01 02 03 04 05 06 --> 0x03020100, 0x06050400 // uint32_t stm32_hw_crc32(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte) { uint32_t last_data; uint32_t NumOfDWord = NumOfByte>>2; uint32_t NumOfTailByte = NumOfByte & 3 ; CRC_ResetDR(); crc32 = CRC_CalcBlockCRC( (uint32_t *)pBuffer, NumOfDWord ); switch ( NumOfTailByte ) { case 0: return crc32; case 1: last_data = pBuffer[NumOfByte-1] << 24; break; case 2: last_data = *( (uint16_t *)(&pBuffer[NumOfByte-2]) ); last_data <<= 16; break; case 3: last_data = *( (uint16_t *)(&pBuffer[NumOfByte-3]) ); last_data <<= 8; last_data += pBuffer[NumOfByte-1]<<24; break; } return CRC_CalcCRC( last_data ); } uint32_t stm32_sw_crc32_by_bit(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte) { uint32_t last_data; uint32_t NumOfDWord = NumOfByte>>2; uint32_t NumOfTailByte = NumOfByte & 3 ; while(NumOfDWord--) { crc32 = crc32 ^ *((unsigned long *)pBuffer); pBuffer += 4; for(int i=0; i<32; i++) { if (crc32 & 0x80000000) crc32 = (crc32 << 1) ^ POLY_USED_IN_STM32; else crc32 = (crc32 << 1); } } switch ( NumOfTailByte ) { case 0: return crc32; case 1: last_data = pBuffer[0] << 24; break; case 2: last_data = *( (uint16_t *)(&pBuffer[0]) ); last_data <<= 16; break; case 3: last_data = *( (uint16_t *)(&pBuffer[0]) ); last_data <<= 8; last_data += pBuffer[2]<<24; break; } crc32 = stm32_sw_crc32_by_bit( crc32, (uint8_t *)&last_data, 4); return crc32; } // Nibble lookup table for 0x04C11DB7 polynomial const unsigned long sw_crc32_by_nibble_table[16] = { 0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9, 0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005, 0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61, 0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD }; uint32_t stm32_sw_crc32_by_nibble(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte) { uint32_t last_data; uint32_t NumOfDWord = NumOfByte>>2; uint32_t NumOfTailByte = NumOfByte & 3 ; while(NumOfDWord--) { crc32 = crc32 ^ *((unsigned long *)pBuffer); pBuffer += 4; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28]; } switch ( NumOfTailByte ) { case 0: return crc32; case 1: last_data = pBuffer[0] << 24; break; case 2: last_data = *( (uint16_t *)(&pBuffer[0]) ); last_data <<= 16; break; case 3: last_data = *( (uint16_t *)(&pBuffer[0]) ); last_data <<= 8; last_data += pBuffer[2]<<24; break; } crc32 = stm32_sw_crc32_by_nibble( crc32, (uint8_t *)&last_data, 4); return crc32; } unsigned long sw_crc32_by_byte_table[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, // 0..3 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, // 4..7 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, // 8..B 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, // C..F 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 }; uint32_t stm32_sw_crc32_by_byte(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte) { uint32_t last_data; uint32_t NumOfDWord = NumOfByte>>2; uint32_t NumOfTailByte = NumOfByte & 3 ; while(NumOfDWord--) { crc32 = crc32 ^ *((unsigned long *)pBuffer); pBuffer += 4; crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24]; crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24]; crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24]; crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24]; } switch ( NumOfTailByte ) { case 0: return crc32; case 1: last_data = pBuffer[0] << 24; break; case 2: last_data = *( (uint16_t *)(&pBuffer[0]) ); last_data <<= 16; break; case 3: last_data = *( (uint16_t *)(&pBuffer[0]) ); last_data <<= 8; last_data += pBuffer[2]<<24; break; } crc32 = stm32_sw_crc32_by_byte( crc32, (uint8_t *)&last_data, 4); return crc32; }
unit uCRC32; interface uses Windows; function stm32_sw_crc32_by_byte(crc32 : DWORD; pBuffer : pbyte; NumOfByte : DWORD) : DWORD; function uCrc32_Demo : DWORD; implementation const sw_crc32_by_byte_table : array[0..255] of DWORD = ( $00000000, $04c11db7, $09823b6e, $0d4326d9, // 0..3 $130476dc, $17c56b6b, $1a864db2, $1e475005, // 4..7 $2608edb8, $22c9f00f, $2f8ad6d6, $2b4bcb61, // 8..B $350c9b64, $31cd86d3, $3c8ea00a, $384fbdbd, // C..F $4c11db70, $48d0c6c7, $4593e01e, $4152fda9, $5f15adac, $5bd4b01b, $569796c2, $52568b75, $6a1936c8, $6ed82b7f, $639b0da6, $675a1011, $791d4014, $7ddc5da3, $709f7b7a, $745e66cd, $9823b6e0, $9ce2ab57, $91a18d8e, $95609039, $8b27c03c, $8fe6dd8b, $82a5fb52, $8664e6e5, $be2b5b58, $baea46ef, $b7a96036, $b3687d81, $ad2f2d84, $a9ee3033, $a4ad16ea, $a06c0b5d, $d4326d90, $d0f37027, $ddb056fe, $d9714b49, $c7361b4c, $c3f706fb, $ceb42022, $ca753d95, $f23a8028, $f6fb9d9f, $fbb8bb46, $ff79a6f1, $e13ef6f4, $e5ffeb43, $e8bccd9a, $ec7dd02d, $34867077, $30476dc0, $3d044b19, $39c556ae, $278206ab, $23431b1c, $2e003dc5, $2ac12072, $128e9dcf, $164f8078, $1b0ca6a1, $1fcdbb16, $018aeb13, $054bf6a4, $0808d07d, $0cc9cdca, $7897ab07, $7c56b6b0, $71159069, $75d48dde, $6b93dddb, $6f52c06c, $6211e6b5, $66d0fb02, $5e9f46bf, $5a5e5b08, $571d7dd1, $53dc6066, $4d9b3063, $495a2dd4, $44190b0d, $40d816ba, $aca5c697, $a864db20, $a527fdf9, $a1e6e04e, $bfa1b04b, $bb60adfc, $b6238b25, $b2e29692, $8aad2b2f, $8e6c3698, $832f1041, $87ee0df6, $99a95df3, $9d684044, $902b669d, $94ea7b2a, $e0b41de7, $e4750050, $e9362689, $edf73b3e, $f3b06b3b, $f771768c, $fa325055, $fef34de2, $c6bcf05f, $c27dede8, $cf3ecb31, $cbffd686, $d5b88683, $d1799b34, $dc3abded, $d8fba05a, $690ce0ee, $6dcdfd59, $608edb80, $644fc637, $7a089632, $7ec98b85, $738aad5c, $774bb0eb, $4f040d56, $4bc510e1, $46863638, $42472b8f, $5c007b8a, $58c1663d, $558240e4, $51435d53, $251d3b9e, $21dc2629, $2c9f00f0, $285e1d47, $36194d42, $32d850f5, $3f9b762c, $3b5a6b9b, $0315d626, $07d4cb91, $0a97ed48, $0e56f0ff, $1011a0fa, $14d0bd4d, $19939b94, $1d528623, $f12f560e, $f5ee4bb9, $f8ad6d60, $fc6c70d7, $e22b20d2, $e6ea3d65, $eba91bbc, $ef68060b, $d727bbb6, $d3e6a601, $dea580d8, $da649d6f, $c423cd6a, $c0e2d0dd, $cda1f604, $c960ebb3, $bd3e8d7e, $b9ff90c9, $b4bcb610, $b07daba7, $ae3afba2, $aafbe615, $a7b8c0cc, $a379dd7b, $9b3660c6, $9ff77d71, $92b45ba8, $9675461f, $8832161a, $8cf30bad, $81b02d74, $857130c3, $5d8a9099, $594b8d2e, $5408abf7, $50c9b640, $4e8ee645, $4a4ffbf2, $470cdd2b, $43cdc09c, $7b827d21, $7f436096, $7200464f, $76c15bf8, $68860bfd, $6c47164a, $61043093, $65c52d24, $119b4be9, $155a565e, $18197087, $1cd86d30, $029f3d35, $065e2082, $0b1d065b, $0fdc1bec, $3793a651, $3352bbe6, $3e119d3f, $3ad08088, $2497d08d, $2056cd3a, $2d15ebe3, $29d4f654, $c5a92679, $c1683bce, $cc2b1d17, $c8ea00a0, $d6ad50a5, $d26c4d12, $df2f6bcb, $dbee767c, $e3a1cbc1, $e760d676, $ea23f0af, $eee2ed18, $f0a5bd1d, $f464a0aa, $f9278673, $fde69bc4, $89b8fd09, $8d79e0be, $803ac667, $84fbdbd0, $9abc8bd5, $9e7d9662, $933eb0bb, $97ffad0c, $afb010b1, $ab710d06, $a6322bdf, $a2f33668, $bcb4666d, $b8757bda, $b5365d03, $b1f740b4 ); // 00 01 02 03 --> 0x03020100 // 00 01 02 03 04 --> 0x03020100, 0x04000000 // 00 01 02 03 04 05 --> 0x03020100, 0x05040000 // 00 01 02 03 04 05 06 --> 0x03020100, 0x06050400 // function stm32_sw_crc32_by_byte(crc32 : DWORD; pBuffer : pbyte; NumOfByte : DWORD) : DWORD; var i : DWORD; last_data : array[0..3] of byte; NumOfDWord : DWORD; NumOfTailByte : DWORD; begin NumOfDWord := NumOfByte shr 2; NumOfTailByte := NumOfByte and 3 ; for i := 0 to NumOfDWord-1 do begin crc32 := crc32 xor ( PDWORD( pbuffer ) )^; Inc( pbuffer, 4); crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24]; crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24]; crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24]; crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24]; end; if NumOfTailByte <> 0 then begin for i := 0 to 3 do last_data[i] := 0; if NumOfTailByte = 1 then begin last_data[3] := pBuffer^; end else if NumOfTailByte = 2 then begin last_data[2] := pBuffer^; Inc( pBuffer ); last_data[3] := pBuffer^; end else begin last_data[1] := pBuffer^; Inc( pBuffer ); last_data[2] := pBuffer^; Inc( pBuffer ); last_data[3] := pBuffer^; end; crc32 := stm32_sw_crc32_by_byte( crc32, @last_data, 4 ); end; result := crc32; end; function uCrc32_Demo : DWORD; var crc32 : DWORD; buffer : array[0..3] of DWORD; begin buffer[0] := $12345678; buffer[1] := $00000000; buffer[2] := $12345678; crc32 := stm32_sw_crc32_by_byte( $FFFFFFFF, @buffer, 12 ); buffer[3] := crc32; crc32 := stm32_sw_crc32_by_byte( $FFFFFFFF, @buffer, 16 ); result := crc32; end;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本