📄 sdcard.c
字号:
{
SPI1_SrByte(0XFF); //send 74 clock at least!!!
}
retry=0;
do
{
temp=SD_WriteCom(CMD0,0); //Send Command CMD0 to MMC/SD Card
retry++;
if(retry>=200)
{
return(0);
}
}
while(temp!=0x01);
retry=0;
do
{
temp=SD_WriteCom(CMD1,0); //Send Command CMD1 to MMC/SD-Card
retry++;
if(retry>=200)
{
return(0);
}
}
while(temp!=0);
retry=0;
SD_WriteCom(16,512); //设置一次读写BLOCK的长度为512个字节
SPI1_CS_SET(); //MMC_CS_PIN=1; //set MMC_Chip_Select to high
SPI1_Init(2);
return 1; //All commands have been taken.
}
/**************************************************************************************************
**Name:
**Function:
**Input:
**Output:
**************************************************************************************************/
INT8U Fat_Init(void)
{
SD_ReadBlock(0,BUFFER); //read partion message // 读MBR结构//struct bpb710 *bpb;
// 读取分区表信息// 读引导扇区// 引导扇区号在PartInfo.prStartLBA中
Partition_PartType= BUFFER[450]; //分区信息 FAT32 0x0B
Partition_Size = BUFFER[458]+(BUFFER[459]<<8)+(BUFFER[460]<<16)+(BUFFER[461]<<24);
Partition_StartLBA = BUFFER[454]+(BUFFER[455]<<8)+(BUFFER[456]<<16)+(BUFFER[457]<<24); //0xF9*512=127488
SD_ReadBlock(Partition_StartLBA,BUFFER); //FAT32 read BPB
BS_OEMName[0] = BUFFER[3];
BS_OEMName[1] = BUFFER[4];
BS_OEMName[2] = BUFFER[5];
BS_OEMName[3] = BUFFER[6];
BS_OEMName[4] = BUFFER[7];
BS_OEMName[5] = BUFFER[8];
BS_OEMName[6] = BUFFER[9];
BS_OEMName[7] = BUFFER[10];
BPB_BytesPerSec = BUFFER[11] |(BUFFER[12] << 8); //0x0200 //每个扇区字节数
BPB_SecPerClus = BUFFER[13]; //0x08 //每个簇的扇区数
BPB_RsvdSecCnt = BUFFER[14] |(BUFFER[15] << 8); //0x20 //保留扇区数
BPB_NumFATs = BUFFER[16]; //0x02 //FAT 表数目
BPB_RootEntCnt = BUFFER[17] | (BUFFER[18] << 8);
BPB_TotSec16 = BUFFER[19] | (BUFFER[20] << 8);
BPB_Media = BUFFER[21];
BPB_FATSz16 = BUFFER[22] | (BUFFER[23] << 8);
BPB_SecPerTrk = BUFFER[24] | (BUFFER[25] << 8);
BPB_NumHeads = BUFFER[26] | (BUFFER[27] << 8);
BPB_HiddSec = BUFFER[28] | (BUFFER[29] << 8) | (BUFFER[30] << 16) | (BUFFER[31] << 24);
BPB_TotSec32 = BUFFER[32] | (BUFFER[33] << 8) | (BUFFER[34] << 16) | (BUFFER[35] << 24);
BPB_FATSz32 = BUFFER[36] | (BUFFER[37] << 8) | (BUFFER[38] << 16) | (BUFFER[39] << 24);
BPB_ExtFlags = BUFFER[40] | (BUFFER[41] << 8);
BPB_FSVer = BUFFER[42] | (BUFFER[43] << 8);
BPB_RootClus = BUFFER[44] | (BUFFER[45] << 8) | (BUFFER[46] << 16) | (BUFFER[47] << 24);
BPB_FSInfo = BUFFER[48] | (BUFFER[49] << 8);
BPB_BKBootSec = BUFFER[50] | (BUFFER[51] << 8);
//BPB_Reserved = BUFFER[52];
BS_drvNum = BUFFER[64];
BS_Reservd1 = BUFFER[65];
BS_BootSig = BUFFER[66];
BS_VolID = BUFFER[67] | (BUFFER[68] << 8) | (BUFFER[69] << 16) | (BUFFER[70] << 24);
//BS_VolLab[0] = BUFFER[71];
//BS_FilSysType[0] = BUFFER[82];
switch(Partition_PartType)
{
case PART_TYPE_FAT12:
break;
case PART_TYPE_DOSFAT16:
case PART_TYPE_FAT16:
case PART_TYPE_FAT16LBA:
break;
case PART_TYPE_FAT32LBA:
case PART_TYPE_FAT32:
FAT_MASK = FAT32_MASK; //0x0fffffff
Clust = BPB_RootClus;
FAT1Sec = BPB_RsvdSecCnt+Partition_StartLBA;
FAT2Sec = FAT1Sec+BPB_FATSz32;
FirstDataSector = FAT2Sec+BPB_FATSz32;
break;
default:
return 0;
}
return 1;
}
/*****************************************************************************************
* 名称:ReadBlockforCluster
* 功能:读一个扇区至 pbuff[]
* 输入:INT32U LBA
INT8U *pbuff
* 返回:无
*****************************************************************************************/
INT32U ReadBlockforCluster(INT32U Sector,INT32U offset)
{
INT32U tmp;
SD_ReadBlock(Sector,BUFFER);
tmp=BUFFER[offset] |(BUFFER[offset+1]<<8) |(BUFFER[offset+2]<<16) |(BUFFER[offset+3]<<24);
return tmp;
}
/*****************************************************************************************
* 名称:IsFatherDir
* 功能:查询是否是上层目录
* 输入:INT8U *strName
* 返回:1: 查询成功
0: 查询失败
*****************************************************************************************/
INT8U IsFatherDir(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(hzk12[3][i]!= strName[i]) break;
}
if(i==3)
return 1; // 是上层目录
return 0;
}
/*****************************************************************************************
* 名称:IsCurDir
* 功能:查询是否是当前目录
* 输入:INT8U *strName
* 返回:1: 查询成功
0: 查询失败
*****************************************************************************************/
INT8U IsCurDir(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(hzk12[2][i]!= strName[i]) break;
}
if(i==3) return 1; // 是当前目录
return 0;
}
/*****************************************************************************************
* 名称:IsMusicFile
* 功能:查询是否是音乐文件
* 输入:INT8U *strName
* 返回:1: 是 MP3 文件
2: 是 WMA 文件
0: 没有可用的音乐文件
*****************************************************************************************/
INT8U IsMusicFile(INT8U *strName)
{
INT8U i;
for(i=0; i<3; i++)
{
if(filetype[MP3_TYPE][i]!= strName[i]) break;
}
if(i == 3) return 1; // 是MP3文件
for(i=0; i<3; i++)
{
if(filetype[WMA_TYPE][i]!= strName[i]) break;
}
if(i == 3) return 2; // 是WMA文件
/*
for(i=0;i<3;i++)
{
if(filetype[MID_TYPE][i]!=strName[i]) break;
}
if(i == 3) return 3; // 是MIDI文件
*/
return 0;
}
/*****************************************************************************************
* 名称:GetUpFileSector
* 功能:查询目录项,向上取得音乐文件目录
* 输入:
*
* 返回:无
*****************************************************************************************/
void GetUpFileClust(void)
{
uint8 i;
uint32 tem;
if(Index<2)
{
Index=0;
GetFileClust();
}
else
{
do{
SD_ReadBlock(FirstDataSector+(Index-2)/(BPB_BytesPerSec/32),BUFFER); // 重新读取目录表
tem=((Index-2)*0x20)%BPB_BytesPerSec;
if((BUFFER[tem+11] & ATTR_LONG_FILENAME) != ATTR_LONG_FILENAME) // 是否是长文件名?
{
if((BUFFER[tem] != 0xe5) && (BUFFER[tem] != 0x05))
{
if((BUFFER[tem+11]&ATTR_DIRECTORY) != ATTR_DIRECTORY) // is it a directory ?
{
for(i=0;i<8;i++)
{
deName[i]=BUFFER[tem+i];
}
for(i=0;i<3;i++)
{
deExtension[i]=BUFFER[tem+8+i];
}
if(IsMusicFile(&deExtension[0]))
{
Clust=(BUFFER[tem+20]<<16) | (BUFFER[tem+21]<<24) | (BUFFER[tem+26]) | (BUFFER[tem+27]<<8);
FileSize=(BUFFER[tem+28]) | (BUFFER[tem+29]<<8);
Index--;
break;
}
}
}
}
Index--;
if(Index == 0) // 等所有文件都已经查询结束
{
Index=0;
GetFileClust();
break;
}
}
while(1);
}
}
/*****************************************************************************************
* 名称:fatNextCluster
* 功能:在FAT表中查询下一个簇号
* 输入:INT32U cluster : 当前的簇号
* 返回:INT32U nextCluster : 下一个簇号
*****************************************************************************************/
INT32U fatNextCluster(INT32U cluster)
{
INT32U nextCluster=0;
INT32U fatOffset=0;
INT32U sector=0;
INT16U offset=0;
if(Partition_PartType == PART_TYPE_FAT32) // 一个表项为 4bytes(32 bits)
{
fatOffset = cluster << 2;
sector = FAT1Sec + (fatOffset>>9); // 计算FAT扇区号
offset = fatOffset % BPB_BytesPerSec; // 计算FAT扇区号中表项的偏移地址
nextCluster = ReadBlockforCluster(sector,offset); // 读取下一个簇号
}
else if(Partition_PartType == PART_TYPE_FAT16) // 一个表项为 2bytes(16 bits)
{
fatOffset = cluster << 1; // 计算FAT扇区号
//sector = FirstFATSector + (fatOffset / BPB_BytesPerSec);
offset = fatOffset % BPB_BytesPerSec; // 计算FAT扇区号中表项的偏移地址
nextCluster = ReadBlockforCluster(sector,offset);
}
if (nextCluster >= (CLUST_EOFS & FAT_MASK)) // 是否文件的结束簇
{
nextCluster = CLUST_EOFE;
}
return nextCluster;
}
/*****************************************************************************************
* 名称:GetFileSector
* 功能:查询目录项,取得音乐文件目录
* 输入:
*
* 返回:无
*****************************************************************************************/
void GetFileClust(void)
{
INT8U i;
INT32U tem;
//INT8U BUFFER[512];
do{
SD_ReadBlock(FirstDataSector+Index/(BPB_BytesPerSec/32),BUFFER); // 重新读取目录表
tem=(Index*0x20)%BPB_BytesPerSec;
if((BUFFER[tem+11] & ATTR_LONG_FILENAME) != ATTR_LONG_FILENAME); // 是否是长文件名
{
if((BUFFER[tem] != 0xe5) && (BUFFER[tem] != 0x05))
{
if((BUFFER[tem+11]&ATTR_DIRECTORY) != ATTR_DIRECTORY) // is it a directory ?
{
for(i=0;i<8;i++)
{
deName[i]=BUFFER[tem+i];
}
for(i=0;i<3;i++)
{
deExtension[i]=BUFFER[tem+8+i];
}
if(IsMusicFile(&deExtension[0]))
{
Clust=(BUFFER[tem+20]<<16) | (BUFFER[tem+21]<<24) | (BUFFER[tem+26]) | (BUFFER[tem+27]<<8);
FileSize=(BUFFER[tem+28]) | (BUFFER[tem+29]<<8);
Index++;
break;
}
}
}
}
Index++;
if(BUFFER[tem] == 0) // 等所有文件都已经查询完了
{
Index=0;
}
}
while(1);
}
/*****************************************************************************************
* 名称:GetFileData
* 功能:得到播放数据
* 输入:
*
* 返回:无
*****************************************************************************************/
void GetFileData(uint32 cluster,uint8 index)
{
SD_ReadBlock(FirstDataSector+(cluster-2)*8+index,MP3_BUFFER);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -