用SPI模式写SD卡遇到的问题

[复制链接]
5980|10
 楼主| xiaoyanjing20 发表于 2009-3-30 11:35 | 显示全部楼层 |阅读模式
问题:<br />可以从SD卡读出数据,并且没有错误,但是往SD卡写数据的时候就有问题了,写完一个块(512byet)后接着两字节CRC16码,然后读回SD卡返回的响应令牌(响应令牌返回的是CRC校验状态)总是0xff,数据也没有被写进SD卡,有谁写过SD卡的给点提示啊,谢谢了。
古道热肠 发表于 2009-3-30 12:41 | 显示全部楼层

把CRC校验关掉试试.

  
 楼主| xiaoyanjing20 发表于 2009-3-30 14:46 | 显示全部楼层

回复2楼

我在SD&nbsp;Memory&nbsp;Card&nbsp;Specifications没有找到关才CRC的说明,是不是我看得不仔细可否提示一下。<br />另外好像并不是CRC校验出错,如果CRC校验出错应该返回101,而不是f。SD协议里是这样说的When&nbsp;a&nbsp;flash&nbsp;programming&nbsp;error&nbsp;occurs&nbsp;the&nbsp;card&nbsp;will&nbsp;ignore&nbsp;all&nbsp;further&nbsp;data&nbsp;blocks.&nbsp;In&nbsp;this&nbsp;case&nbsp;no<br />CRC&nbsp;response&nbsp;will&nbsp;be&nbsp;sent&nbsp;to&nbsp;the&nbsp;host&nbsp;and,&nbsp;therefore,&nbsp;there&nbsp;will&nbsp;not&nbsp;be&nbsp;CRC&nbsp;start&nbsp;bit&nbsp;on&nbsp;the&nbsp;bus&nbsp;and<br />the&nbsp;three&nbsp;CRC&nbsp;status&nbsp;bits&nbsp;will&nbsp;read&nbsp;(‘111‘).<br />只有当发生编程错误,卡才会反回0xff<br /><br />CRC状态令牌的格式如下:<br />7&nbsp;6&nbsp;5&nbsp;4&nbsp;3--------1&nbsp;0&nbsp;(bit)<br />x&nbsp;x&nbsp;x&nbsp;0&nbsp;CRC&nbsp;Status&nbsp;1&nbsp;<br /><br />The&nbsp;meaning&nbsp;of&nbsp;the&nbsp;status&nbsp;bits&nbsp;is&nbsp;defined&nbsp;as&nbsp;follows:<br />‘010’&nbsp;-&nbsp;Data&nbsp;accepted.<br />‘101’&nbsp;-&nbsp;Data&nbsp;rejected&nbsp;due&nbsp;to&nbsp;a&nbsp;CRC&nbsp;error.<br />’110’&nbsp;-&nbsp;Data&nbsp;Rejected&nbsp;due&nbsp;to&nbsp;a&nbsp;Write&nbsp;Error
古道热肠 发表于 2009-3-30 16:39 | 显示全部楼层

只能贴个代码您自己参考了.代码在压缩包中

能读不能写,是否写保护?是否超里过短,原因可能是多方面的,您自己单个排除了.印象中成功返回00,不成功返回非0.代表错误的原因,都有定义的, <br /> 相关链接:<a href='https://bbs.21ic.com/upfiles/img/20093/2009330163738176.rar'>https://bbs.21ic.com/upfiles/img/20093/2009330163738176.rar</a>
 楼主| xiaoyanjing20 发表于 2009-3-30 17:19 | 显示全部楼层

回复古道热肠

有没有write&nbsp;protection还不确定,不过返回值应该是上面的CRC&nbsp;Status令牌的值,不会是0x00的吧。我先看看你的代码。
 楼主| xiaoyanjing20 发表于 2009-3-30 17:24 | 显示全部楼层

回复古道热肠

你给的代码是周立功的,我也用过了,返回值是一样的,跟我自己的代码是一样的结果
 楼主| xiaoyanjing20 发表于 2009-3-30 17:49 | 显示全部楼层

re

uint8&nbsp;SD_WriteBlockData(uint8&nbsp;bmulti,&nbsp;uint32&nbsp;len,&nbsp;uint8&nbsp;*sendbuf)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;tmp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;SPI_CS_Assert();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte(0xFF);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;开始发送数据之前发送8个clock&nbsp;clock&nbsp;out&nbsp;8&nbsp;clk&nbsp;before&nbsp;start&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(bmulti&nbsp;==&nbsp;1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte(SD_TOK_WRITE_STARTBLOCK_M);&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;写多块开始令牌&nbsp;start&nbsp;token&nbsp;of&nbsp;write&nbsp;multi&nbsp;blocks&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte(SD_TOK_WRITE_STARTBLOCK);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;写单块开始令牌&nbsp;start&nbsp;token&nbsp;of&nbsp;write&nbsp;single&nbsp;block&nbsp;*/<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt&nbsp;len;&nbsp;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte(sendbuf);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;发送数据&nbsp;send&nbsp;data&nbsp;*/<br /><br />#if&nbsp;SD_CRC_EN&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;SD_GetCRC16(sendbuf,len);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;计算CRC16&nbsp;calculate&nbsp;CRC16&nbsp;*/<br />#endif<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte((i&nbsp;&gt&gt&nbsp;8)&nbsp;&&nbsp;0xFF);<br />&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte(i&nbsp;&&nbsp;0xFF);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;发送CRC16校验码&nbsp;send&nbsp;CRC16&nbsp;check&nbsp;code&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;SPI_RecByte();//就是这里tmp总是0xff,如果成功的话应该是tmp&0x0f=05<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((tmp&nbsp;&&nbsp;SD_RESP_DATA_MSK)&nbsp;!=&nbsp;SD_RESP_DATA_ACCETPTED)&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_SendByte(0xFF);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;返回之前发送8个clock&nbsp;&nbsp;clock&nbsp;out&nbsp;8&nbsp;clk&nbsp;before&nbsp;return&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPI_CS_Deassert();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;SD_ERR_DATA_RESP;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;数据响应错误&nbsp;data&nbsp;response&nbsp;error&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;SPI_CS_Deassert();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(SD_WaitBusy(SD_WAIT_WRITE)&nbsp;!=&nbsp;SD_NO_ERR)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;SD_ERR_TIMEOUT_WRITE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;写入超时&nbsp;write&nbsp;time&nbsp;out&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;SD_NO_ERR;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;写入正确&nbsp;write&nbsp;right&nbsp;*/<br />&nbsp;}<br /><br /><br />前面所有的卡响应都是正确的<br />就是这里tmp总是0xff,如果成功的话应该是tmp&0x0f=05<br />tmp&nbsp;=&nbsp;SPI_RecByte();&nbsp;
 楼主| xiaoyanjing20 发表于 2009-3-31 09:23 | 显示全部楼层

回复古道热肠

搞定了,是SPI总线的问题,我用的是SSP总线控制器的SPI帧格式,换成SPI总线控制器就行了,很奇怪的是,如果SSP总线发出的数据被卡接收错误,那卡怎么能接收到正确的命令。
古道热肠 发表于 2009-3-31 10:49 | 显示全部楼层

呵呵SPI总线这东西,得用高级的示波器才能整明白的.

俺没那东西,就用SPI工作模式挨个试,通常也就4种,总有一两种能用.读写块都正常,一般就不会出错了.
 楼主| xiaoyanjing20 发表于 2009-3-31 14:09 | 显示全部楼层

回复古道热肠

SSP控制器的CPOL和CPHA的四种组合我都试过了,只有一种是可以读,但写就出现这个情况。后来我用IO模拟的SPI方式都可以读写,最后换成SPI控制器也没有问题,NXP的东西,哎。
robinson_911 发表于 2014-3-28 16:52 | 显示全部楼层
楼主好啊,我也遇到这个问题了(可以读,不能写),请问你这边是怎么修改的啊?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

7

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部