OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3258|回复: 2

计算CRC问题

[复制链接]

79

主题

127

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2013-2-19
在线时间
1 小时
发表于 2013-4-28 15:52:54 | 显示全部楼层 |阅读模式
哦,计算CRC的公式我知道,有两种一种是16为CRC的还有一种是7位的。都是知道生成表达式。我想问假如您用CRC7,怎样计算出CMD8的CRC的,具体的说就是您的M(x)是怎么选的?




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-4-28 18:47:20 | 显示全部楼层
   /* CRC 7 to produce SD memory card packet format

      Code works as tested for one packet example given by
      student questioning the algorithm.
      Code derived from documentation of Maxim website,
      as detailed below.

      Code may not be pretty or optimized, but it does
      do the job. Code was compiled using Borland C compiler
      for DOS, with DOS cmnd line executable (included in ZIP file)
      runnable under Windows XP via command line.

      Usage is
      CRC_7 Val1 Val2 Val3 Val4 Val5
        where Val1..5 are decimal values for the bytes of command to SD.
      For example, CRC_7 64 0 0 0 0
        generates the data for the student's example to send GO_IDLE_STATE
         command (lower 6 bits of 0).

         Any and all use of this code is granted to any and all users.
       To contact the author of this code, send an email to:

      bitwacker55@yahoo.com

         I'll try to be of assistance. I also program in LabView, Visual
         Basic, Python, Forth, etc.

      Information from ZIP file to authenticate EXE file.

      2008-07-24  10:35       7900 1CD57D4B CRC_7.EXE
      7e2d8ec62f7f5500e830b954c0a7f651  crc_7.exe   MD5 digest.

   */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>

/*
CRC7 algorithm info :


http://www.pldesignline.com/showArticle.jhtml?articleID=209102269&cid=NL_pldl


Student in Canada has question in above website.

Frame below (cmd 0 as 0x40 Go Idle State)

01000000 00000000 00000000 00000000 00000000 10010101


Text cut from web site:
http://www.maxim-ic.com/appnotes.cfm/an_pk/3969

Cyclic Redundancy Check
The CRC algorithm is commonly used to detect errors induced by an unreliable 
communication channel. The selection of a particular CRC is governed by 
the size of data to be protected. In the case of SD media, CRC-7 and CRC-16 
are specified.

The CRC algorithm divides the protected data by a selected divisor and 
produces a remainder. This division is done without carry logic due to 
the polynomial math used in the algorithm. As no carries are needed, division 
can be accomplished with the logical XOR operation. The selected divisor 
is commonly referred to as the CRC's polynomial. The resulting remainder 
is then transmitted with the data, and can be used by the receiver to 
check that the data was not corrupted during transmission.

In the case of CRC-7, the remainder can be calculated using a 7-bit shift 
register in software. This shift register is initialized to all zeros 
at the start of the calculation. As each bit (MSB first) of the protected 
data is shifted into the LSB of the shift register, the MSB of the shift 
register is shifted out and examined. If the bit just shifted out is one, 
the contents of the shift register are modified by XORing with the CRC-7 
polynomial value 0x09. If the bit shifted out of the shift register is 
zero, no XOR is performed. Once the last bit of protected data is shifted 
in and the conditional XOR completed, seven more zeros must be shifted 
through in a similar manner. This process is referred to as augmentation, 
and completes the polynomial division. At this point, the CRC-7 value 
can be read directly from the shift register.


SD Command Format
Commands are issued to the card in a 6-byte format (Identified as Bytes 1..6).
The first byte of a command can be constructed by ORing the 6-bit command code with
hex 0x40. The next four bytes provide a single 32-bit argument, if
required by the command; the final byte contains the CRC-7 checksum over
bytes 1 through 5. Table 1 lists important SD commands.

Byte1.2.3.4.5.6 with 6 being CRC with 7 bits in MS order rank, with LSB of 1
added at the end. After Byte 5 is CRCed an augment of 7 zero bits is mixed
in too.


Table 1. Selected SD Memory Card Commands
Command    Mnemonic             Argument Reply  Description
0 (0x00)   GO_IDLE_STATE        none     R1     Resets the SD card.
9 (0x09)   SEND_CSD             none     R1     Sends card-specific data.
10 (0x0a)  SEND_CID             none     R1     Sends card identification.
17 (0x11)  READ_SINGLE_BLOCK    address  R1     Reads a block at byte address.
24 (0x18)  WRITE_BLOCK          address  R1     Writes a block at byte address.
55 (0x37)  APP_CMD              none     R1     Prefix for application command.
59 (0x3b)  CRC_ON_OFF           Only Bit 0 R1   Argument sets CRC on (1) or off (0).
41 (0x29)  SEND_OP_COND         none     R1     Starts card initialization.


*/

/****************/
static unsigned char Encode( unsigned char Seed, unsigned char Input , unsigned char Depth)
                  /* --
                     roduce a 7 bit CRC value Msb first.
                    Seed is last round or initial round shift register
                      value (lower 7 bits significant).
                    Input is an 8 bit value from byte stream being CRCd.
                    CRC register is seeded initially with the value 0 prior
                     to mixing in the variable packet data.
                    Depth is usually 8, but the last time is 7 to shift in
                      the augment string of 7 zeros.
*****************/
{
/*begin-Encode. -
      local defs: */
   register unsigned char regval;      // shift register byte.
   register unsigned char count;
   register unsigned char cc;          // data to manipulate.
 #define POLYNOM (0x9)        // polynomical value to XOR when 1 pops out.

/*BODY*/

   regval = Seed;    // get prior round's register value.
   cc = Input;       // get input byte to generate CRC, MSB first.

   /* msb first of byte for Depth elements */
   for ( count = Depth     // set count to 8 or 7.
          ; count--        // for count # of bits.
           ;  cc <<= 1     // shift input value towards MSB to get next bit.
       )
      {
      // Shift seven bit register left and put in MSB value of input to LSB.
      regval = (regval << 1) + ( (cc & 0x80) ? 1 : 0 );
      // Test D7 of shift register as MSB of byte, test if 1 and therefore XOR.
      if (regval & 0x80)
         regval ^= POLYNOM;
      } // end byte loop.
   return (regval & 0x7f);    // return lower 7 bits of CRC as value to use.
}
/*...
end-Encode.
.....*/




int main(int argc, char * argv[] )
{
   char * cp;     // pointer into command line argument list.
   int walker;    // index into argv parameter list.
   int value, nuval;    // temporary values from cmd line and CRC generator.
   unsigned char CrcAccum; // local storage of each round of CRC.

   // 7 bit shift register CRC computation across 5 byte SD message field
   //   with 6th byte of message being the CRC field generated herein.
   if ( argc != (1+5) )
      {
      fprintf(stderr, "\nCRC_7 command line syntax error.\n");
      fprintf(stderr, "Requires 5 argument(s) to encode w/crc value\n");
      fprintf(stderr, "Usage is :\nCRC_7 0 0 0 0 0\n");
      fprintf(stderr, " or similar with decimal value for each byte.\n");
      fprintf(stderr, "  Use CRC_7 64 0 0 0 0\n   to generate example run.\n\n");
      return 1;
 // EARLY EXIT, CMND LINE SYNTAX ERROR
      }

   // start w/seed of 0 per algorithm.
   CrcAccum = 0;

   // loop through 5 command line decimal values. Display in HEX to
   //  stdout, can be captured via >> on cmdline.
   for ( walker = 1 ; walker < argc ; walker++ )
      {
      cp = argv[walker];
      value = atoi(cp);
      nuval = Encode(CrcAccum, value, 8 );
      printf(" CRC remainder of 0x%02X for 0x%02X input byte.\n"
               , nuval
               , value
            );
      CrcAccum = nuval;    // reload crc accum.
      }

   // mix in last 7 bits of 0s to augment, and then shift final CRC
   //  remainder left and OR in fixed 1 LSB.
   nuval = Encode(CrcAccum, 0, 7 );
   value = (nuval << 1) + 1;
   printf("CRC remainder after augment is 0x%02X with FINAL CRC byte of 0x%02X.\n"
               , nuval
               , value
            );
   return 0;
}


/* end of file */

crc7.zip

8.57 KB, 下载次数: 100

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

79

主题

127

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
465
金钱
465
注册时间
2013-2-19
在线时间
1 小时
 楼主| 发表于 2013-4-28 19:50:16 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-20 18:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表