打印

SD卡和Fatfs文件系统

[复制链接]
2219|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
laomo|  楼主 | 2013-4-14 11:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
SD的读写程序我单独调试可以对卡进行读写操作,但是我SD卡的读写程序作为Fatfs文件系统的底层驱动函数时就出现不能写了,我用串口调试时在发送CMD24单块的写命令时返回的响应是32(十进制的32)。换成二进制数是(100000),是表示地址错误(这个错误的地址我用串口打印出来是74456)。这是为什么会这样啊??我的卡是2GB的小卡,是装了个卡套插在STM32开发板上的。,这个问题搞了好久了,就是没有找到答案。求高手指点啊

//***************写存储块***********************************
uint8_t WriteBlack(const uint8_t *buffer)//写存储块
{
     u16 count;
     u8 tmp1;
     //tmp1 = SD_SendCmd(SD_CMD24, add, 0xff);
     //if(tmp1) return 1;
     SD_CS_LOW();
     //SPI_Data(SPI1, 0xff);
     //SPI_Data(SPI1, 0xff);
    // SPI_Data(SPI1, 0xff);
     //SPI_Data(SPI1, 0xfe);
     for(count=0;count<512;count++)
     {
          SPI_Data(SPI1, *buffer);  //发送512字节的数据
         buffer++;
     }
     SPI_Data(SPI1, 0xff);    //发送两字节的CRC校验
     SPI_Data(SPI1, 0xff);
     tmp1 = SPI_Data(SPI1, 0xff);
     if((tmp1&0x1F)!=0x05) return 1;
     while((!SPI_Data(SPI1, 0xff))&&count<0xfff)count++; //等待写操作完成
     if(count==0xfff) return 1;//写操作失败
     //printf("@@@@@@@@@@@@@\n");
     SPI_Data(SPI1, 0xff);
     SD_CS_HIGH();
    return 0;
}

/**************************写多个存储块********************************/
u8 WriteMultpleblock(const uint8_t *buffer, uint32_t add, uint16_t count)
{
    u8 tmp1;    // ,tmp4
    u16 tmp2,tmp3;
    printf("开始写入\n");
    if(count==1)
    {
        printf("开始发送单块写命令[%d]\n",add);
        tmp1 = SD_SendCmd(SD_CMD24, add, 0xff);//发送写单个块命令
        printf("%d\n",tmp1);
        if(tmp1) return 1;//判断命令是否发送成功,不成功返回‘1’
        printf("单块写命令发送成功\n");
        SD_CS_LOW();
        SPI_Data(SPI1, 0xff);
        SPI_Data(SPI1, 0xff);
        SPI_Data(SPI1, 0xff);
        SPI_Data(SPI1, 0xfe);
        SD_CS_HIGH();
        tmp1 = WriteBlack(buffer);
        if(tmp1) return 1;    //判断写数据是否成功,不成功返回‘1’
    }
    else if(count>1)
    {
        printf("开始发送多块写命令[%d]\n",add);
        tmp1 = SD_SendCmd(SD_CMD25, add, 0xff);//发送写多个块命令
        printf("%d\n",tmp1);
        if(tmp1) return 1;//判断命令是否发送成功,不成功返回‘1’
        printf("多块写命令发送成功\n");
        SD_CS_LOW();
        SPI_Data(SPI1, 0xff); //放空两个数据,
        SPI_Data(SPI1, 0xff);
        do
        {        
            SPI_Data(SPI1, 0xfc); //连续写多个块的起始令牌
            for(tmp2=0;tmp2<512;tmp2++)//发送一个块的数据
             {
                 SPI_Data(SPI1, *buffer);  //发送512字节的数据
                 buffer++;
             }

             SPI_Data(SPI1, 0xff);    //发送两个字节的CRC校验
             SPI_Data(SPI1, 0xff);

             while((SPI_Data(SPI1, 0xff))!=0xff) //等待写完成
             {
                tmp3++;
                if(tmp3==0xfffe) return 1;
             }            
        }while(count--);
        tmp1 = SPI_Data(SPI1, 0xfd);
        if(tmp1==0x00) return 1;
        tmp1 = SPI_Data(SPI1, 0xff);
        for(tmp3=0;tmp3<50000;tmp3++);  //延时,等待写多块的完成,这个地方在移植的时候要注意更改
        SPI_Data(SPI1, 0xff);
        SD_CS_HIGH();
    }
    printf("写入成功\n");
    return 0;
}


//***************读存一个储块***********************************
uint8_t ReadBlack(uint8_t *buffer) //函数返回‘1’读取出错,返回‘0’读取无误
{
    uint8_t tmp1;
    uint16_t tmp3=0,tmp2=0;
    SD_CS_LOW();
    while((tmp1!=0xfe)&&(tmp3<0xfff))
    {    tmp3++;
        tmp1 = SPI_Data(SPI1, 0xff); //接收开始令牌
    }
    //printf("(0x%x,%d)\n", tmp1, tmp3);
    if(tmp1 != 0xfe) return 1;
   
    while(tmp2<512)//接收512字节数据
    {
        tmp2++;
        *buffer = SPI_Data(SPI1, 0xff);
        buffer++;
    }
    SPI_Data(SPI1, 0xff);//抛弃两字节的CRC校验
    SPI_Data(SPI1, 0xff);
    SD_CS_HIGH();
    return 0;
}
//********************读多个存储块*************************************************
u8 ReadMultipleBlock(uint8_t *buffer1, uint32_t add, uint32_t count)
{
    u8 tmp1;
    //如果不是 SDHC,将 add 地址转成 byte 地址

    if(count==1)
    {//读一个块
        printf("开始发送读单块命令\n");
        tmp1 = SD_SendCmd(SD_CMD17, add, 0xff);
        printf("%d\n",tmp1);
        if(tmp1) return 1;
        printf("发送读单块命令成功\n");
        tmp1 = ReadBlack(buffer1);
        if(tmp1) return 1;
    }
    else if(count>1)
    {//读多个块
        printf("开始发送读多块命令\n");
        tmp1 = SD_SendCmd(SD_CMD18, add, 0xff);//发送读多块的命令
        printf("%d\n",tmp1);
        if(tmp1) return 1;
        printf("发送读多块命令成功\n");
        do
        {
            ReadBlack(buffer1);
            buffer1 += 512;
        }while(count--);
        SD_SendCmd(SD_CMD12, add, 0xff);
    }
    printf("读取成功\n");
    return 0;
}

沙发
cjhk| | 2013-4-14 20:12 | 只看该作者
谢谢楼主共享的资料   谢谢了   呵呵   顶一个   呵呵

使用特权

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

本版积分规则

3

主题

6

帖子

0

粉丝