锆石科技社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 281|回复: 5

SD卡

[复制链接]

5

主题

41

帖子

1196

积分

金牌会员

Rank: 6Rank: 6

积分
1196
发表于 2016-10-17 17:38:25 | 显示全部楼层 |阅读模式
SD卡失败了


//---------------------------------------------------------------------------
//-- 文件名        :        Qsys_Spi.c
//-- 描述                :        利用SPI读写SD卡
//-- 修订历史        :        2014-1-1
//-- 作者                :        Zircon Opto-Electronic Technology CO.,Ltd.
//---------------------------------------------------------------------------
#include "system.h"                                        //系统头文件
#include <stdio.h>                                        //标准的输入输出头文件
#include <unistd.h>                                        //延时函数头文件
#include "alt_types.h"                                //数据类型头文件
#include "altera_avalon_spi_regs.h"        //spi寄存器头文件
#include "altera_avalon_spi.h"                //spi底层驱动头文件

alt_u8 SDReadBlock_Data[512];                //(读)扇区缓冲数组,512字节数据
alt_u8 SDWriteBlock_Data[512];                //(写)扇区缓冲数组,512字节数据

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDWriteByte()
//-- 功能                :        往Spi中写数据函数
//-- 输入参数        :        txdata:需要发送的数据
//-- 输出参数        :        无
//---------------------------------------------------------------------------
void Spi_SDWriteByte(alt_u8 txdata)
{
        //往Spi中写一个字节
        alt_avalon_spi_command(SPI_BASE, 0, 1, &txdata, 0, NULL, 0);
}

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDReadByte()
//-- 功能                :        从Spi中读数据函数
//-- 输入参数        :        无
//-- 输出参数        :        readbuf:从Spi中读取出来的数据
//---------------------------------------------------------------------------
alt_u8 Spi_SDReadByte()
{
        alt_u8 readbuf;
        //从Spi中读一个字节
        alt_avalon_spi_command(SPI_BASE, 0, 0, NULL, 1, &readbuf, 0);
        return(readbuf);
}

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDReadByte()
//-- 功能                :        往SD卡中写命令函数
//-- 输入参数        :        cmd:Byte1命令;arg:Byte2~Byte5命令;crc:Byte6命令
//-- 输出参数        :        r1:响应变量
//---------------------------------------------------------------------------
alt_u8 Spi_SDSendCmd(alt_u8 cmd,alt_u32 arg,alt_u8 crc)
{
    alt_u8 r1;                                                //响应变量
    alt_u8 time = 0;                                //超时变量

    //SD卡的命令格式如下,6字节共48位,传输时最高位(MSB)先传输
    Spi_SDWriteByte(cmd | 0x40);        //写Byte1
    Spi_SDWriteByte(arg>>24);                //写Byte2
    Spi_SDWriteByte(arg>>16);                //写Byte3
    Spi_SDWriteByte(arg>>8);                //写Byte4
    Spi_SDWriteByte(arg);                        //写Byte5
    Spi_SDWriteByte(crc);                        //写Byte6

        //写入命令后,附加8个填充时钟,等待SD卡回应
        do{

                r1 = Spi_SDReadByte(); //读数据
                time++;
                if(time > 254)        return 1; //超时退出返回1

        }while(r1 == 0xff);

    return r1; //命令写入成功,返回响应变量
}

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDReset()
//-- 功能                :        SD卡复位函数
//-- 输入参数        :        无
//-- 输出参数        :        0:成功;1:失败
//---------------------------------------------------------------------------
alt_u8 Spi_SDReset(void)
{
        alt_u8 i;                        //循环变量
    alt_u8 r1;                        //响应变量
    alt_u8 time = 0;        //超时变量

    //发送至少74个clk周期来使SD卡达到正常工作电压和进行同步
    for(i = 0;i < 16;i ++)
            Spi_SDWriteByte(0xff);

    //发送CMD0,需要收到回应0x01表示成功
    do{

        r1 = Spi_SDSendCmd(0,0,0x95); //发送CMD0命令
        time++;
        if(time > 254)         return 1; //超时退出返回1

    }while(r1 != 0x01);        //等待返回0x01

    return 0; //复位成功,则返回0
}

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDInit()
//-- 功能                :        SD卡初始化函数
//-- 输入参数        :        无
//-- 输出参数        :        0:成功;1:失败
//---------------------------------------------------------------------------
alt_u8 Spi_SDInit(void)
{
        alt_u8 r1;                        //响应变量
        alt_u8 time = 0;        //超时变量
    alt_u32 r7 = 0;                //响应变量

    //发送CMD8检测接口条件,若r1返回0x01,r7返回0x000001aa,则表示检测成功
        do{

                r1 = Spi_SDSendCmd(8,0x000001aa,0x87);         //发送CMD8命令
        r7 += Spi_SDReadByte();                                 //读取响应0x00
        r7 <<= 8;
        r7 += Spi_SDReadByte();                                 //读取响应0x00
        r7 <<= 8;
        r7 += Spi_SDReadByte();                                 //读取响应0x01
        r7 <<= 8;
        r7 += Spi_SDReadByte();                                 //读取响应0xaa
                time++;
                if(time > 254) return 1;                                //超时退出返回1

        }while((r1 != 0x01) && (r7 != 0x000001aa));        //等待r1返回0x01,r7返回0x000001aa

        time = 0;

        //此处省略发送CMD58命令

        //发送CMD55+ACMD41,收到0x00表示成功
        do{

                r1 = Spi_SDSendCmd(55,0,0xff); //发送CMD55命令
                if(r1 == 0x01) r1 = Spi_SDSendCmd(41,0x40000000,0xff); //发送ACMD41命令
                time++;
                if(time > 254) return 1; //超时退出返回1

        }while(r1 != 0x00); //等待返回0x00

        //此处省略发送CMD58命令

        return 0; //初始化成功,则返回0
}

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDReadBlock()
//-- 功能                :        读取SD卡一个扇区数据
//-- 输入参数        :        address:扇区地址
//-- 输出参数        :        0:成功;1:失败
//---------------------------------------------------------------------------
alt_u8 Spi_SDReadBlock(alt_u32 address)
{
    alt_u8 r1;                        //响应变量
    alt_u32 i = 0;                //循环变量

    //发送CMD17命令,收到0x00表示成功
    r1 = Spi_SDSendCmd(17,address,0xff); //发送CMD17命令
    if(r1 != 0x00) return 1;

    //连续读直到读到开始字节0xFE
    while (Spi_SDReadByte()!= 0xfe);

    //读取一个扇区512字节数据
    for(i = 0; i < 512; i++)
            SDReadBlock_Data[i] = Spi_SDReadByte();

    //读取两个字节CRC校验
    Spi_SDReadByte();
    Spi_SDReadByte();

    return 0; //读取成功,则返回0
}

//---------------------------------------------------------------------------
//-- 名称                :        Spi_SDWriteBlock()
//-- 功能                :        写入SD卡一个扇区数据
//-- 输入参数        :        sector:扇区地址;buffer:写入SD卡的数据首地址
//-- 输出参数        :        0:成功;1:失败
//---------------------------------------------------------------------------
alt_u8 Spi_SDWriteBlock(alt_u32 sector, alt_u8* buffer)
{
    alt_u8 r1;                        //响应变量
    alt_u32 i;                        //循环变量

    //发送CMD24命令,收到0x00表示成功
    r1 = Spi_SDSendCmd(24, sector<<9, 0xff); //发送CMD24命令
    if(r1 != 0x00) return 1; //写入失败,返回1

    //发送若干时钟
    for(i =0; i < 5; i++)
            Spi_SDWriteByte(0xff); //送8个时钟周期脉冲

    //发送写扇区开始字节0xFE
    Spi_SDWriteByte(0xfe);

    //发送512个字节数据
    for(i = 0; i < 512; i++)
            Spi_SDWriteByte(*buffer++);

    //发送2字节CRC校验
    Spi_SDWriteByte(0xff);
    Spi_SDWriteByte(0xff);

    //连续读直到读到XXX00101表示数据写入成功
    r1 = Spi_SDReadByte();
    if((r1 & 0x1f) != 0x05) return 1; //写入失败,返回1

    //继续读进行忙碌检测,当读到0xff表示写操作完成
    while(!Spi_SDReadByte());

    return 0;
}

//---------------------------------------------------------------------------
//-- 名称                :        main()
//-- 功能                :        程序入口
//-- 输入参数        :        无
//-- 输出参数        :        无
//---------------------------------------------------------------------------
int main(void)
{
    alt_u32 i;

    if(Spi_SDReset()) //SD卡复位
            printf("SD Reset Failed!");
    else
        printf("SD Reset Succeed!");

    if(Spi_SDInit()) //SD卡初始化
            printf("SD Inint Failed!");
    else
            printf("SD Inint Succeed!");

    for(i = 0; i < 512; i++) //初始化写入数据
                SDWriteBlock_Data[i] = i;

    if(Spi_SDWriteBlock(0, SDWriteBlock_Data)) //写一个扇区
            printf("SD Write Failed!");
    else
            printf("SD Write Succeed!");

    Spi_SDReset();
    Spi_SDInit(); //SD卡复位并初始化

    if(Spi_SDReadBlock(0)) //读一个扇区
            printf("SD Read  Failed!");
    else
            printf("SD Read  Succeed!\n");

    for(i = 0; i < 16; i++) //读取16个字节数据
            printf("0x%.2x,",SDReadBlock_Data[i]);

    return 0;
}



回复

使用道具 举报

5

主题

41

帖子

1196

积分

金牌会员

Rank: 6Rank: 6

积分
1196
 楼主| 发表于 2016-10-17 17:38:46 | 显示全部楼层
图片传不上去
回复 支持 反对

使用道具 举报

发表于 2016-10-17 17:39:57 | 显示全部楼层
SD卡的容量是多大的?
回复 支持 反对

使用道具 举报

5

主题

41

帖子

1196

积分

金牌会员

Rank: 6Rank: 6

积分
1196
 楼主| 发表于 2016-10-17 17:43:12 | 显示全部楼层
8G                                    
回复 支持 反对

使用道具 举报

发表于 2016-10-17 17:46:11 | 显示全部楼层
8G的是支持的,还有没有其他SD卡,或者多尝试几次。
回复 支持 反对

使用道具 举报

0

主题

26

帖子

66

积分

注册会员

Rank: 2

积分
66
发表于 2016-11-17 10:06:59 | 显示全部楼层
我也不懂mark大哭
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|锆石科技社区 ( 苏ICP备15059756号  

GMT+8, 2019-5-27 03:17 , Processed in 0.145236 second(s), 28 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表