wumei 发表于 2008-8-1 19:21:01

SD卡用CRC7和CRC16校验程序(汇编)

在开发我的MP3时,花了不少时间和参考了不少CRC的程序写了以下的CRC程,用的是查表法,对于SPI接口的SD卡,
在发送数据后的等待时间中可以完成CRC校验计算,可以说得上是零等待的CRC校验了.并付上SD卡的写命令和读扇区程序.

/////////////////////////////////
//SD卡CRC保存在R16,数据入口R17//
/////////////////////////////////
CRC7:         
                LDI             R18,            0x09            ;CRC7多项式
                LSL             R16
                SBRC            R16,            7
                EOR             R16,            R18

                SBRC            R17,            7
                EOR             R16,            R18
                ANDI            R16,            0x7F
                ANDI            R17,            0x7F

                EOR             R16,            R17
                CLR             R19

                LDI             R30,            LOW(CRC7DAT*2)
                LDI             R31,            HIGH(CRC7DAT*2)

                ADD             R30,            R16
                ADC             R31,            R19
                LPM             R16,            Z
                RET
CRC7DAT: /* CR7C余式表 */
.DB        0x00,0x09,0x12,0x1B,0x24,0x2D,0x36,0x3F,0x48,0x41,0x5A,0x53,0x6C,0x65,0x7E,0x77
.DB        0x19,0x10,0x0B,0x02,0x3D,0x34,0x2F,0x26,0x51,0x58,0x43,0x4A,0x75,0x7C,0x67,0x6E
.DB        0x32,0x3B,0x20,0x29,0x16,0x1F,0x04,0x0D,0x7A,0x73,0x68,0x61,0x5E,0x57,0x4C,0x45
.DB        0x2B,0x22,0x39,0x30,0x0F,0x06,0x1D,0x14,0x63,0x6A,0x71,0x78,0x47,0x4E,0x55,0x5C
.DB        0x64,0x6D,0x76,0x7F,0x40,0x49,0x52,0x5B,0x2C,0x25,0x3E,0x37,0x08,0x01,0x1A,0x13
.DB        0x7D,0x74,0x6F,0x66,0x59,0x50,0x4B,0x42,0x35,0x3C,0x27,0x2E,0x11,0x18,0x03,0x0A
.DB        0x56,0x5F,0x44,0x4D,0x72,0x7B,0x60,0x69,0x1E,0x17,0x0C,0x05,0x3A,0x33,0x28,0x21
.DB        0x4F,0x46,0x5D,0x54,0x6B,0x62,0x79,0x70,0x07,0x0E,0x15,0x1C,0x23,0x2A,0x31,0x38

CRC32DAT: /* CRC32余式表 */
.DW        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7
.DW        0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
.DW        0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6
.DW        0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de
.DW        0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485
.DW        0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d
.DW        0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4
.DW        0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc
.DW        0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823
.DW        0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b
.DW        0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12
.DW        0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a
.DW        0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41
.DW        0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49
.DW        0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70
.DW        0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78
.DW        0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f
.DW        0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067
.DW        0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e
.DW        0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256
.DW        0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d
.DW        0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405
.DW        0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c
.DW        0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634
.DW        0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab
.DW        0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3
.DW        0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a
.DW        0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92
.DW        0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9
.DW        0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1
.DW        0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8
.DW        0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
////////////////////////////////////
//SD卡CRC保存在R24R25,数据入口R16//
////////////////////////////////////
CRC32:
                PUSH            R30
                PUSH            R31

                MOV             R30,            R25
                EOR             R30,            R16
                CLR             R31
                LSL             R30
                ROL             R31
                SUBI            R30,            LOW(-CRC32DAT*2)
                SBCI            R31,            HIGH(-CRC32DAT*2)

                LPM             R0,             Z+
                LPM             R1,             Z+

                EOR             R1,             R24
                MOVW            R24,            R0

                POP             R31
                POP             R30
                RET


/////////////////////////////////////////////////////
//写SD卡命令,R16为命令,R0,1,2,3为参数,反回参数R16//
/////////////////////////////////////////////////////
SD_Write_CMD:
                PUSH            R30
                PUSH            R31
                PUSH            R24

                LDI             R17,            0xFF
                OUT             SPDR,         R17
                SBIS            SPSR,         SPIF
                RJMP            PC-1

                SD_CS_L
                ORI             R16,            0x40
                MOV             R17,            R16

                OUT             SPDR,         R16

                CLR             R16                        ;CRC7的初值为0
                RCALL         CRC7

                SBIS            SPSR,         SPIF
                RJMP            PC-1

                OUT             SPDR,         R3
                MOV             R17,            R3
                RCALL         CRC7

                SBIS            SPSR,         SPIF
                RJMP            PC-1

                OUT             SPDR,         R2
                MOV             R17,            R2
                RCALL         CRC7

                SBIS            SPSR,         SPIF
                RJMP            PC-1

                OUT             SPDR,         R1
                MOV             R17,            R1
                RCALL         CRC7

                SBIS            SPSR,         SPIF
                RJMP            PC-1

                OUT             SPDR,         R0
                MOV             R17,            R0
                RCALL         CRC7
               
                LSL             R16
                SUBI            R16,            -1
                SBIS            SPSR,         SPIF
                RJMP            PC-1

                OUT             SPDR,         R16

                SBIS            SPSR,         SPIF
                RJMP            PC-1

                LDI             R17,            0xFF
                CLR             R24
_SD_WCOM_0:
                OUT             SPDR,         R17
                SBIS            SPSR,         SPIF
                RJMP            PC-1
                IN            R16,            SPDR
                INC             R24
                SBRS            R16,            7
                RJMP            _SD_WCOM_1
                CPI             R24,            255
                BRNE            _SD_WCOM_0
_SD_WCOM_1:
                SD_CS_H
                POP             R24
                POP             R31
                POP             R30
                RET

/////////////////////////////////////////////////////
//从SD卡中读出一个扇区数据,存到R16,R17所指的数据区//
/////////////////////////////////////////////////////
SD_ReadBlock:
                PUSH            R24
                PUSH            R25
                PUSH            R30
                PUSH            R31
                MOVW            R30,            R16
                LDI             R16,            9
_SD_READ_BLOCK_1:
                LSL             R0
                ROL             R1
                ROL             R2
                ROL             R3
                DEC             R16
                BRNE            _SD_READ_BLOCK_1

                LDI             R16,            17
                RCALL         SD_Write_CMD
                SD_CS_L
                LDI             R24,            255
                LDI             R18,            0xFF
                OUT             SPDR,         R18
_SD_READ_BLOCK_2:
                SBIS            SPSR,         SPIF
                RJMP            PC-1
                IN            R16,            SPDR
                OUT             SPDR,         R18
                CPI             R16,            0xFE
                BREQ            _SD_READ_BLOCK_3
                DEC             R24
                BRNE            _SD_READ_BLOCK_2
                LDI             R16,            0xFF
                RJMP            _SD_READ_BLOCK_END
_SD_READ_BLOCK_3:
                CLR             R17
                CLR             R24
                CLR             R25
_SD_READ_BLOCK_4:
                SBIS            SPSR,         SPIF
                RJMP            PC-1
                IN            R16,            SPDR
                OUT             SPDR,         R18

                ST            Z+,             R16
                RCALL         CRC32

                SBIS            SPSR,         SPIF
                RJMP            PC-1
                IN            R16,            SPDR
                OUT             SPDR,         R18

                ST            Z+,             R16
                RCALL         CRC32
               
                DEC             R17
                BRNE            _SD_READ_BLOCK_4

                SBIS            SPSR,         SPIF
                RJMP            PC-1
                IN            R19,            SPDR

                OUT             SPDR,         R18
                SBIS            SPSR,         SPIF
                RJMP            PC-1
                IN            R18,            SPDR

                LDI             R16,            5
_SD_READ_BLOCK_5:
                LDI             R17,            0xFF
                OUT             SPDR,         R17
                SBIS            SPSR,         SPIF
                RJMP            PC-1
                DEC             R16
                BRNE            _SD_READ_BLOCK_5

                CP            R18,            R24
                CPC             R19,            R25
                BREQ            _SD_READ_BLOCK_END
                ;CRC16不正确,反回错误码0x80
                LDI             R16,            0x80
_SD_READ_BLOCK_END:
                SD_CS_H
                POP             R31
                POP             R30
                POP             R25
                POP             R24
                RET

wumei 发表于 2008-8-2 13:14:40

自己顶一下

qkj1575 发表于 2008-8-2 13:21:21

LSL             R0
                ROL             R1
                ROL             R2
                ROL             R3
楼主的R0-R3是参数为什么要移动这个数值呢?

gmen_pliskin 发表于 2008-8-2 13:57:31

其实mp3一般不用校验的,基本没有出错

wumei 发表于 2008-8-2 16:03:45

【2楼】
在这里R0-3是SD卡的扇区号,但SD卡的读写起始要指定到字节的,所以R0-3要移动9位(即乘上512).所以SD卡的理论最大容量是4G.

qkj1575 发表于 2008-8-2 18:34:38

感谢了知道了

chxgzl4862 发表于 2008-8-7 09:04:34

LDI             R18,            0x09            ;CRC7多项式
为什么不是0x89呢?

wumei 发表于 2008-8-7 10:59:05

CRC7多只有7位有较值,第八位是1时才和多项式异或,也可写成0x89不过没有意义

huanxian 发表于 2008-8-25 21:59:02

恐怖,太汇编了。 赞赏一个

xinjie1023 发表于 2009-8-21 17:40:13

标记

lanmao8701 发表于 2012-7-25 14:23:00

O(∩_∩)O谢谢楼主

mcuprogram 发表于 2012-12-7 15:24:21

mark!!!!!!!!!!!!!!!!!!!!!!

阿莫小子~ 发表于 2012-12-10 01:27:06

楼主很强大……考完试把SD读写加字库加5110显示搞出来
页: [1]
查看完整版本: SD卡用CRC7和CRC16校验程序(汇编)