打印

SPI模式下SD卡的命令格式的Byte6

[复制链接]
6172|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pengyang73|  楼主 | 2012-7-4 08:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在许多资料上看到关于这个问题的介绍,都有以下的说法:



SD卡的指令由6字节(Byte)组成,如下:

Byte10 1 x x x x x x(命令号,由指令标志定义,如CMD3910011116进制0x27,那么完整的CMD39第一字节为01100111,即0x27+0x40)
Byte2-5:Command Arguments,
命令参数,有些命令没有参数
Byte6:7位为CRC(Cyclic Redundacy Check,循环冗余校验)校验位,最后一位为停止位0.


然后在许多例程里都看到发送的Byte6是0x95,如下片断:



   SPI_SD_SendReceiveByte(cmd | 0x40);
   SPI_SD_SendReceiveByte(arg >> 24);
   SPI_SD_SendReceiveByte(arg >> 16);
   SPI_SD_SendReceiveByte(arg >> 8);
   SPI_SD_SendReceiveByte(arg);
   SPI_SD_SendReceiveByte(0x95);

   do{
        // 等待响应,响应的开始位为0
        Response = SPI_SD_SendReceiveByte(0xff);
        Retry++;
   } while( ((Response&0x80)!=0) && (Retry < 200) );





我想问的是这个0x95是怎么来的?
沙发
figo20042005| | 2012-7-4 09:42 | 只看该作者
每个在总线上传输的SD存储卡令牌被CRC位保护。在SPI模式下,SD存储卡提供一个非保护模式。此模式使系统用可靠的数据链接来建立,以排除(否定)硬件或软件需要执行CRC生成和校验功能。



在非保护模式下,命令、响应和数据令牌的CRC位在令牌中仍被需要,尽管,对于发送器,它们被定义成“don't care”,且被接收器忽略。



在非保护模式下,SPI接口被初始化。尽管,RESET命令用于使卡切换到SPI模式,但它是在SD模式下被卡接收,所以,必须有一个有效的CRC域。



因为CMD0没有参数,所有的域的内容(包括CRC域)都是常数,不需要在运行时间计算出来。一个有效的复位命令是:



       0x40,0x0, 0x0, 0x0, 0x0,0x95



主机可以用CRC_ON_OFF命令(CMD59)开关卡的CRC选项。

使用特权

评论回复
板凳
figo20042005| | 2012-7-4 09:44 | 只看该作者
2.SD卡的命令
SD卡命令共分为12类,分别为class0到class11,

不同的SDd卡,主控根据其功能,支持不同的命令集 如下:

Class0 :(卡的识别、初始化等基本命令集)  

CMD0 的CRC 是0x95,
其余命令的 CRC 无所谓。

CMD0:复位SD 卡.

CMD1:读OCR寄存器.

CMD9:读CSD寄存器.

CMD10:读CID寄存器.

CMD12:停止读多块时的数据传输

CMD13:读 Card_Status 寄存器

Class2 (读卡命令集):

CMD16:设置块的长度

CMD17:读单块.

CMD18:读多块,直至主机发送CMD12为止 .


Class4(写卡命令集) :

CMD24:写单块.

CMD25:写多块.

CMD27:写CSD寄存器 .

Class5 (擦除卡命令集):

CMD32:设置擦除块的起始地址.

CMD33:设置擦除块的终止地址.

CMD38: 擦除所选择的块.

Class6(写保护命令集):

CMD28:设置写保护块的地址.

CMD29:擦除写保护块的地址.

CMD30: Ask the card for the status of the write protection bits


class7:卡的锁定,解锁功能命令集

class8:申请特定命令集 。

class10 -11 :保留

其中 class1, class3,class9:SPI模式不支持



SD卡中的响应有许多种,R1为标准响应,最为常用。与R1响应相似的还有R1b、R2和R3。R1响应在除SEND_STATUS外其它命令后发送,也是最高位先发送,共1个字节。R1的格式如图7所示。响应说明如下:

0x01:空闲状态   //0表示空闲,1表示忙

0x02:擦除错误

0x04:命令错误

0x08:CRC通信错误

0x10:擦除次序错误

0x20:地址错误

0x40:参数错误

MMC_write_Blocks:
1,初始化,进入SPI模式,
2,发CMD25命令,
3,连读2字节,好象读1字节也可以,
4,发start(发一字节0xfc到sd卡),
5,发一个数据块到sd卡,
6,发2字节0xff到sd卡,当作CRC16,
7,读忙信息,直到不忙,
8,如果所有数据没有发完,跳到4,
9,结束,发end(发一字节0xfb到sd卡),
10,发CMD12命令。

使用特权

评论回复
地板
pengyang73|  楼主 | 2012-7-4 13:18 | 只看该作者
哦,原来其余命令的 CRC 无所谓... 谢谢!

还有一个问题,0x95(10010101)的最后一位是1, 系统怎样识别出停止位0呢?

使用特权

评论回复
5
figo20042005| | 2012-7-4 13:54 | 只看该作者
好像命令里没有给停止位。你看下时序SPI时序如下:

read.jpg (57.03 KB )

read.jpg

write.jpg (48.2 KB )

write.jpg

reset.jpg (76.34 KB )

reset.jpg

使用特权

评论回复
6
pengyang73|  楼主 | 2012-7-4 20:08 | 只看该作者
0              1         bit 5...bit 0         bit 31...bit 0            bit 6...bit 0            1
start bit    host      command            argument                 CRC71            end bit

刚看了原版的英文, 如上表, 原来停止位取值是1,不是0. 看来网上提供的翻译有误

使用特权

评论回复
7
figo20042005| | 2012-7-5 09:34 | 只看该作者
知道怎么回事就可以 了,一般资料还是官方原版的最准

使用特权

评论回复
8
悠然科技| | 2012-7-5 09:40 | 只看该作者
万能的论坛,真是想吃海鲜来虾皮,今天正研究sd卡

使用特权

评论回复
9
pengyang73|  楼主 | 2012-7-5 16:49 | 只看该作者
今天又碰到问题了,SD的初始化过程中,在送出CMD55后,得到的R1一直为0x05(非法CRC和Idle),而不是0x01.请帮我看看我的程序有什么问题吧,谢谢!


void SPI_SD_Init(void)
{  
       u8 i, response;

       // card needs 74 cycles minimum to start up */
       for(i=0; i<10; i++)  SPI_SD_SendReceiveByte(0x00);         
     
        SPI_SD_CS_LOW();

        response = SPI_SD_SendCommand(CMD0,0);
        if (response!=0x01)  
        {
             printf(" CMD0 failed!\r\n");
             SPI_SD_CS_HIGH();
             return;
         }
  
        do {
            response = SPI_SD_SendCommand(CMD55,0);
            if (response!=0x01)
                    {
                          printf(" CMD55 failed!\r\n");  
                          SPI_SD_CS_HIGH();
                          return;
                    }

           response = SPI_SD_SendCommand(ACMD41,0);
              } while (response!=0x00);

        SPI_SD_CS_HIGH();
}

使用特权

评论回复
10
figo20042005| | 2012-7-5 17:02 | 只看该作者
这里有段初始化的程序,你看看。改改看行不行

SD卡初始化及读取程序.pdf

114.19 KB

使用特权

评论回复
11
pengyang73|  楼主 | 2012-7-5 21:18 | 只看该作者
谢谢figo20042005啊, 不过这段程序是MMC卡的,要改写的地方较多,这样一来,我就更不容易找到错误了.

继续找错中,头疼!

使用特权

评论回复
12
pengyang73|  楼主 | 2012-7-5 21:43 | 只看该作者
想起来了,我的卡是128M的SD,已经有文件系统了,这个不会有影响吧?

使用特权

评论回复
13
figo20042005| | 2012-7-6 08:54 | 只看该作者
可能有影响的,不过关于这方面的资料还是很多的,你去查查

使用特权

评论回复
14
pengyang73|  楼主 | 2012-7-6 09:01 | 只看该作者
还有, 按照figo20042005提供的例子试了下, 发CMD55的返回r1为0x05,发CMD1的返回r1为0x01,都不对

使用特权

评论回复
15
pengyang73|  楼主 | 2012-7-6 09:04 | 只看该作者
我是SD卡, 我的SYSCLK是72M,因为不是MMC,就没有降频, 是这个原因吗?

使用特权

评论回复
16
figo20042005| | 2012-7-6 10:03 | 只看该作者
这个你可以试试看,我是具体没真正搞过这个,所以又些实际问题还是不知道的,需要LZ你去琢磨,这样才能提高你的能力

使用特权

评论回复
17
pengyang73|  楼主 | 2012-7-6 12:23 | 只看该作者
好的,谢谢figo20042005鼓励!先不结题,等解决了问题再说。 再次感谢!

使用特权

评论回复
18
pengyang73|  楼主 | 2012-7-8 21:27 | 只看该作者
已经解决了,总结如下:
1)我手上的卡其实是个MMC卡,但是它也有SD卡的写保护缺口,甚至有个拨片可以拨动。它也比较薄,总之我就一直以为它是个SD卡,因此我就忽略了SPI时钟的降速问题,也一直在用CMD55+ACMD41处理它;
2)关于初始化的问题,网上不同资料之间出入较大,所以我这个没有基础功底的初学者就很头大。根据我的实践, CMD1似乎对MMC卡和SD卡都有效,但CMD55+ACMD41只对SD卡有效。但不知我的这个结论对不对;

结题给分!

使用特权

评论回复
19
chenyu988| | 2012-9-14 00:28 | 只看该作者
2# figo20042005 请问 SD卡指令格式为6个字节,其中有4个字节为指令参数,这个指令参数是什么意思?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

26

帖子

0

粉丝