SD卡的读写(SD模式和SPI模式)

一、SPI 方式驱动 SD 卡的方法

        SD 卡的 SPI 通信接口使其可以通过 SPI 通道进行数据读写。从应用的角度来看,采用 SPI 接口的好处在于,很多单片机内部自带 SPI 控制器,不光给开发上带来方便,同时也见降低了开发成本。然而,它也有不好的地方,如失去了 SD 卡的性能优势,要解决这一问题,就要用 SD 方式,因为它提供更大的总线数据带宽。SPI 接口的选用是在上电初始时向其写入第一个命令时进行的。以下介绍 SD 卡的驱动方法,只实现简单的扇区读写。

        为了使SD卡初始化进入SPI模式,我们需要使用的命令有3个CMD0,CMD55,ACMD41(使用ACMD类的指令前应先发CMD55,CMD55起到一个切换到ACMD类命令的作用

        为什么在使用CMD0以后不使用CMD1?CMD1是MMC卡使用的指令。我们上电或者发送CMD0后,应该首先发送CMD55+ACMD41确认是否有回应,如果有回应则为SD卡,如果等回应超时,则可能是MMC卡,再发CMD1确认。

二、SD卡调试步骤:

        1.上电时要延时足够长的时间给SD卡一个准备的过程,SD卡初始化第一步发送CMD命令之前,在片选有效的情况下首先要发送至少74个时钟,否则可能会出现SD卡不能初始化的问题。那么为什么要74个CLK呢?因为在上电初期,电压的上升过程据SD卡组织的计算约合64个CLK周期才能到达SD卡的正常工作电压他们管这个叫做Supply ramp up time,其后的10个CLK是为了与SD卡同步,之后开始CMD0的操作,严格按照此项操作,一定没有问题。

        2.SD卡发送CMD0命令,返回状态为0x01,则复位成功

        3.SD卡发送复位命令CMD0后,要发送版本查询命令CMD8,返回状态一般分为两种,若返回0x01,表示此SD卡接收CMD8,也就是说SD卡支持版本2若返回0x05则表示SD卡支持版本1.

        4.理论上要求发送CMD58获得SD卡电压参数,但实际上都实现知道SD卡的工作电压是3.3v,所以可以省略这一步。

        5.发送CMD55命令,返回0x01,起到转换的作用

        6.再发送ACMD41,等待返回0x00,则表示完成初始化。这里要说的是如果最后的回应内容还是0x01的话,可以循环发送CMD55+ACMD41,直到回应的内容0x00

三、SD卡操作命令作步骤:

1.读步骤:

        发送CMD17(单块)或CMD18(多块)读命令,返回0x00

        接收数据开始令牌0xfe(或0xfc)+正式数据512B+CRC校验2B

2.写步骤:

        发送CMD24(单块)或CMD25(多块)写命令,返回0x00.

        发送数据开始令牌0xfe(或0xfc)+正式数据512B+CRC校验2B

3.擦除步骤:

        发送CMD32,跟一个参数来指定首个要擦除的起始地址

        发送CMD33,指定最后的地址

        发送CMD38,擦除指定区间的内容。

        向SD卡写入一个CMD或者ACMD指令的过程是这样的:

        1.首先使CS为低电平,SD卡使能;其次在SD卡的Din写入指令;写入指令后还要附加8个填充时钟,是SD卡完成内部操作;之后在SD卡的Dout上接受回应;回应接受完毕使CS为低电平,再附加8个填充时钟。

        2.在SD卡的Din没有数据写入时,应使Din保持高电平。

四、一些常用的指令格式:

CMD0:0x40,0x00,0x00,0x00,0x00,0x95 

CMD8:0x48,0x00,0x00,0x01,0xaa,0x87 

CMD55:0x77,0x00,0x00,0x00,0x00,0xff 0x77=0x40+0x37(55的16进制表示) ACMD41:0x69,0x40,0x00,0x00,0x00,0xff

CMD58:0x7a,0x00,0x00,0x00,0x00,0xff

ACMD41属于附加命令,发送起来要麻烦一些,必须提前通知SD卡下一条要发送的命令为ACMD,这个通知就是CMD55,它的4字节参数都为0即可。

五、SD卡的命令格式:

        每一个命令的长度都是固定的6个字节,前1个字节的值=命令号+0x40;中间4个字节为参数,不同的命令参数格式都不相同,但参数最多为4个字节;最后1个字节是CRC校验码和1位固定结束位‘1’。这里需要说明一下0x40的意思,任何命令都有一个固定的起始格式,即先0后1,这是固定的命令起始标志,前两个字节的二进制码就是:01xx xxxx SD 卡所有的命令都是由 48 个数据位组成的,其结构如表 2 所示。

        需要特殊说明的是CRC的问题,这是一种检验错误的方法,具体问题度娘说的还算明白,在SPI模式中,CRC校验默认是关闭的,也就是说这7位必须要发,但是SD卡会在读到CRC以后自动忽略它,所以全部发1就可以。例外的是,CMD0,CMD8这两个命令发送的时候SD卡还没有进入SPI模式,也就是说CRC校验在这个时候还是启用状态,因此这两个命令的CRC效验码必须要写正确,SD卡才会执行命令,否在在返回值R1中就会有相应的错误标志位提示开发人员CRC校验码错误。 

六、SD卡读取与写入(SPI模式)

1、发送CMD17;

2、接收卡响应R1;

3、接收数据起始令牌0XFE;

4、接收数据;

5、接收2个字节的CRC,如果不使用CRC,这两个字节在读取后可以丢掉。

6、禁止片选之后,发多8个CLK;

以上就是一个典型的读取SD卡数据过程。

七、SD卡的写于读数据差不多,写数据通过CMD24来实现,具体过程如下:

1、发送CMD24;

2、接收卡响应R1;

3、发送写数据起始令牌0XFE;

4、发送数据;

5、发送2字节的伪CRC;

6、禁止片选之后,发多8个CLK;

以上就是一个典型的写SD卡过程。

八、SD卡操作命令作步骤:

1.读步骤:

发送CMD17(单块)或CMD18(多块)读命令,返回0x00

接收数据开始令牌0xfe(或0xfc)+正式数据512B+CRC校验2B

2.写步骤:

发送CMD24(单块)或CMD25(多块)写命令,返回0x00.

发送数据开始令牌0xfe(或0xfc)+正式数据512B+CRC校验2B

3.擦除步骤:

发送CMD32,跟一个参数来指定首个要擦除的起始地址

发送CMD33,指定最后的地址

发送CMD38,擦除指定区间的内容。

九、ACMD指令

ACMD指令是SD卡中的应用命令(Application Command)。ACMD指令是通过CMD55命令激活的,用于执行与SD卡应用相关的操作。ACMD指令与CMD指令的区别在于,ACMD指令需要先发送CMD55命令,然后再发送对应的ACMD指令。

以下是一些常用的ACMD指令:

1. ACMD6:设置SD卡的默认工作模式,可以选择高速模式或默认速度模式。

2. ACMD13:发送SD卡状态,用于获取SD卡的状态信息。

3. ACMD22:发送发送指定扇区的写保护状态,用于查询指定扇区是否被写保护。

4. ACMD23:设置或清除指定扇区的写保护状态,用于设置或取消指定扇区的写保护。

5. ACMD41:初始化SD卡,用于初始化SD卡并获取SD卡的OCR(Operation Condition Register)寄存器的值。

6. ACMD42:设置或清除SD卡的写保护状态,用于设置或取消SD卡的写保护。

7. ACMD51:读取SD卡的SCR(SD Configuration Register),用于获取SD卡的配置信息。

这些ACMD指令是与SD卡应用相关的命令,通过发送CMD55命令后再发送对应的ACMD指令,可以执行与SD卡应用相关的操作,例如初始化SD卡、获取状态信息、设置写保护状态等。具体的应用中,可以根据需要使用这些指令来执行相应的操作。

十、CMD指令

SD卡的CMD指令是一组用于与SD卡进行交互和控制的命令。以下是一些常用的SD卡CMD指令:

1. CMD0:进入IDLE状态,用于初始化SD卡。

2. CMD8:发送SD卡接口条件,用于检查SD卡是否支持特定的电压和功能。

3. CMD9:读取SD卡的CSD(Card Specific Data)寄存器,用于获取SD卡的参数信息。

4. CMD16:设置SD卡的块大小,用于指定读写操作的块大小。

5. CMD17:读取指定扇区的数据,用于从SD卡中读取数据。

6. CMD18:连续读取数据块,用于从SD卡中连续读取数据。

7. CMD24:写入指定扇区的数据,用于向SD卡中写入数据。

8. CMD25:连续写入数据块,用于向SD卡中连续写入数据。

9. CMD32:设置SD卡的起始扇区,用于指定写入数据的起始位置。

10. CMD33:设置SD卡的结束扇区,用于指定写入数据的结束位置。

11. CMD38:擦除指定扇区,用于将指定扇区的数据擦除。

12. CMD55:发送应用特定命令之前的准备命令。

13. CMD58:读取OCR(Operation Condition Register)寄存器,用于获取SD卡的操作特性。

这些CMD指令是通过SPI或SD模式与SD卡进行通信和控制的基本命令。在具体的应用中,可以根据需要使用这些指令来操作SD卡进行读写数据等操作。

积分电路是一种能够将输入信号进行积分的电路。在运算放大器搭建的积分电路中,我们使用了一个反相输入的运算放大器,它的输出信号被连接到电容上,而电容的另一端则连接到反馈电阻上,如下图所示: ![image](https://user-images.githubusercontent.com/42630853/132034857-6c5b7d5f-92e7-4d33-aa61-7c9e10c9f1ac.png) 当输入信号V_in施加到电路中时,运算放大器开始放大这个信号。由于反相输入,运算放大器输出的信号与输入信号相反。因此,当输入信号为正时,输出信号为负,反之亦然。这个负信号将通过电容传递到反馈电阻上,而反馈电阻会将这个信号转化为电流。这个电流将被输入到电容中,使其开始充电。当电容开始充电时,它的电压将逐渐增加,同时输出信号也会减小,直到最终趋于零。 这个过程可以用下面的方程式来表示: V_out = -1/(Rf*C) * ∫(V_in) dt 其中,Rf是反馈电阻的阻值,C是电容的电容值,V_in是输入信号,V_out是输出信号,t是时间。 从方程式可以看出,输出信号是输入信号的积分,而反馈电阻电容的值决定了积分的速度。当电容充电的速度比较慢时,输出信号将会有一个滞后的效应,这种效应常常被用于滤波器中。 总之,运算放大器搭建的积分电路可以将输入信号进行积分,输出信号是输入信号的积分,反馈电阻电容值决定了积分速度。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值