• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

STM32CRC32(Delphi)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
/*

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;

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
[Delphi]类型强制和转换发布时间:2022-07-18
下一篇:
基于Directshow的USB视频捕获Delphi篇(一)发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap