📄 sd.c
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&SD卡驱动&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//*文件名称:sd.c
//*文件作用:SD卡驱动
//*文件作者:翟 鹏
//*创建日期:2004年5月
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include <include.h>
static uchar bdata Data=0;
sbit Data0=Data^0;
sbit Data1=Data^1;
sbit Data2=Data^2;
sbit Data3=Data^3;
sbit Data4=Data^4;
sbit Data5=Data^5;
sbit Data6=Data^6;
sbit Data7=Data^7;
static uchar xdata CMD17[]={0x51,0x00,0x00,0x00,0x00,0xFF};//cmd17
//***********************************************************************************************************************
//函数作用:io口模拟spi
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static void sd_write(void)
{
SD_CLK=0;
SD_DI=Data7;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data6;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data5;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data4;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data3;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data2;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data1;
SD_CLK=1;
SD_CLK=0;
SD_DI=Data0;
SD_CLK=1;
}
//***********************************************************************************************************************
//函数作用:io口模拟spi
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static void sd_read(void)
{
SD_CLK=0;
SD_CLK=1;
Data7=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data6=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data5=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data4=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data3=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data2=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data1=SD_DO;
SD_CLK=0;
SD_CLK=1;
Data0=SD_DO;
}
//***********************************************************************************************************************
//函数作用:发送命令----在初始化时使用
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static uchar sd_send_cmd_init(uchar *cmd)
{
uchar xdata a,timeout=0;
SD_CS=1;
Data=0xff;sd_write();
SD_CS=0;
Data=cmd[0];sd_write();
Data=cmd[1];sd_write();
Data=cmd[2];sd_write();
Data=cmd[3];sd_write();
Data=cmd[4];sd_write();
Data=cmd[5];sd_write();
Data=0xff;
while(Data==0xff)
{
sd_read();
for(a=0;a<255;a++);
for(a=0;a<255;a++);
for(a=0;a<255;a++);
if(timeout++>100)break;
}
return Data;
}
//***********************************************************************************************************************
//函数作用:发送命令----在读写数据时使用
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static uchar SD_Send_Cmd(void)
{
uchar xdata timeout=0;
SD_CS=1;
Data=0xff;sd_write();
SD_CS=0;
Data=CMD17[0];sd_write();
Data=CMD17[1];sd_write();
Data=CMD17[2];sd_write();
Data=CMD17[3];sd_write();
Data=CMD17[4];sd_write();
Data=CMD17[5];sd_write();
Data=0xff;
while(Data==0xff)
{
sd_read();
if(timeout++>100)break;
}
return Data;
}
//***********************************************************************************************************************
//函数作用:初始化
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
uchar SD_Init(void)
{
uchar xdata retry;
uchar xdata CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//cmd0
SD_CS=1;
Data=0xff;sd_write();
SD_CS=0;
//Send the 1st command
retry=0;
while(sd_send_cmd_init(CMD)!=0x01)
{
dog();
if(retry++>200)return 1;
}
//Send the 2nd command
retry=0;
CMD[0]=0x41;
CMD[5]=0xFF;
while(sd_send_cmd_init(CMD)!=0x00)
{
dog();
if(retry++>200)return 2;
}
//Send the third command set block size
retry=0;
CMD[0]=0x50;
CMD[3]=((512&0xFF00)>>8);
CMD[4]=(512&0x00FF);
CMD[5]=0xFF;
while(sd_send_cmd_init(CMD)!=0x00)
{
dog();
if(retry++>200)return 3;
}
SD_CS=1;
return 0;
}
//***********************************************************************************************************************
//函数作用:设置当前扇区地址
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
void SD_Set_SectorAddr(ulong addr)
{
(ulong)addr<<=9;
*((ulong *)&CMD17[1])=addr;
}
//***********************************************************************************************************************
//函数作用:读取当前扇区的某个字节
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
uchar SD_Read_SectorByte(uint ByteAddr, uchar *ch)
{
uint data a;
uchar data retry=0;
//Send the read command
while(SD_Send_Cmd()!=0)
{
dog();
if(retry++>200)return 1;
}
//Send the start byte
retry=0;
Data=0;
while(Data!=0xfe)
{
sd_read();
if(++retry>=200)return 1;
dog();
}
//Read off all the bytes in the block
for(a=0;a<512;a++)
{
sd_read();
if(a==ByteAddr)*ch=Data;
}
//Read CRC byte
sd_read();
sd_read();
// Set SD_Chip_Select to high
SD_CS=1;
return 0;
}
//***********************************************************************************************************************
//函数作用:读取当前扇区的某些字节
//参数说明:
//注意事项:
//返回说明:无
//***********************************************************************************************************************
uchar SD_Read_Sector_Offset(uint Offset, uchar *buf, uint length)
{
uint data a;
uchar data retry=0;
//Send the read command
while(SD_Send_Cmd()!=0)
{
dog();
if(retry++>200)return 1;
}
//Send the start byte
retry=0;
Data=0;
while(Data!=0xfe)
{
sd_read();
if(++retry>=200)return 1;
dog();
}
//Read all the bytes in the block
for(a=0;a<512;a++)
{
sd_read();
if(a>=Offset && length)
{
*buf=Data;
buf++;
length--;
}
}
//Read CRC byte
sd_read();
sd_read();
// Set SD_Chip_Select to high
SD_CS=1;
return 0;
}
//9.write 512 bytes to a given sector from a Byte_byte_long Buffer
/*
uchar SD_Write_Sector(ulong addr,uchar *Buffer)
{
uint xdata a;
uchar xdata retry,temp;
uchar xdata CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};//cmd24
addr = addr << 9; //addr = addr * 512
CMD[1]=((addr&0xFF000000)>>24);
CMD[2]=((addr&0x00FF0000)>>16);
CMD[3]=((addr&0x0000FF00)>>8);
CMD[4]=(addr&0x000000FF);
//Send the write command
while(SD_Send_Cmd(CMD)!=0)
{
if (retry++>50)return 1;
}
//Send the start byte
sd_write(0xfe);
//Read off all the bytes in the block
for(a=0;a<512;a++)
{
sd_write(*Buffer++);
}
while((temp=sd_read())&0x10);
if((temp&0x0f)!=0x05)return 2;
//Read CRC byte
while(!SD_DO);//detect if data_in pb.4 is still busy(high)
// Set SD_Chip_Select to high
SD_CS=1;
return 0;
}
uchar SD_Read_Sector(ulong addr, uchar *Buffer)
{
uint xdata a;
uchar xdata retry;
uchar xdata CMD[]={0x51,0x00,0x00,0x00,0x00,0xFF};//cmd17
addr = addr << 9; //addr = addr * 512
CMD[1]=((addr&0xFF000000)>>24);
CMD[2]=((addr&0x00FF0000)>>16);
CMD[3]=((addr&0x0000FF00)>>8);
CMD[4]=(addr&0x000000FF);
//Send the read command
while(SD_Send_Cmd(CMD)!=0)
{
if (retry++>200)return 1;
}
//Send the start byte
while(sd_read()!=0xfe)
{
}
//Read off all the bytes in the block
for(a=0;a<512;a++)
{
*Buffer=sd_read();
Buffer++;
}
//Read CRC byte
sd_read();
sd_read();
// Set SD_Chip_Select to high
SD_CS=1;
return 0;
}
*/
/*
//6.硬spi写指令及读响应
uchar SD_Send_Cmd(char *CMD)
{
uchar a;
uchar tmp=0xff;
uchar Timeout=0;
// Raise chip select -----/ss=1
SD_CS=1();
// Send an 8 bit pulse
Write_Byte_SD(0xFF);
// Lower chip select
SD_CS=0;
//Send the 6 byte command
for(a=0;a<0x06;a++)
{
Write_Byte_SD(*CMD++);
}
//Wait for the response
while(tmp==0xff)//
{
tmp=Read_Byte_SD();
if(Timeout++>100)
{
break;
}
}
//for some reason we need to delay here
//delay_1ms();
return(tmp);//the respone of the byte_write_operation
}
//read xx bytes no matter of misalignment!!
uchar read_antimisaliment(unsigned long addr_temp,uchar *p_buffer, uint length)
{
uint _length=0x0000;
SD_CS=0;
while(SD_read_sector(addr_temp,p_buffer,length))
{
SD_CS=0;//
length-=0x0001;//to find a suuitable length to avoid misalignment
_length+=0x0001;// _length+length==xx
SD_set_length(length);
}
///
if(_length==0x0000)
{
return 0;
}
///
addr_temp+=length;
SD_CS=0;//
SD_set_length(_length);
SD_CS=0;//
while(SD_read_sector(addr_temp,p_buffer,_length))
{
SD_CS=0;
}
SD_CS=0;//
SD_set_length(length+_length);//to read the rest bytes of the xx bytes
return 0;
/////////////////
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -