SD卡扇区读写程序 经测试通过
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include"SDcard.h"
char Is_Init=0;
void SD_Port_Init()
{
DO_DIR_OUT;
CS_DIR_OUT;
CLK_DIR_OUT;
SET_SD_CLK;
SET_SD_DO;
SET_SD_CS;
}
void Write_Byte_SD(uchar value)
{
unsigned char i;
for (i=0;i<8;i++)
{
if (value&0x80)
SET_SD_DI; //Send bit by bit(MSB First)
else
CLR_SD_DI;
value <<=1;
}
}
unsigned char Read_Byte_SD()
{
unsigned char i=0,temp=0;
SET_SD_DO;
for(i=0;i<8;i++)
{
DO_DIR_IN; //设置为输入
CLR_SD_CLK;
SET_SD_CLK;
temp<<=1;
if(SD_DO) temp|=0x01;
// DO_DIR_OUT ;//设置为输出
delay(5);
}
return temp;
}
//-----------------------------------------------------------------------------------------------
// 向SD卡中写入命令,并返回回应的第二个字节
//-----------------------------------------------------------------------------------------------
unsigned char Write_Command_SD(unsigned char *CMD)
{
unsigned char tmp,time=0,i;
SET_SD_CS; //禁止SD卡片选
Write_Byte_SD(0xFF); //发送8个时钟信号
CLR_SD_CS; //使能SD卡片选
for (i=0;i<0x08;i++) //向SD卡发送6字节命令
{
Write_Byte_SD(*CMD++);
}
//获得16位的回应
Read_Byte_SD(); //read the first byte,ignore it.
do
{ //读取后8位
tmp = Read_Byte_SD();
time++;
}
while((tmp==0xff)&&(time<100));
return(tmp);
}
unsigned char SD_Reset()
{
unsigned char tmp,time=0,i;
unsigned char pcmd[]={0x40,0x00,0x00,0x00,0x00,0x95};
SD_Port_Init(); //初始化驱动端口
SET_SD_CS; //禁止SD卡片选
Is_Init=1; //将初始化标志置1
for (i=0;i<0x0f;i++)
{
Write_Byte_SD(0xff); //发送至少74个时钟信号
}
CLR_SD_CS; //使能SD卡片选
time=0;
do
{ //为了能够成功写入CMD0,在这里写200次
tmp=Write_Command_SD(pcmd);
time++;
if(time==200)
{ //超过200次
return(INIT_CMD0_ERROR);//CMD0 Error!
}
}
while(tmp!=1); //回应01h,停止写入
SET_SD_CS; //禁止SD卡片选
Write_Byte_SD(0xff);
return 0;
}
unsigned char SD_Init()
{
unsigned char tmp,time=0;
unsigned char pcmd[]={0x41,0x00,0x00,0x00,0x00,0xff};
CLR_SD_CS; //使能SD卡片选
do
{ //为了能够成功写入CMD0,在这里写200次
tmp=Write_Command_SD(pcmd);
time++;
if(time==200)
{ //超过200次
return(INIT_CMD1_ERROR);//CMD0 Error!
}
}
while(tmp!=0); //回应00h,停止写入
Is_I
nit=0;
SET_SD_CS; //禁止SD卡片选
Write_Byte_SD(0xff);
return 0;
}
unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer)
{
unsigned char temp,time=0;
unsigned int i;
unsigned char pcmd[]={0x58,0x00,0x00,0x00,0x00,0xFF};
addr<<=9;
pcmd[1] = ((addr & 0xFF000000) >>24 );
pcmd[2] = ((addr & 0x00FF0000) >>16 );
CLR_SD_CS; //使能SD卡片选
time=0;
do
{ //为了可靠写入,写100次
time++;
if(time==100)
{
return(temp); //send commamd Error!
}
}
while(temp!=0);
//在写之前先产生100个时钟信号
for (i=0;i<100;i++)
{
Read_Byte_SD();
}
//写入开始字节
Write_Byte_SD(0xFE);
//现在可以写入512个字节
for (i=0;i<512;i++)
{
Write_Byte_SD(*Buffer++);
}
//CRC-Byte
Write_Byte_SD(0xFF); //Dummy CRC
Write_Byte_SD(0xFF); //CRC Code
temp=Read_Byte_SD();
if((temp & 0x1F)!=0x05) // 写入的512个字节是未被接受
{
SET_SD_CS; //禁止SD卡片选
return(WRITE_BLOCK_ERROR); //Error!
}
//等到SD卡不忙为止
//因为数据被接受后,SD卡在向储存阵列中编程数据
while (Read_Byte_SD()!=0xff);
SET_SD_CS; //禁止SD卡片选
Write_Byte_SD(0xff);
return(0);//写入成功
}
uchar SD_read_sector(unsigned long addr,uchar *buffer)
{
uchar temp,time=0;
uint i=0;
uchar pcmd[]={0x51,0x00,0x00,0x00,0x00,0xff};
addr<<=9;
pcmd[1]=((addr&0xff000000)>>24);
pcmd[2]=((addr&0x00ff0000)>>16);
CLR_SD_CS; //使能SD卡片选
do
{
time++;
if(time==200)
{
return (READ_BLOCK_ERROR);
}
}while(temp!=0);
while(Read_Byte_SD()!=0xfe);
for(i=0;i<512;i++)
{
buffer[i]=Read_Byte_SD();
}
Read_Byte_SD();
Read_Byte_SD();
SET_SD_CS; //禁止SD卡片选
Write_Byte_SD(0xff);
return 0;
}