打印

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

[复制链接]
4724|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiaoyanjing20|  楼主 | 2009-3-30 11:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
古道热肠| | 2009-3-30 12:41 | 只看该作者

把CRC校验关掉试试.

使用特权

评论回复
板凳
xiaoyanjing20|  楼主 | 2009-3-30 14:46 | 只看该作者

回复2楼

我在SD Memory Card Specifications没有找到关才CRC的说明,是不是我看得不仔细可否提示一下。
另外好像并不是CRC校验出错,如果CRC校验出错应该返回101,而不是f。SD协议里是这样说的When a flash programming error occurs the card will ignore all further data blocks. In this case no
CRC response will be sent to the host and, therefore, there will not be CRC start bit on the bus and
the three CRC status bits will read (‘111‘).
只有当发生编程错误,卡才会反回0xff

CRC状态令牌的格式如下:
7 6 5 4 3--------1 0 (bit)
x x x 0 CRC Status 1 

The meaning of the status bits is defined as follows:
‘010’ - Data accepted.
‘101’ - Data rejected due to a CRC error.
’110’ - Data Rejected due to a Write Error

使用特权

评论回复
地板
古道热肠| | 2009-3-30 16:39 | 只看该作者

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

能读不能写,是否写保护?是否超里过短,原因可能是多方面的,您自己单个排除了.印象中成功返回00,不成功返回非0.代表错误的原因,都有定义的,
相关链接:https://bbs.21ic.com/upfiles/img/20093/2009330163738176.rar

使用特权

评论回复
5
xiaoyanjing20|  楼主 | 2009-3-30 17:19 | 只看该作者

回复古道热肠

有没有write protection还不确定,不过返回值应该是上面的CRC Status令牌的值,不会是0x00的吧。我先看看你的代码。

使用特权

评论回复
6
xiaoyanjing20|  楼主 | 2009-3-30 17:24 | 只看该作者

回复古道热肠

你给的代码是周立功的,我也用过了,返回值是一样的,跟我自己的代码是一样的结果

使用特权

评论回复
7
xiaoyanjing20|  楼主 | 2009-3-30 17:49 | 只看该作者

re

uint8 SD_WriteBlockData(uint8 bmulti, uint32 len, uint8 *sendbuf)
{
    uint16 i;
    uint8 tmp;

    SPI_CS_Assert();
        
    SPI_SendByte(0xFF);                                /* 开始发送数据之前发送8个clock clock out 8 clk before start */
    
    if (bmulti == 1)
        SPI_SendByte(SD_TOK_WRITE_STARTBLOCK_M);    /* 写多块开始令牌 start token of write multi blocks */
    else
        SPI_SendByte(SD_TOK_WRITE_STARTBLOCK);        /* 写单块开始令牌 start token of write single block */

    for (i = 0; i < len; i++)
        SPI_SendByte(sendbuf);                    /* 发送数据 send data */

#if SD_CRC_EN    
    i = SD_GetCRC16(sendbuf,len);                    /* 计算CRC16 calculate CRC16 */
#endif

    SPI_SendByte((i >> 8) & 0xFF);
    SPI_SendByte(i & 0xFF);                         /* 发送CRC16校验码 send CRC16 check code */
                
    tmp = SPI_RecByte();//就是这里tmp总是0xff,如果成功的话应该是tmp&0x0f=05
      if ((tmp & SD_RESP_DATA_MSK) != SD_RESP_DATA_ACCETPTED)    
      {        
           SPI_SendByte(0xFF);                            /* 返回之前发送8个clock  clock out 8 clk before return */
           SPI_CS_Deassert();
           return SD_ERR_DATA_RESP;                    /* 数据响应错误 data response error */
    }
        
    SPI_CS_Deassert();
             
    if (SD_WaitBusy(SD_WAIT_WRITE) != SD_NO_ERR)            
        return SD_ERR_TIMEOUT_WRITE;                /* 写入超时 write time out */
    else
        return SD_NO_ERR;                             /* 写入正确 write right */
 }


前面所有的卡响应都是正确的
就是这里tmp总是0xff,如果成功的话应该是tmp&0x0f=05
tmp = SPI_RecByte(); 

使用特权

评论回复
8
xiaoyanjing20|  楼主 | 2009-3-31 09:23 | 只看该作者

回复古道热肠

搞定了,是SPI总线的问题,我用的是SSP总线控制器的SPI帧格式,换成SPI总线控制器就行了,很奇怪的是,如果SSP总线发出的数据被卡接收错误,那卡怎么能接收到正确的命令。

使用特权

评论回复
9
古道热肠| | 2009-3-31 10:49 | 只看该作者

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

俺没那东西,就用SPI工作模式挨个试,通常也就4种,总有一两种能用.读写块都正常,一般就不会出错了.

使用特权

评论回复
10
xiaoyanjing20|  楼主 | 2009-3-31 14:09 | 只看该作者

回复古道热肠

SSP控制器的CPOL和CPHA的四种组合我都试过了,只有一种是可以读,但写就出现这个情况。后来我用IO模拟的SPI方式都可以读写,最后换成SPI控制器也没有问题,NXP的东西,哎。

使用特权

评论回复
11
robinson_911| | 2014-3-28 16:52 | 只看该作者
楼主好啊,我也遇到这个问题了(可以读,不能写),请问你这边是怎么修改的啊?

使用特权

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

本版积分规则

1

主题

7

帖子

0

粉丝