TI的技术参考手册325页中提到Kingston的16G卡测试未通过,可我用SanDisk的2G卡、8G卡、Transcend的2G卡测试都未通过,都是发送CMD41后就死等。网上查了一下,大多提到SD卡协议中要求发送指令CMD0前需先发送74个时钟脉冲等待电压上升,可手册中不知为何连SDHOST的寄存器信息都没提供,请问这74个时钟脉冲必须得发吗?通过寄存器操作怎么发?还是有其它的原因导致读卡失败?急!!!
gaoyang9992006:
楼主,你笑死我了,这个跟单片机没有一毛钱的关系的。首先只要单片机上有SPI接口,或者你会用IO模拟SPI协议,都是可以的、
另外你看人家说74个,你也玩74个重复写,其实这个没有定数,就是为了写入成功而已,甚至一个就写入成功了,或者你75个才能成功,所以你74个不对的,你可以用do while ,判断是否写入成功,管他多少个,如果超过多少个,就是作为超时处理嘛。
给你个范例:在附件。另外不要总是抄人家的,人家写的不一定对啊,我就深受其害。
XINGWEI LI1:
回复 gaoyang9992006:
多谢大侠!范例很详细,也很受用。但还是没法解决我的问题:我必须用CC3200的SD硬件接口而不是SPI或者GPIO模拟,发送CMD_SELECT_CARD命令后对应的中断标志位没有变化,一直死等,又查不到相关资料,真不知如何下手啊!
XINGWEI LI1:
回复 XINGWEI LI1:
死等问题的原因找到了:
查看到CMD_SELECT_CARD指令的定义为SDHOST_CMD_7|SDHOST_RESP_LEN_48B,应该是在接收应答时要用到SD_DATA线上的BUSY信号,但实际调试时发现指令发出后一直等不到SDHOST_INT_TC信号变化,而且SD_CLK还一直不停地往外发。将SDHOST_CMD_7|SDHOST_RESP_LEN_48B改为0X07020000后,后续的命令也都正常了: //ulRet = SendCmd(CMD_SELECT_CARD, (Card->ulRCA << 16)); ulRet = SendCmd(0X07020000, (Card->ulRCA << 16));
if(ulRet == 0) { //while( !(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC) ) }
但新的问题又出来了:
读取首个数据块时,首字节前多了1个0x1F字节和n个0xff字节,首字节向后挪了1位,导致尾数0x55aa变成了0x2ad5——无语!这多出的0xff的个数还跟SD卡的时钟频率相关,频率越高个数越多。
把上面的问题将错就错拼凑正确后,首个数据块可以正确读取了,文件分区表的偏移地址也读取正确了,结果下一个读取数据块的命令却又被卡住了,在SendCmd()函数的等待循环中打死都不出来: do { ulStatus = MAP_SDHostIntStatus(SDHOST_BASE); } while( !(ulStatus & (SDHOST_INT_CC|SDHOST_INT_ERRI)));
用示波器看到,第二个数据块读取指令执行后连个SD_CLK时钟都没送出去一个,但换成其它指令却能正常执行——晕!
请TI的工程师帮忙看一下,或者提供下CC3200的SD_HOST寄存器的相关资料也可以。例程跑不起来又无资料可查,真的没辙了!
XiongCheng liao:
回复 XINGWEI LI1:
你好,我看CC3200只有一个数据线 , 标准人SD卡不是有4根线吗? 请问应该怎样连接SD卡,能否指导下,谢谢
XINGWEI LI1:
回复 XiongCheng liao:
data0之外的三根线不用接
XiongCheng liao:
回复 XINGWEI LI1:
那么问题来了,只有一根数据线,这读取速率是不是很慢?? 是否能实现3MB不是Mbps)的读取? 谢谢
XiongCheng liao:
回复 XiongCheng liao:
用一根数据线,接法就像SPI一样吧,所以的地址、数据都是通过DATA0来传输,所以我有点担心能否实现3MB/s的读取。
gaoyang9992006:
回复 XiongCheng liao:
楼主现在是怎么做的,速度还可以吧?