📄 sd._c
字号:
#include<all.h>
#include<vs1001k.h>
#include<sd.h>
#define SD_INIT_TRY 50
#define SD_IDLE_WAIT_MAX 100 //等待进入IDLE次数
#define SD_CMD_TIMEOUT 100 //读CMD次数
#define TIMEOUT_WRITE 10000 // 8M/8
#define TIMEOUT_READ 400000 // 8M/20
uchar mp3_data[DATA_LENGTH];
uchar response[5];
void sd_wait_nobusy(void)
{
while(read_single()!=0xff);
select_vs;
}
void sd_delay(uchar dat)
{ uint n;
for(n=0;n<dat;n++)
write_single(0xff);
}
/****************sd 发命令**********************/
uchar sd_write_command(uchar cmd,uchar response_type,ulong arg,uchar *response)
{ uchar response_length,dat;
int n;
select_sd;//选择SD
write_single(cmd|0x40);
write_single(arg>>24);
write_single(arg>>16);
write_single(arg>>8);
write_single(arg);
write_single(0x95);//CRC 对于CMD0有效,SPI忽略
response_length=0;
switch(response_type)
{ case R1:
case R1B:response_length=1;break;
case R2: response_length=2;break;
case R3: response_length=5;break;
default: break;
}
n=0;
do //等待响应
{ dat=read_single();
n++;
}
while(((dat&0x80)!=0)&&(n<SD_CMD_TIMEOUT));
if(n>=SD_CMD_TIMEOUT) //超时
{ select_vs;
return 0;
}
for(n=response_length-1;n>=0;n--)//取数据
{ response[n]=dat;
dat=read_single();
}
if(response_type==R1B)//忙等待结束
{ do
{ dat=read_single();}
while(dat!=0xff);
write_single(0xff);
}
select_vs;//释放SD
return 1;
}
uchar read_block(ulong blockadd,uint length,uchar *mp3_data)
{ uchar dat;
ulong n;
sd_wait_nobusy();
if(sd_write_command(CMD16,CMD16_R,length,response)==0)//设置读取数据的长度
return 0;
//blockadd<<=9;//增加512B
if(sd_write_command(CMD17,CMD17_R,blockadd,response)==0)
return 0;
if(response[0]!=0)//出现error
return 0;
select_sd;
n=0;
do
{ dat=read_single();
n++;
}
while((dat==0xff)&&(n<TIMEOUT_READ));//读出数据的头0xfe
for(n=0;n<length;n++)
{ mp3_data[n]=read_single();}
read_single();//CRC 16bit
read_single();
select_vs;
return 1;
}
void sd_read_block(ulong blockadd,uint length,uchar *mp3_data)//读SD数据
{ while(read_block(blockadd,length,mp3_data)==0);}
uchar do_sd_init(void)//sd初始化
{ uchar n;
delay(200);
select_sd;
sd_delay(100);
select_vs;
sd_delay(2);
if(sd_write_command(CMD0,CMD0_R,0,response)==0)
return 0;
n=0;
do
{ n++;
if(sd_write_command(CMD55,CMD55_R,0,response)==1)//进入special command
{ /*getin OCR*/
sd_write_command(ACMD41,ACMD41_R,0,response);
}
else
n=SD_IDLE_WAIT_MAX; //no response
delay(500);//经调试需要加延迟
}
while(((response[0]&MSK_IDLE)==MSK_IDLE)&&(n<SD_IDLE_WAIT_MAX));
if(n>=SD_IDLE_WAIT_MAX)
return 0;
if(sd_write_command(CMD58,CMD58_R,0,response)==0)//读取OCR
return 0;
if((response[2]&MSK_OCR_33)!=MSK_OCR_33)//电压最低为3.3V
return 0;
/*set block length
if(sd_write_command(CMD16,CMD16_R,DATA_LENGTH,response)==0)
return 0;
*/
return 1;
}
uchar sd_init(void)
{ uchar n,j;
j=0;
for(n=0;(n<SD_INIT_TRY)&&(j!=1);n++)
j=do_sd_init();
if(n>=SD_INIT_TRY)//超次数
return 0;
return 1;
}
/****************song***************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -