📄 sdfilelib.c
字号:
#include <c8051f020.h>
#include <math.h>
#include <stdlib.h>//调用 atoi函数
//--------------------------------
struct FAT32_FAT_Item
{
unsigned char Item[4];
};
//-----------------------------------
struct FAT32_FAT
{
struct FAT32_FAT_Item Items[128];
};
/*
FAT32中对BPB的定义如下 一共占用90个字节
*/
struct FAT32_BPB
{
unsigned char BS_jmpBoot[3]; //跳转指令 offset: 0
unsigned char BS_OEMName[8]; // offset: 3
unsigned char BPB_BytesPerSec[2];//每扇区字节数 offset:11
unsigned char BPB_SecPerClus[1]; //每簇扇区数 offset:13
unsigned char BPB_RsvdSecCnt[2]; //保留扇区数目 offset:14
unsigned char BPB_NumFATs[1]; //此卷中FAT表数 offset:16
unsigned char BPB_RootEntCnt[2]; //FAT32为0 offset:17
unsigned char BPB_TotSec16[2]; //FAT32为0 offset:19
unsigned char BPB_Media[1]; //存储介质 offset:21
unsigned char BPB_FATSz16[2]; //FAT32为0 offset:22
unsigned char BPB_SecPerTrk[2]; //磁道扇区数 offset:24
unsigned char BPB_NumHeads[2]; //磁头数 offset:26
unsigned char BPB_HiddSec[4]; //FAT区前隐扇区数 offset:28
unsigned char BPB_TotSec32[4]; //该卷总扇区数 offset:32
unsigned char BPB_FATSz32[4]; //一个FAT表扇区数 offset:36
unsigned char BPB_ExtFlags[2]; //FAT32特有 offset:40
unsigned char BPB_FSVer[2]; //FAT32特有 offset:42
unsigned char BPB_RootClus[4]; //根目录簇号 offset:44
unsigned char FSInfo[2]; //保留扇区FSINFO扇区数offset:48
unsigned char BPB_BkBootSec[2]; //通常为6 offset:50
unsigned char BPB_Reserved[12]; //扩展用 offset:52
unsigned char BS_DrvNum[1]; // offset:64
unsigned char BS_Reserved1[1]; // offset:65
unsigned char BS_BootSig[1]; // offset:66
unsigned char BS_VolID[4]; // offset:67
unsigned char BS_FilSysType[11]; // offset:71
unsigned char BS_FilSysType1[8]; //"FAT32 " offset:82
};
//-----------------------------------------
xdata struct file_content_info
{
unsigned long file_size; //文件的大小
unsigned long frist_clust; //文件的起始簇
unsigned long current_clust; //第几族
unsigned char current_sector; //一族中的第几扇
unsigned int current_byte; //一扇中的第几字节
unsigned long file_name_sector; //文件名所在的扇区
unsigned int file_name_byte; //文件名在的字节位置
}file[5];
/*
FAT32初始化时初始参数装入如下结构体中
*/
struct FAT32_Init_Arg
{
unsigned long Total_Sectors; //磁盘的总容量
unsigned long FirstDirClust; //根目录的开始簇
unsigned long FirstDataSector; //文件数据开始扇区号
unsigned int BytesPerSector; //每个扇区的字节数
unsigned int FATsectors; //FAT表所占扇区数
unsigned int SectorsPerClust; //每簇的扇区数
unsigned long FirstFATSector; //第一个FAT表所在扇区
unsigned long FirstDirSector; //第一个目录所在扇区
// unsigned long RootDirSectors; //根目录所占扇区数
// unsigned long RootDirCount; //根目录下的目录与文件数
};
//---------------------------------------------------------------
xdata unsigned char FAT32_Buffer[512] ; //扇区数据读写缓冲区
//xdata unsigned char FAT_Buffer[512]; //操作FAT时数据读缓冲区
xdata struct FAT32_Init_Arg Init_Arg1; //初始化参数结构体实体
//struct FileInfoStruct FileInfo; //文件信息结构体实体
unsigned long xdata se=0; //要操作的扇区数
//unsigned long xdata current_clust;
//unsigned int xdata clust_num;
unsigned char xdata file_num=0,file_byte=0xff; //打开文件的数目
//unsigned char xdata hzk[1024]; //存放液晶字库
//unsigned char xdata ch1[90]; //一条记录86个字节和串口中断条码数据
//unsigned char xdata count=0,count_flag,connect_data[5];
#define SYSCLK 24000000
sbit CS=P3^7;
unsigned char data cmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};
//-----------函数申明--------------------------------------------
void MCU_init();
//SD卡的SPI初始化
void SD_SPI_init();
//小端转大端
unsigned long Little_To_Big(unsigned char *dat,unsigned char len);
//打开或创建文件
unsigned char fopen(char file_name[8]);
//关闭文件代号
void fclose(unsigned pfile);
//文件定位
void fseek(unsigned char pfile,unsigned long len);
//读区文件内容
void fread(unsigned char pfile,unsigned char *store,unsigned int read_num);
//写入文件内容,只能写在结尾
void fwrite(unsigned char pfile,unsigned char *store,unsigned int write_num);
//写入文件内容,删除原来文件内容
void fwriteall(unsigned char pfile,unsigned char *store,unsigned int write_num);
//汉字库与液晶汉字库的转换
void HZKLCD(unsigned char *ch,unsigned char *CH);
//字符串转数字
unsigned long find1(unsigned char pfile,unsigned char pfile1,unsigned char len1,unsigned char *array,unsigned char len,unsigned char len2);
unsigned char SD_SPI_init_1();
void SD_CMD(unsigned char *cmd);
void FAT32_Init();
unsigned long Little_To_Big(unsigned char *dat,unsigned char len);
void Write_SD_Sector(unsigned long sector);
void Read_SD_Sector(unsigned long sectors);
#define ulong unsigned long
#define uchar unsigned char
#define uint unsigned int
//-------------函数声明-----------------------------------------
uchar file_name_compare(uchar *file_name,uchar *Name);
uchar fopen(char file_name[8]);
ulong FAT32_GetNextCluster(ulong LastCluster);
unsigned long Add_Newclust(unsigned char pfile);
unsigned long find_emptyclust();
void write_size(unsigned char pfile,unsigned int write_num);
void MCU_init()
{
WDTCN = 0xde;
WDTCN = 0xad;
XBR0=0x02; //选择.P0.0 - P0.3分别为SPI接口的SCK、MISO、MOSI和NSS
//XBR0=0x06; //P0.0和P0.1为串口,P0.2、P0.3、P0.4和P1.0为SPI接口
XBR1=0x00;
XBR2=0x44; //允许功能选择开关有效,开启UART1串口
P0MDOUT=0x1d;//0x34; //选择SCK、MOSI、NSS为推拉式输出,MISO为开漏式,作为数据输入口
P1MDOUT=0x40; //选择P1.6 LED为推拉式输出
P3=0x82; //READY 输入口
P74OUT=0x00; //P4 - P7 漏极开路
P4=0x0ff; //P4 输入
SPI0CFG=0xc7; //选择在时钟的第2个边沿采样,SCK的空闲状态为高电平,移位位数为8
SPI0CN=0x03; //允许主方式,允许SPI
SPI0CKR=SYSCLK/2/12000000-1;//SPI的波特率为12Mb/s
}
//---------------------------------------------------
//Name :SD_SPI_init_1
//Fun :SD 卡进入 SPI 模式
//In :none
//Out :0 - successful; 1 - failed
//---------------------------------------------------
unsigned char SD_SPI_init_1()
{
unsigned char j,retry;
for(j=0;j<10;j++) //Send 80 clocks
{
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
}
retry = 0;
do
{
SD_CMD(cmd); //Send CMD0
if(retry++>20) /* 超时返回 */
return 1;
}
while(SPI0DAT != 1); //Response 01h,Successful!
cmd[0]=0x41;
cmd[5]=0xff;
retry = 0;
do
{
SD_CMD(cmd); //Send CMD1
if(retry++>20) /* 超时返回 */
return 1;
}
while(SPI0DAT!=0); //Response 00h,Successful!
CS = 1;
return 0;
}
//---------------------------------------------------
//Name :SD_SPI_init
//Fun :sd卡初始化
//In :none
//Out :none
//---------------------------------------------------
void SD_SPI_init()
{
unsigned char t;
for(t=0;t<50;t++)
{if(SD_SPI_init_1()==0)break;/*file_num=SD_SPI_init_1();*/}
//ERROR();
}
//--------------------------------------------
//Name :SD_CMD
//Fun :Send SD Card Command
//In :unsigned char *cmd
//Out :none
//---------------------------------------------------
void SD_CMD(unsigned char *cmd)
{
unsigned char i;
CS = 1;
SPI0DAT = 0xff; //发送8个时钟信号
while(!SPIF);
SPIF = 0;
CS = 0;
for(i=0;i<6;i++)
{
SPI0DAT = *(cmd++);
while(!SPIF);
SPIF = 0;
}
i = 0;
do
{
SPI0DAT = 0xff; /* Wait for Response */
while(!SPIF);
SPIF = 0;
if(i++>20) /* 超时返回 */
return;
}
while(SPI0DAT == 0xff);
}
//---------------------------------------------------
//函数名:Read_SD_Sector
//功 能:读 一个扇区寄存器
//参 数:sector
//返回值:
//---------------------------------------------------
void Read_SD_Sector(unsigned long sectors)
{
unsigned int n = 0;
unsigned long sector;
sector=sectors;
// unsigned char response;
//地址变换 由逻辑块地址转为字节地址
sector = sector << 9; // sector = sector * 512
cmd[0] = 0x51;
cmd[1] = ((sector & 0xFF000000) >>24 );
cmd[2] = ((sector & 0x00FF0000) >>16 );
cmd[3] = ((sector & 0x0000FF00) >>8 );
do
{
SD_CMD(cmd);//发送CMD16
n++;
if(n == 100);
// READ_BLOCK_ERROR=0x55;
// return(READ_BLOCK_ERROR);//CMD16 错误!
}
while(SPI0DAT!=0); //回应00h,停止写入
n = 0;
do
{
SPI0DAT = 0xff; //* 等待回复 *
while(!SPIF){}
SPIF = 0;
if(n++>200);
// READ_BLOCK_START_ERROR=0x55; //* 超时返回 *
// return(READ_BLOCK_START_ERROR);
}
while(SPI0DAT != 0xfe);
for (n=0;n<512;n++)
{
SPI0DAT = 0xff;
while(!SPIF){}
SPIF = 0;
FAT32_Buffer[n] = SPI0DAT;
}
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
CS = 1;
}
//---------------------------------------------------
//Name :Write_SD_Sector
//Fun :Write one Sector on SD Card
//In :unsigned long sector
//Out :none
//---------------------------------------------------
void Write_SD_Sector(unsigned long sector)
{
unsigned int n = 0;
//地址变换 由逻辑块地址转为字节地址
sector = sector << 9; //sector = sector * 512
cmd[0] = 0x58;
cmd[1] = ((sector & 0xFF000000) >>24 );
cmd[2] = ((sector & 0x00FF0000) >>16 );
cmd[3] = ((sector & 0x0000FF00) >>8 );
do
{SD_CMD(cmd);} //Send CMD24
while(SPI0DAT!=0); //Response 00h,Successful!
SPI0DAT = 0xff;
while(!SPIF);
SPIF = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -