分类: 嵌入式
2009-09-22 13:53:21
SD卡的价格越来越便宜 呵呵 用小型的单片机来读取sd卡 作为外部大容量存储器(相对小型嵌入式而言)是一个比较好的方式 嗯 这几天一直在看sd卡的文档 并尝试用avr m16驱动读写sd卡 嗯 几经周折 终于成功了 呵呵 各种有些需要注意的地方 结合网站上找到的资料 一并总结在这里 嗯
1. sd卡的初始化时序图跟mmc卡是一样的 初始化时CMD0是一样的
2. sd卡手册上建议使用3.3v电压 好几次我的粗心 直接是5v使用 在我的kingston 1G sd卡上是可以的 没有任何问题 不过建议 如果mcu使用的是5v 最好在mcu引脚上用2个3.3K左右的电阻分压 再连接到sd卡 手册上建议信号线上都用10K的电阻上拉 我的sd卡没上拉的情况下也是可以工作的
3. 上电时sd卡默认传输模式是SD模式 在初始化sd卡工作在spi模式前 请发至少74个时钟过去 以保证初始化成功 那么为什么要74个CLK呢?因为在上电初期,电压的上升过程据SD卡组织的计算约合64个CLK周期才能到达SD卡的正常工作电压 他们管这个叫做Supply ramp up time 其后的10个CLK是为了与SD卡同步 之后开始CMD0的操作
4. spi模式下 输入数据和输出数据都是在clk的上升沿锁存数据
5. 初始化的时候 注意用低速的spi模式 400k以下吧 但是 初始化完了之后 建议马上设置spi为高速模式 这样读写速度可以提高n多倍
6.为了使SD卡初始化进入SPI模式,我们需要使用的命令有3个:CMD0,ACMD41,CMD55(使用ACMD类的指令前应先发CMD55,CMD55起到一个切换到ACMD类命令的作用)。
7.为什么在使用CMD0以后不使用CMD1?CMD1是MMC卡使用的指令,虽然本文并不想讨论MMC卡的问题,但是我还是要说:为了实现兼容性,上电或者发送CMD0后,应该首先发送CMD55+ACMD41确认是否有回应,如果有回应则为SD卡,如果等回应超时,则可能是MMC卡,再发CMD1确认。
8.正确的回应内容应该是:
CMD0——0x01(SD卡处于in-idle-state)
CMD55——0x01(SD卡处于in-idle-state)
ACMD41——0x00(SD卡跳出in-idle-state,完成初始化准备接受下一条指令)
这里要说的是如果最后的回应内容还是0x01的话,可以循环发送CMD55+ACMD41,直到回应的内容0x00。
9.在所有的指令中,唯独CMD0特殊,在向SD卡发送以前需要向SD卡发送74+个时钟。那么为什么要74个CLK呢?因为在上电初期,电压的上升过程据SD卡组织的计算约合64个CLK周期才能到达SD卡的正常工作电压他们管这个叫做Supply ramp up time,其后的10个CLK是为了与SD卡同步,之后开始CMD0的操作,严格按照此项操作,一定没有问题。
10.关于SD卡的SPI总线,在读入数据时SD卡的SPI是CLK的上升沿输入锁存,输出数据也是在上升沿。
11.向SD卡写入一个CMD或者ACMD指令的过程是这样的:
首先使CS为低电平,SD卡使能;其次在SD卡的Din写入指令;写入指令后还要附加8个填充时钟,是SD卡完成内部操作;之后在SD卡的Dout上接受回应;回应接受完毕使CS为低电平,再附加8个填充时钟。
12.在SD卡的Din没有数据写入时,应使Din保持高电平。