织梦CMS - 轻松建站从此开始!

罗索

sd卡驱动代码分析-sd.h

罗索客 发布于 2011-09-13 15:56 点击:次 
很多部分参考网友(波仔)的
TAG:

************************************************************/
#ifndef _SD_INCLUDED_
#define _SD_INCLUDED_
#include <util/delay.h>
//正点原子@scut 08/09/11
//很多部分参考网友(波仔)的
#include "myspi.h"


#define SD_CS_H    SET_BIT(PORTB,0)
#define SD_CS_L    CLR_BIT(PORTB,0)

       
unsigned char BUFFER[512]; //扇区缓冲区
unsigned char reading=0;     //标记读写,1:读

void spi_init(void);    //初始化spi
unsigned char SD_Write_Command(unsigned char cmd,unsigned long arg);//写命令到sd卡
void sd_port_init(void);//初始化sd卡的io
unsigned char SD_Init(void);     //sd卡初始化            
unsigned char SD_Read_Block(unsigned long address); //读取一个块数据
#define   sd_port_init() {SD_CS_H;}
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
//****************************************************************************
unsigned char SD_Write_Command(unsigned char cmd,unsigned long arg)
{
    unsigned char tmp;
    unsigned char retry=0;

    SD_CS_H;      //SD卡关闭  
    //send 8 Clock Impulse
    Write_Byte_SPI(0xFF);
    SD_CS_L;      //SD卡使能
    Write_Byte_SPI(cmd|0x40);   //送头命令
    Write_Byte_SPI(arg>>24);
    Write_Byte_SPI(arg>>16);    //send 6 Byte Command to MMC/SD-Card
    Write_Byte_SPI(arg>>8);
    Write_Byte_SPI(arg&0xff);
    Write_Byte_SPI(0x95);       //仅仅对RESET有效的CRC效验码
       //get 8 bit response
    do //Read_Byte_MMC(); //read the first byte,ignore it.
    {
        tmp = Read_Byte_SPI(); //Only last 8 bit is used here.Read it out.
        retry++;
    }
    while((tmp==0xff)&&(retry<100));   //当没有收到有效的命令的时候
    if(reading==0)SD_CS_H;//MMC_CS_PIN=1;
    else SD_CS_L;        //MMC_CS_PIN=0;  
    return(tmp);
}
//****************************************************************************
//SD卡初始化(SPI-MODE)
//****************************************************************************
unsigned char SD_Init(void)
{
    unsigned char retry,temp;
    unsigned char i;
    SD_CS_L; //SD卡使能
    _delay_us(250);         //Wait MMC/SD ready...等待MMC/SD卡准备就绪
    for (i=0;i<0x0f;i++)
    {
        Write_Byte_SPI(0xff); //send 74 clock at least!!!
    }
    retry=0;
    do//Send Command CMD0 to MMC/SD Card
    {
        temp=SD_Write_Command(0,0);//retry 200 times to send CMD0 command
        retry++;
        if(retry==100)return 0xff;//CMD0 Error!
    }
    while(temp!=1);
    retry=0;
    do//Send Command CMD1 to MMC/SD-Card
    {
        temp=SD_Write_Command(1,0);//retry 100 times to send CMD1 command
        retry++;
        if(retry==100);
    }while(temp!=0);
    retry=0;
    SD_Write_Command(16,512);     //设置一次读写BLOCK的长度为512个字节
    SD_CS_H;   //MMC_CS_PIN=1; //set MMC_Chip_Select to high 设置到高位
    return(0); //All commands have been taken.
}
//****************************************************************************
//从SD卡读一个扇区 Return 0 if no Error.
//address:所在的物理扇区编号
//返回值:!0xff
//****************************************************************************
unsigned char SD_Read_Block(unsigned long address)
{
    unsigned char temp=0;
unsigned int i=0;
    reading=1;
    temp=SD_Write_Command(17,address); //读出RESPONSE    
    while(Read_Byte_SPI()!= 0xfe)SET_BIT(PORTA,1);//直到读取到了数据的开始头0XFE,才继续
    CLR_BIT(PORTA,1);
    for(i=0; i<512; i++)
{
     BUFFER[i]=Read_Byte_SPI();
}
    Read_Byte_SPI();//CRC - Byte
    Read_Byte_SPI();//CRC - Byte
    reading=0;
    SD_CS_H;;        //关闭SD卡
    return(temp);
}
//****************************************************************************
//从SD卡读一个扇区 Return 0 if no Error.
//****************************************************************************
unsigned char SD_Read_Block2(unsigned long address,unsigned char *buf)
{
    unsigned char temp=0;unsigned int i=0;
    reading=1;
    temp=SD_Write_Command(17,address);     //读出RESPONSE    
    while (Read_Byte_SPI()!= 0xfe);//直到读取到了数据的开始头0XFE,才继续
    for(i=0; i<512; i++)
{
        buf[i]=Read_Byte_SPI();
}
    Read_Byte_SPI();//CRC - Byte
    Read_Byte_SPI();//CRC - Byte
    reading=0;
    SD_CS_H;        //关闭SD卡
    return(temp);
}

//从指定位置读取一个字
unsigned int SD_Read_Word(unsigned long address,unsigned int offset)
{
    unsigned char temp=0;unsigned int i=0;
    unsigned char k=0;
    unsigned char buf[2];
    reading=1;
    temp=SD_Write_Command(17,address<<9);     //读出RESPONSE    
    while (Read_Byte_SPI()!= 0xfe);//直到读取到了数据的开始头0XFE,才继续
    for(i=0;i<offset;i++)Read_Byte_SPI();
    for(;i<offset+2;i++)buf[k++]=Read_Byte_SPI();
    for(;i<512;i++)Read_Byte_SPI();
    Read_Byte_SPI();
    Read_Byte_SPI();
    reading=0;
    SD_CS_H;        //关闭SD卡        
    return (*((unsigned int*) &((char*)buf)[0])) ;
}     
//连续读取指定扇区offset偏移位置,bytes个数据
void SD_Read_Bytes(unsigned long address,unsigned char *buf,unsigned int offset,unsigned int bytes)
{
    unsigned char temp=0;unsigned int i=0;
    reading=1;
    temp=SD_Write_Command(17,address<<9);     //读出RESPONSE    
    while (Read_Byte_SPI()!= 0xfe);//直到读取到了数据的开始头0XFE,才继续
   for(i=0;i<offset;i++) Read_Byte_SPI();
    for(;i<offset+bytes;i++)   *buf++=Read_Byte_SPI();
    for(;i<512;i++) Read_Byte_SPI();
    Read_Byte_SPI();
    Read_Byte_SPI();
    reading=0;
    SD_CS_H;        //关闭SD卡
}
#endif

(正点原子)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201109/14986.html]
本文出处:网络 作者:正点原子
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容