基于51单片机FAT32文件系统程序
petit_fatfs文件系统移植
FatFS文件系统的优点我就不赘述了,我需要的功能不多,所以我移植是FatFS的精简版petit fatfs,现将我的一直步骤写下来供大家参考。
工程暂不能分享,见谅。
1、移植的文件系统为petit fatfs R0.02。
下载地址:/fsw/ff/pff2.zip2、本人选用的单片机是STC12C5A56S2(容量够大)。
3、选用的SD卡为macro SD,容量512M,格式化为fat32文件系统,分配大小为512字节。
Petit fatfs文件系统的修改步骤及说明如下:一、integer.h,pff.c,diskio.h这三个文件不需要修改。
二、pff.h的修改:1、使能FAT32文件系统的支持#define_FS_FAT3212、选择简体中文编码格式#define_CODE_PAGE936三、diskio.c的修改:1、添加必要头文件:reg51.h,sd.h,spi.h。
2、填写设备初始化函数DSTATUS disk_initialize(void)这个函数我是参考别人写的:DSTATUS disk_initialize(void){DSTATUS stat;//Put your code herestat=STA_NOINIT;if(!SD_Init()){stat&=~STA_NOINIT;}return stat;}3、填写读函数:DRESULT disk_readp(BYTE*dest,DWORD sector,WORD sofs,WORD count)这个函数写法各异,就不具体说了,BYTE*dest这个就是指你要讲读出来的数据存在哪里的指针变量。
DWORD sector是要读扇区的地址,看一下SD卡的读写命令你就知道了。
WORD sofs是偏移量,简单就是说,要读的数据相对于扇区开始的字节数,这个读出来,直接忽略掉。
WORD count是要读的字节个数,读完偏移量的字节数,就是要读这个,将读出来的数据存在干才说的那个BYTE*dest。
FAT32文件系统的存储机制及其在单片机上的实现(于振南)
_No; //装入第一个 FAT 表扇区号到 FirstFATSector 中
arg->RootDirCount
=lb2bb((bpb->BPB_RootEntCnt) ,2);
//装入根目录项数到 RootDirCount 中
arg->RootDirSectors
=(arg->RootDirCount)*32>>9;
这就是大端模式与小端模式在作怪。上面我们合成 int 型变量的方法(00 为 高字节,02 为低字节)为小端模式。而如果我们改用大端模式来进行合成的话,
结果就会不同:将 02 作高字节,而把 00 作低字节,变量值就成了 0x0200(十进 制的 512),这样就和实际数据吻合了。可见 FAT32 中字节的排布是采用小端模式 的。在我们程序中需要将它转为大端模式的表达方式。在笔者的程序有这样一个
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: 0
unsigned char BS_OEMName[8]; //
offset: 3
unsigned char BPB_BytesPerSec[2];//每扇区字节数
offset:11
unsigned char BPB_SecPerClus[1]; //每簇扇区数
关于单片机读写U盘F16和F32文件系统
摘要本文以51单片机为例介绍如何扩展USB接口进行对U盘的读写,并详细介绍FAT16、F AT32文件系统的细节以及如何编码实现单片机对文件系统的常用操作,顺带提到一点关于U盘兼容性问题的解决经验。
在这里单片机是host,U盘是slave。
在嵌入式系统中实现host很有意义,可以直接扩展出大容量的外存储器。
只要对单片机有一点点了解的人应该可以很顺利地阅读下去,如有简单的C语言编程基础更佳。
本文是科普性质,并不面面俱到,有一点应用笔记的味道。
章节间关联性较强,最好按顺序来阅读。
本文资料完全来自网络,再加入了笔者自己的理解和实践结果。
本文末尾列出了所有的参考资料。
如果觉得有知识产权问题请在21ic社区发信给fjh。
仓促成文,错误绝对存在,但希望不影响阅读。
关键词USB枚举过程;读写U盘;SL811;F AT16;F AT32Abstract[Click here and input abstract in English]Keywords[Click here and input keywords in English]符号说明(略)目录第一章硬件设计1.1 硬件概述先详细介绍基于Cypress公司的SL811芯片的扩展方案,基于国内南京沁恒电子的CH375芯片的方案最后介绍。
本文尽量介绍关于USB、U盘和文件系统等平台无关的内容,SL811硬件平台方面的内容不可避免要涉及到一点,但尽量控制到最少。
硬件很简单,详见protel文件(省略了无关的部分,比较粗糙,凑合看…)。
主要是扩展一片32K的外部RAM 62256作为数据缓冲,同时分配好SL811的地址。
通过51单片机的A15地址线分别连接到外部RAM 62256和SL811的片选CS端,来区分两者的地址,可见RAM占据低32K地址空间,而SL811依“写地址”和“读写数据地址”分别占据8000H和8001H两个字节的地址空间。
第二章U盘的逻辑结构2.1 U盘的逻辑结构U盘可以看成是以扇区(1扇区=512Bytes)为单位线性排列的实体,即0号扇区,1号扇区,2号扇区,……这样按顺序地排列下去。
FAT32文件系统的存储机制及其在单片机上的实现
FAT32文件系统的存储机制及其在单片机上的实现FAT32文件系统的存储机制及其在单片机上的实现based on a SD cardFAT32文件系统您一定不会陌生,最多看到它是在windows操作系统里,但在一些嵌入式产品(如手机、MP3、MP4等)中,也能看到它的身影。
从某种意义上来讲,FAT32文件系统是非常成功的,使我们可以脱离底层储存设备驱动,更为方便高效地组织数据。
给单片机系统中的大容量存储器(如SD卡、CF卡、硬盘等)配以FAT32文件系统,将是非常有意义的(如创建的数据文件可以在windows等操作系统中直接读取等)。
FAT32本身是比较复杂的,对其进行讲解的最好方法就是实际演练。
笔者手里持有一张刚以FAT32格式化的SD卡,我们就围绕它来讲解FAT32的实现机理。
FAT32分为几个区域,这里将用实例的方法对它们的结构与在文件存储中的功能进行详细的剖析。
实例说明此实例首先在一张空的SD卡(已被格式化为FAT32格式)上创建一个文本文件,并在其中输入20个字符。
再将它插入到单片机系统中,实现对这个文件的读取,将文件内容输出在调试终端上。
实现过程格式化与创建文件Windows上的磁盘格式化与文件创建就不用多说了。
如下图:2)DBR(DOS BOOT RECORD操作系统引导记录区)DBR是我们进军FAT32的首道防线。
其实DBR中的BPB部分才是这一区域的核心部分(第12~90字节为BPB),只有深入详实的理解了BPB的意义,才能够更好的实现和操控FAT32。
关于DBR在FAT32中的地位就不多说了,以下面实际的DBR内图所示:上面的数据看起来杂乱不堪,无从下手,其实对我们有用的数据只不过90个字节(如图中彩色线标记的字节)。
仅仅是这90个字节就可以告诉我们关于磁盘的很多信息,比如每扇区字节数、每簇扇区数、磁道扇区数等等。
对于这些信息的读取,只要遵循DBR中的字段定义即可。
(比如图中紫色字段的两个字节表示这张磁盘的每一个扇区有512个字节,具体的计算方法见下文)DBR的实现代码:struct FAT32_DBR{unsigned char BS_jmpBoot[3]; //跳转指令offset: 0 unsignedchar 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:40unsigned char BPB_FSVer[2]; //FAT32特有offset:42unsigned char BPB_RootClus[4]; //根目录簇号offset:44unsigned char FSInfo[2]; //保留扇区FSINFO扇区数offset:48 unsigned char BPB_BkBootSec[2]; //通常为6 offset:50unsigned char BPB_Reserved[12]; //扩展用offset:52unsigned char BS_DrvNum[1]; // offset:64unsigned char BS_Reserved1[1]; // offset:65unsigned char BS_BootSig[1]; // offset:66unsigned char BS_VolID[4]; // offset:67unsigned char BS_FilSysType[11]; // offset:71unsigned char BS_FilSysType1[8]; //"FAT32 " offset:82};在程序中我们采用以上的结构体指针对扇区数据指针进行转化,就可以直接读取数据中的某一字段,如要读取BPB_BytesPerSec,可以这样来作:((struct FAT32_DBR *)pSector)-> BPB_BytesPerSec用如上语句就可以得到这一字段的首地址。
51单片机与SD卡接口设计
近年来,SD存储卡在嵌入式产品中的应用越来越广泛,但SD卡接口一般仅集成在32位ARM处理器中,一般51单片机则由于资源限制没有该接口。
因此,如何解决51单片机应用系统存取SD卡大容量数据就显得很有实际意义。
本课题使用W86L388D作为单片机与SD卡的接口芯片,采用4线并行方式取代SPI串行方式读写数据,使SD卡的访问速度得到明显提高,并且设计了FAT32文件系统,提高了SD卡的存储效率和兼容性,因此特别适用于需要大容量存储功能的嵌入式仪表和设备中。
1硬件设计1.1SD卡接口芯片简介单片机与SD卡接口使用了华邦公司的W86L388D芯片。
芯片的主要特性包括8/16位CPU总线接口、最高时钟率25MHz、支持SD卡1线或4线数据传输、支持DMA和中断传输模式。
由于该芯片内部集成了SD卡操作的全部时序,因此用户只需通过初始化参数配置,然后给相应的寄存器写入控制命令,就可方便的控制SD卡的读写操作。
每次命令操作结果的状态,可以通过查询内部的状态寄存器获知,以决定下一步的操作。
W86L388D工作电压为3.3V,且采用48脚LQPF小型封装,所以特别适用于要求体积小、功耗低的嵌入式应用场合。
1.2接口电路设计电路中的W86L388D使用8位数据总线与单片机连接,它与处理器的接口采用异步模式(XTYP2引脚接地),芯片还支持另一种同步模式(XTYP2引脚接高电平)。
在8位总线下,D15用作A0,与A1~A3共同作用选择内部寄存器。
SD1~SD6引脚与SD卡的4根数据线,1根命令线和1根时钟线相连。
W86L388D的5个GPIO引脚,一个用于SD卡是否插入的检测,一个用于控制MOS管的导通从而控制SD卡电源的接通与断开,两个分别控制两个发光二极管,可用来指示卡是否插入和对卡的写保护指示,一个检测写保护。
32KBSRAM用于文件缓冲区,MAX3232是RS-232接口,用于和HOST机通信。
2软件设计软件设计主要包括三部分:对SD卡进行底层多块读写的驱动程序设计,中间层FAT32文件系统设计,以及跟上位机(HOST)依据传输协议的通信程序设计。
基于51单片机的音乐播放器的设计
基于51单片机的音乐播放器的设计学院:电子与电气工程学院专业:测控技术与仪器***名:**学号: ***********湖南工业大学Hunan university of Technology基于51单片机的音乐播放器的设计[摘要]本课题完成了基于51单片机的音乐播放器的软件设计。
论文主要介绍了对U盘所存储的MP3、WMA或MIDI格式的文件识别、提取以及音频解码程序实现的方法,通过与硬件调试表明所设计的音乐播放器可以通过按键选择歌曲以及控制音量,同时还可以通过显示屏来显示所播放的歌曲名。
声音的播放可以通过扬声器或耳机进行,基本实现了音乐播放器的功能。
[关键词]单片机;音乐播放器;U盘文件读取;音频解码目录1 引言 (1)1.1 设计意义 (1)1.2 理论分析与方案论证 (1)1.2.1 理论分析 (1)2 系统硬件原理及概述 (2)2.1 STC12C5A60S2处理器介绍 (2)2.2 系统硬件电路综述 (2)2.2.1 硬件系统总体设计方案 (2)2.2.2 USB总线的通用接口芯片CH375电路 (3)2.2.3 LCD12864显示电路 (3)2.2.4 按键控制电路 (3)2.2.5 音频解码芯片VS1003电路 (4)3 系统软件设计 (4)3.1 软件开发平台 (4)3.2 系统的软件设计 (4)3.2.1 软件总体分析................................ 错误!未定义书签。
3.2.2 CH375软件系统设计 (7)3.2.3 CH375模块的U盘数据读取程序设计 (8)3.2.4 VS1003模块的MP3文件播放程序设计 (9)3.3 系统流程图 (11)参考文献 (11)1 引言1.1设计意义基于单片机的音乐播放器可应用于MP3,MP4,扩音器等很多方面,并可作为很多系统的辅助功能,传统的音乐播放器是利用定时器可以产生各种固定频率的方波信号,可以产生包括“Do”、“Re”、“Me”等音阶在内的各种频率声音。
FAT32文件系统实现单片机MP3播放器 源代码
/* FAT32初始化时初始参数装入如下结构体中 */ struct FAT32_Init_Arg { unsigned char BPB_Sector_No; //BPB所在扇区号 unsigned long Total_Size; //磁盘的总容量 unsigned long FirstDirClust; //根目录的开始簇 unsigned long FirstDataSector; //文件数据开始扇区号 unsigned int BytesPerSector; //每个扇区的字节数 unsigned int FATsectors; //FAT表所占扇区数 unsigned int SectorsPerClust; //每簇的扇区数
return temp; } unsigned long FAT32_FindBPB() //寻找BPB所在的扇区号 { MMC_Init(); //SD卡初始化 FAT32_ReadSector(0,FAT32_Buffer); if(FAT32_Buffer[0]!=0xeb) return lb2bb(((((struct PartSector *)(FAT32_Buffer))->Part[0]).StartLBA),4); else return 0; } unsigned long FAT32_Get_Total_Size() //存储器的总容量,单位为M { MMC_Init(); //SD卡初始化 FAT32_ReadSector(Init_Arg.BPB_Sector_No,FAT32_Buffer); return ((float)(lb2bb((((struct FAT32_BPB *)(FAT32_Buffer))>BPB_TotSec32),4)))*0.0004883; } void FAT32_Init(struct FAT32_Init_Arg *arg) { struct FAT32_BPB *bpb; bpb=(struct FAT32_BPB *)(FAT32_Buffer); //将数据缓冲区指针转 为struct FAT32_BPB 型指针 arg->BPB_Sector_No =FAT32_FindBPB(); //FAT32_FindBPB()可以返回BPB所在的扇区号 arg->Total_Size =FAT32_Get_Total_Size(); //FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆 arg->FATsectors =lb2bb((bpb->BPB_FATSz32) ,4); //装入FAT表 占用的扇区数到FATsectors中 arg->FirstDirClust =lb2bb((bpb->BPB_RootClus) ,4); //装入根目录簇 号到FirstDirClust中 arg->BytesPerSector =lb2bb((bpb->BPB_BytesPerSec),2); //装入每扇区 字节数到BytesPerSector中
FAT32文件系统 C语言源代码
//这是FAT32文件系统源代码#ifndef __FAT_H__#define __FAT_H__#define CHAR char#define BYTE unsigned char#define WORD unsigned int#define DWORD unsigned long#define FIX_DIRECTORY 0 /* 1 means use fix directory, 0 for any directory */#if FIX_DIRECTORY==0#define RECORD_ADDR_START 0 /* eeprom start address */#define RECORD_ADDR_END 512 /* eeprom end address *///#include<avr/eeprom.h>//#include<avr/pgmspace.h>//#include<stdio.h>#endif//#include "UART.H"#include <stdlib.h>//#include "gui.h"//声明外部器件读写函数//external hardware operating functionextern unsigned char MMC_SD_ReadSingleBlock(unsigned long sector, unsigned char* buffer); extern unsigned char MMC_SD_WriteSingleBlock(unsigned long sector, unsigned char* buffer); extern unsigned long MMC_SD_ReadCapacity(void);#define MSDOSFSROOT 0 // cluster 0 means the root dir#define CLUST_FREE 0 // cluster 0 also means a free cluster#define MSDOSFSFREE CLUST_FREE#define CLUST_FIRST 2 // first legal cluster number#define CLUST_RSRVD 0xfff6 // reserved cluster range#define CLUST_BAD 0xfff7 // a cluster with a defect#define CLUST_EOFS 0xfff8 // start of eof cluster range#define CLUST_EOFE 0xffff // end of eof cluster range#if 0struct partsector{/*char*/unsigned char psPartCode[/*512-64-2*/446]; // pad so struct is 512bunsigned char psPart[64]; // four partition records (64 bytes)unsigned char psBootSectSig0; // two signature bytes (2 bytes)unsigned char psBootSectSig1;#define BOOTSIG0 0x55#define BOOTSIG1 0xaa};struct extboot {CHAR exDriveNumber; // drive number (0x80)//0x00 for floopy disk 0x80 for hard diskCHAR exReserved1; // reserved should always set 0CHAR exBootSignature; // ext. boot signature (0x29)#define EXBOOTSIG 0x29CHAR exV olumeID[4]; // volume ID numberCHAR exV olumeLabel[11]; // volume label "NO NAME"CHAR exFileSysType[8]; // fs type (FAT12 or FAT)};struct bootsector50 {BYTE bsJump[3]; // jump inst E9xxxx or EBxx90CHAR bsOemName[8]; // OEM name and versionCHAR bsBPB[25]; // BIOS parameter blockCHAR bsExt[26]; // Bootsector ExtensionCHAR bsBootCode[448]; // pad so structure is 512bBYTE bsBootSectSig0; // boot sector signature byte 0x55BYTE bsBootSectSig1; // boot sector signature byte 0xAA#define BOOTSIG0 0x55#define BOOTSIG1 0xaa};struct bpb50 {WORD bpbBytesPerSec; // bytes per sector //512 1024 2048 or 4096BYTE bpbSecPerClust; // sectors per cluster // power of 2WORD bpbResSectors; // number of reserved sectors //1 is recommendBYTE bpbFATs; // number of FATs // 2 is recommendWORD bpbRootDirEnts; // number of root directory entriesWORD bpbSectors; // total number of sectorsBYTE bpbMedia; // media descriptor //0xf8 match the fat[0]WORD bpbFATsecs; // number of sectors per FATWORD bpbSecPerTrack; // sectors per trackWORD bpbHeads; // number of headsDWORD bpbHiddenSecs; // # of hidden sectorsDWORD bpbHugeSectors; // # of sectors if bpbSectors == 0};//MDR-DPT(Disk Partition Table)// length 16 bytes//struct partrecord{struct _DPT{bool bActive_Partition; /*=1:激活*/unsigned char cStart_Head; // starting head for partitionunsigned char cStart_Sector; // starting cylinder and sectorunsigned int iStart_Cylinder; //unsigned char ; // partition type (see above)unsigned char cFat_Index; // ending head for this partitionunsigned int iEnd_Sector; // ending cylinder and sectorunsigned long iEnd_Cylinder; // first LBA sector for this partition unsigned long lSector_Len; // size of this partition (bytes or sectors ?) };#endif//#define BOOTSIG0 0x55//#define BOOTSIG1 0xaa//#define BOOTSIG2 0x00//#define BOOTSIG3 0x00//512 bytes for DBR infostruct DBR{unsigned char cJump[3]; // jump inst E9xxxx or EBxx90unsigned char cOem_Name[8]; // OEM name and versionunsigned char cBpb[53]; // BIOS parameter blockunsigned char cExt_Bpb[26]; // Bootsector Extensionunsigned char cBoot_Code[420]; // pad so structure is 512bunsigned char cEnd_Flag[2]; // boot sector signature byte 0x00};#define FATNUM 0xf // mask for numbering active FAT#define FATMIRROR 0x80 // FAT is mirrored (like it always was)#define FSVERS 0 // currently only 0 is understood//BPB(BIOS Parameter Block)//53bytesstruct BPB {//bpb infounsigned int iBytes_Per_Sector; // bytes per sectorunsigned char cSectors_Per_Clust; // sectors per clusterunsigned int iRsv_Sectors; // number of reserved sectorsunsigned char cFats; // number of FATsunsigned int iRoot_Dir_Entries; // number of root directory entries(fat12/16 only;fat32=0)unsigned int iSmall_Sectors; // total number of sectorsunsigned char cMedia; // media descriptorunsigned int iSectors_Per_Fat16; // number of sectors per FATunsigned int iSectors_Per_Track; // sectors per trackunsigned int iHeads; // number of headsunsigned long lHidden_Sectors; // # of hidden sectorsunsigned long lBig_Sectors; // like bpbFATsecs for FAT32//FAT32特有(地址采用插入方式,FAT16后面的信息往后排)unsigned long lSectors_Per_Fat32;unsigned int iExt_Flag;unsigned int iFile_System_Ver; // filesystem versionunsigned long lRoot_Clust; // start cluster for root directoryunsigned int iFile_System_Info; // filesystem info structure sectorunsigned int iBackup_Boot_Sector; // backup boot sector// unsigned char cRsv_Fat32[12]; // There is a 12 byte filler here, but we ignore it//boot sector infounsigned char cDrv_Num; //(0=软;0x80=硬)// unsigned char cRsv_Fat16; //reservedunsigned char cBoot_Sig; //ext boot sig(0x29)unsigned long lVol_Id; //vol idunsigned char cV ol_Lab[11]; //vol labunsigned char cFile_System_Type[8]; //char for file system};#define SLOT_EMPTY 0x00 // slot has never been used#define SLOT_E5 0x05 // the real value is 0xE5#define SLOT_DELETED 0xE5 // file in this slot deleted#define SLOT_DIR 0x2E // a directorymmm#define ATTR_NORMAL 0x00 // normal file#define ATTR_READONL Y 0x01 // file is readonly#define ATTR_HIDDEN 0x02 // file is hidden#define ATTR_SYSTEM 0x04 // file is a system file#define ATTR_VOLUME 0x08 // entry is a volume label#define ATTR_LONG_FILENAME 0x0F // this is a long filename entry#define ATTR_DIRECTORY 0x10 // entry is a directory name#define ATTR_ARCHIVE 0x20 // file is new or modified#define LCASE_BASE 0x08 // filename base in lower case#define LCASE_EXT 0x10 // filename extension in lower case// Structure of a dos directory entry.//FDTstruct direntry{BYTE deName[8]; // filename, blank filledBYTE deExtension[3]; // extension, blank filledBYTE deAttributes; // file attributesBYTE deLowerCase; // NT VFAT lower case flags (set to zero) BYTE deCHundredth; // hundredth of seconds in CTimeBYTE deCTime[2]; // create timeBYTE deCDate[2]; // create dateBYTE deADate[2]; // access dateunsigned int deHighClust; // high bytes of cluster numberBYTE deMTime[2]; // last update timeBYTE deMDate[2]; // last update dateunsigned int deStartCluster; // starting cluster of fileunsigned long deFileSize; // size of file in bytes};// number of directory entries in one sector#define DIRENTRIES_PER_SECTOR 0x10 //when the bpbBytesPerSec=512// Structure of a Win95 long name directory entrystruct winentry {BYTE weCnt; //#define WIN_LAST 0x40#define WIN_CNT 0x3fBYTE wePart1[10];BYTE weAttributes;#define ATTR_WIN95 0x0fBYTE weReserved1;BYTE weChksum;BYTE wePart2[12];WORD weReserved2;BYTE wePart3[4];};#define WIN_ENTRY_CHARS 13 // Number of chars per winentry// Maximum filename length in Win95// Note: Must be < sizeof(dirent.d_name)#define WIN_MAXLEN 255// This is the format of the contents of the deTime field in the direntry// structure.// We don't use bitfields because we don't know how compilers for// arbitrary machines will lay them out.#define DT_2SECONDS_MASK 0x1F // seconds divided by 2#define DT_2SECONDS_SHIFT 0#define DT_MINUTES_MASK 0x7E0 // minutes#define DT_MINUTES_SHIFT 5#define DT_HOURS_MASK 0xF800 // hours#define DT_HOURS_SHIFT 11// This is the format of the contents of the deDate field in the direntry// structure.#define DD_DAY_MASK 0x1F // day of month#define DD_DAY_SHIFT 0#define DD_MONTH_MASK 0x1E0 // month#define DD_MONTH_SHIFT 5#define DD_YEAR_MASK 0xFE00 // year - 1980#define DD_YEAR_SHIFT 9// Stucturesstruct FileInfoStruct{unsigned long StartCluster; //< file starting cluster for last file accessed unsigned long Size; //< file size for last file accessedunsigned char Attr; //< file attr for last file accessed//unsigned short CreateTime; //< file creation time for last file accessed //unsigned short CreateDate; //< file creation date for last file accessed unsigned long Sector; //<file record placeunsigned int Offset; //<file record offset};extern unsigned char Disp_Bmp(void);extern unsigned char Disp_file_name(void);extern unsigned char FAT_Init();//初始化#if 0extern unsigned long FAT_NextCluster(unsigned long cluster);//查找下一簇号extern unsigned int FAT_FindItem(unsigned long cluster, BYTE *name, struct FileInfoStruct *FileInfo);//查找文件extern unsigned long FAT_OpenDir(BYTE * dir);//打开目录#if FIX_DIRECTORYextern unsigned char Search(BYTE *dir,struct direntry *MusicInfo,WORD *Count,BYTE *type);//查找音乐文件#elseextern BYTE SearchInit(void);extern unsigned char Search(struct direntry *MusicInfo,WORD *Count,BYTE *type);//查找音乐文件#endifextern unsigned char FAT_LoadPartCluster(unsigned long cluster,unsigned part,BYTE * buffer);//加载文件#endif#endif以下是FAT.C源代码/*Fat.c*//*磁盘结构:name size(sector) noteMBR/DPT sector 1 (jmp to DBR by DTP)xxx xDBR sector(BPB) 1 逻辑0扇区//FAT开始rsv sector x (get size by PBP)FAT1 x (get size by PBP)FATX... x (get FATS by PBP)DIR(FDT) 32 file root dir(FAT12/16 only)data all*//*init fat file system1:get MBR or DPT & jmp to DBR by DPTMBR:master boot record(主引导记录)+DPT:Disk Partition Table(磁盘分区表;和MBR同一扇区,跟在它后面)+0x55 0xaa......2.get BPB in DBR(DOS BOOT RECORD):逻辑0扇区,可以由DPT得到物理位置.3.get rsv sectors by BPB4.get fats by BPB5.get fat sectors by BPB6.get root dir sector by BPB(fat12/16 only)*//*每族字节数<=32k*//*根目录:1.根FDT中每32字节一个目录项,可以是文件和目录.2.固定占用32扇区;子目录:1.最前面为父/子目录项("."和"..");2.之后为子目录和文件,32字节1单位;*/#include "FAT.h"#include "tft.h"#include "MMC_SD.h"#include "char.h"unsigned long lFirst_Fat_Sector; // The first FAT sectorunsigned long lFat_Sectors; // The amount sector a FAT occupiedunsigned long lFirst_Dir_Sector; // The first Dir sectorunsigned long lFirst_Dir_Clust; //first directory clusterunsigned long lRoot_Dir_Sectors; // The sector number a Root dir occupiedunsigned long lFirst_Data_Sector; // The first sector number of dataunsigned char cSectors_Per_Clust;BYTE FAT32_Enable;BYTE (* FAT_ReadSector)(DWORD,BYTE *);BYTE (* FAT_WriteSector)(DWORD,BYTE *);//函数指针指向sd卡的读写函数//function pointer to the sd card read & write single block//wirte sector are not use in this playerunsigned char (* FAT_ReadSector)(unsigned long sector, unsigned char * buffer)=MMC_SD_ReadSingleBlock;//device readunsigned char (* FAT_WriteSector)(unsigned long sector, unsigned char * buffer)=MMC_SD_WriteSingleBlock;//device writestruct FileInfoStruct FileInfo;//temporarily buffer for file informationunsigned long lDbr_Sector = 0; /*DBR所在扇取*/unsigned long Capacity;struct BPB bpb;//get DBR(BPB)infovoid Get_Dbr_Info(unsigned char *p){unsigned char i,j;bpb.iBytes_Per_Sector = p[1]<<8 | p[0];bpb.cSectors_Per_Clust = p[2];bpb.iRsv_Sectors = p[4]<<8 | p[3];bpb.cFats = p[5];bpb.iRoot_Dir_Entries = p[7]<<8 | p[6];bpb.iSmall_Sectors = p[9]<<8 | p[8];bpb.cMedia = p[10];bpb.iSectors_Per_Fat16 = p[12]<<8 | p[11];bpb.iSectors_Per_Track = p[14]<<8 | p[13];bpb.iHeads = p[16]<<8 | p[15];bpb.lHidden_Sectors = p[20]<<24 | p[19]<<16 | p[18]<<8 | p[17];bpb.lBig_Sectors = p[24]<<24 | p[23]<<16 | p[22]<<8 | p[21];i = 25;//FAT32时插如信息,FAT16直接运行后面程序if(bpb.iSectors_Per_Fat16 == 0){bpb.lSectors_Per_Fat32 = p[28]<<24 | p[27]<<16 | p[26]<<8 | p[25];bpb.iExt_Flag = p[30]<<8 | p[29];bpb.iFile_System_Ver = p[32]<<8 | p[31];bpb.lRoot_Clust = p[36]<<24 | p[35]<<16 | p[34]<<8 | p[33];bpb.iFile_System_Info = p[38]<<8 | p[37];bpb.iBackup_Boot_Sector = p[40]<<8 | p[39];//12bytsi=53;}//boot sector(FAT16 & FAT32)bpb.cDrv_Num = p[i++];i++; //rsvbpb.cBoot_Sig = p[i++];bpb.lVol_Id = p[i+3]<<24 | p[i+2]<<16 | p[i+1]<<8 | p[i];i += 4;for(j=0; j<11; j++)bpb.cVol_Lab[j] = p[i++];for(j=0; j<8; j++)bpb.cFile_System_Type[j] = p[i++];}//Initialize of FAT need initialize SD firstunsigned char FAT_Init(){struct DBR * bs;unsigned char buffer[512];//1.memory sizeCapacity = MMC_SD_ReadCapacity();if(Capacity < 0xff)return 1;//2.read MBR or DBRif(FAT_ReadSector(0, buffer)) /*read MBR(有可能直接为DBR)*/ return 1;if((buffer[510] != 0x55) || (buffer[511] != 0xaa))return 1;//首扇区=DBR?if((buffer[0]!=0xE9) && (buffer[0]!=0xEB) ){//2.1读取MBR中的DPT(分区表)信息,用于跳到DBRlDbr_Sector = buffer[457]<<24 | buffer[456]<<16 | buffer[455]<<8 | buffer[454];if(lDbr_Sector >= Capacity/512){ /*>所有扇区?*/lDbr_Sector = 0;return 1;}else{//2.2read DBRif(FAT_ReadSector(lDbr_Sector, buffer)) //read DBRreturn 1;//read the bpb sectorif((buffer[510] != 0x55) || (buffer[511] != 0xaa))return 1;if((buffer[0]!=0xE9) && (buffer[0]!=0xEB))return 1;}}//DBR infobs = (struct DBR *)buffer;//3.get bpb infoGet_Dbr_Info(&(bs->cBpb[0])); /*读取DBR(BPB)信息*///4.if(bpb.iSectors_Per_Fat16){ //do not support FAT12FAT32_Enable = 0; //FAT16lFat_Sectors = bpb.iSectors_Per_Fat16; /*FAT占用的扇区数//the sectors number occupied by one fat talbe*/lFirst_Dir_Clust = 2;}else{FAT32_Enable = 1; //FAT32lFat_Sectors = bpb.lSectors_Per_Fat32; /*FAT占用的扇区数//the sectors number occupied by one fat talbe*/lFirst_Dir_Clust = bpb.lRoot_Clust;}//5.lFirst_Fat_Sector = lDbr_Sector + bpb.iRsv_Sectors; /*第一个FAT表扇区= DBR + 保留*///文件分配表≡DBR +保留扇区数lFirst_Dir_Sector = lFirst_Fat_Sector + (bpb.cFats * lFat_Sectors); /*第一个目录扇区= FAT + FAT_SIZE*///根目录≡保留扇区数+FAT的个数×每个FAT的扇区数lRoot_Dir_Sectors = (bpb.iRoot_Dir_Entries * 32) >> 9; /*根目录占用的扇区数= DIR_CNT * 32 / 512;FAT32此项=0*/lFirst_Data_Sector = lFirst_Dir_Sector + lRoot_Dir_Sectors; /*第一个数据扇区= DIR + DIR_SIZE*///数据区≡根目录逻辑扇区号+(32×根目录中目录项数)/ 每扇区字节数return 0;}//读一个簇中的一个扇区//read one sector of one cluster, parameter part indicate which sectorunsigned char FAT_LoadPartCluster(unsigned long cluster,unsigned part,BYTE * buffer){ DWORD sector;sector = lFirst_Data_Sector + (DWORD)(cluster - 2) * (DWORD)bpb.cSectors_Per_Clust;//calculate the actual sector number//逻辑扇区号=数据区起始逻辑扇区号+(簇号-2)×每簇扇区数if(FAT_ReadSector(sector+part, buffer))return 1;elsereturn 0;}//读下一簇簇号//Return the cluster number of next cluster of file//Suitable for system which has limited RAMunsigned long FAT_NextCluster(unsigned long cluster){BYTE buffer[512];DWORD sector;DWORD offset;if(cluster<2)return 0x0ffffff8;//FAT_PTR_SIZE = 2(FAT16); 4(FAT32)//setor offset = (N * FAT_PA T_SIZE) /512if(FAT32_Enable)offset = cluster/128;elseoffset = cluster/ 256;sector = lFirst_Fat_Sector + offset;//calculate the actual sectorif(FAT_ReadSector(sector, buffer))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured//bytes offset = (N * FAT_PTR_SIZE) % 512if(FAT32_Enable){offset=cluster%128; //find the positionsector = ((unsigned long *)buffer)[offset+3]<<24;sector |= ((unsigned long *)buffer)[offset+2]<<16;sector |= ((unsigned long *)buffer)[offset+1]<<8;sector |= ((unsigned long *)buffer)[offset];}else{offset = cluster % 256;//find the positionsector =(buffer)[offset*2+1]<<8;sector |=(buffer)[offset*2];}return (unsigned long)sector; //return the cluste number}#if FIX_DIRECTORY#if 0//在给定目录下查找文件//Find a item in the directory which specify by the parameter "cluster"//Return the start cluster numberunsigned int FAT_FindItem(unsigned long cluster, BYTE *name, struct FileInfoStruct *FileInfo){ BYTE *buffer;DWORD tempclust;DWORD sector;unsigned char cnt;unsigned int offset;unsigned char i;struct direntry *item = 0;if((cluster==0) && (FAT32_Enable == 0)){// root directorybuffer=malloc(512);//apply memoryif(buffer==0)return 1;//if failedfor(cnt=0;cnt<lRoot_Dir_Sectors;cnt++){if(FAT_ReadSector(lFirst_Dir_Sector+cnt,buffer)){free(buffer);return 1;}for(offset=0;offset<512;offset+=32){item=(struct direntry *)(&buffer[offset]);if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f)){for(i=0;i<11;i++){if(buffer[offset+i]!=name[i])break;}if(i==11){//return the parameter of the itemFileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't careFileInfo->Size = item->deFileSize;FileInfo->Attr = item->deAttributes;FileInfo->Sector = lFirst_Dir_Sector+cnt;FileInfo->Offset = offset;free(buffer);return 0;}}}}free(buffer);//release}else//other folders{tempclust=cluster;while(1){sector=lFirst_Data_Sector+(DWORD)(tempclust-2)*(DWORD)bpb.cSectors_Per_Clust;//cal culate the actual sector numberbuffer=malloc(512);//apply memoryif(buffer==0)return 1;//if failedfor(cnt=0; cnt<bpb.cSectors_Per_Clust; cnt++){if(FAT_ReadSector(sector+cnt,buffer)){free(buffer);return 1;}for(offset=0;offset<512;offset+=32){item=(struct direntry *)(&buffer[offset]);if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f)){for(i=0;i<11;i++){if(buffer[offset+i]!=name[i])break;}if(i==11){FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't careFileInfo->Size = item->deFileSize;FileInfo->Attr = item->deAttributes;FileInfo->Sector = sector+cnt;FileInfo->Offset = offset;free(buffer);return 0;}}}}free(buffer);//releasetempclust=FAT_NextCluster(tempclust);//next clusterif(tempclust == 0x0fffffff || tempclust == 0x0ffffff8 || (FAT32_Enable == 0 && tempclust == 0xffff))break;}}return 1;}#endif#if 0// find a directory with the given pathunsigned long FAT_OpenDir(BYTE * dir){BYTE name[11];BYTE *p=dir;BYTE deep=0;BYTE i,j;DWORD cluster=0;if(FAT32_Enable)cluster = lFirst_Dir_Clust;if(*p != '\\')return 1;//invalid pathwhile(*p){if(*p == '\\'){deep++;}p++;}p=dir;for(i=0;i<deep-1;i++){p++;for(j=0;j<11;j++)name[j]=0x20;j=0;while(*p != '\\'){if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;else name[j] = *p++;j++;}if(FAT_FindItem(cluster,name, &FileInfo))return 1;//find the directorycluster = FileInfo.StartCluster;}p++;for(j=0;j<11;j++)name[j]=0x20;j=0;while(*p){if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;else name[j]=*p++;j++;}if(j == 0)return cluster;if(FAT_FindItem(cluster,name, &FileInfo))return 1;//find the final directory cluster = FileInfo.StartCluster;return cluster;}#endif#endif#if 0//复制记录项信息//copy itemvoid CopyDirentruyItem(struct direntry *Desti,struct direntry *Source){BYTE i;for(i=0;i<8;i++)Desti->deName[i] = Source->deName[i];for(i=0;i<3;i++)Desti->deExtension[i] = Source->deExtension[i];Desti->deAttributes = Source->deAttributes;Desti->deLowerCase = Source->deLowerCase;Desti->deCHundredth = Source->deCHundredth;for(i=0;i<2;i++)Desti->deCTime[i] = Source->deCTime[i];for(i=0;i<2;i++)Desti->deCDate[i] = Source->deCDate[i];for(i=0;i<2;i++)Desti->deADate[i] = Source->deADate[i];Desti->deHighClust = Source->deHighClust;for(i=0;i<2;i++)Desti->deMTime[i] = Source->deMTime[i];for(i=0;i<2;i++)Desti->deMDate[i] = Source->deMDate[i];Desti->deStartCluster = Source->deStartCluster;Desti->deFileSize = Source->deFileSize;}#endif#if FIX_DIRECTORY#if 0//search the file , when *count = 0 it will bring the number whole songs, when *cout != 0 the *MusicInfo will bring the infomation of the fileBYTE Search(BYTE *dir,struct direntry *MusicInfo,WORD *Count,BYTE *type)//当COUNT 为零时,有它带回这个目录下总共有多少首音乐{ //不为零时有MusicInfo带回第Count首歌的详细文件信息BYTE *buffer;//BYTE buff[3];DWORD sector;DWORD cluster;DWORD tempclust;unsigned char cnt;unsigned int offset;unsigned int i=0;struct direntry *item = 0;cluster = FAT_OpenDir(dir);if(cluster == 1)return 1;if(cluster==0 && FAT32_Enable==0)// root directory{buffer=malloc(512);//apply memoryif(buffer==0)return 1;//if failedfor(cnt=0;cnt<lRoot_Dir_Sectors;cnt++){if(FAT_ReadSector(lFirst_Dir_Sector+cnt,buffer)){free(buffer);return 1;}for(offset=0;offset<512;offset+=32){item=(struct direntry *)(&buffer[offset]);//pointer convert//find a valid item and display itif((item->deName[0] != '.') && (item->deName[0] != 0x00) &&(item->deName[0] != 0xe5) && (item->deAttributes != 0x0f)){if((item->deExtension[0] == 'b')&&(item->deExtension[1] == 'm')&&(item->deExtension[2] == 'p')){CopyDirentruyItem(MusicInfo,item);*type=1;i++;if(i==*Count){free(buffer);return 0;}}}}}free(buffer);//release}else//other folders{tempclust=cluster;while(1){sector=lFirst_Data_Sector+(DWORD)(tempclust-2)*(DWORD)bpb.cSectors_Per_Clust;//cal culate the actual sector numberbuffer=malloc(512);//apply memoryif(buffer==0)return 1;//if failedfor(cnt=0;cnt<bpb.cSectors_Per_Clust;cnt++){if(FAT_ReadSector(sector+cnt,buffer)){free(buffer);return 1;}for(offset=0;offset<512;offset+=32){item=(struct direntry *)(&buffer[offset]);if((item->deName[0] != '.') && (item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f)){if((item->deExtension[0] == 'b')&&(item->deExtension[1] == 'm')&&(item->deExtension[2] == 'p')){CopyDirentruyItem(MusicInfo,item);*type=1;i++;if(i==*Count){free(buffer);return 0;}}}}}free(buffer);//releasetempclust=FAT_NextCluster(tempclust);//next clusterif(tempclust == 0x0fffffff || tempclust == 0x0ffffff8 || (FAT32_Enable == 0 && tempclust == 0xffff))break;}}if(*Count==0)*Count=i;return 0;}#endif#else#if 0void WriteFolderCluster(WORD addr,DWORD cluster){/*#if FAT_DEBUGprintf_P(PSTR("\r\nWrite EEPROM address:%d with value:%ld"),addr,cluster);#endifeeprom_write_byte(addr,cluster>>24);eeprom_write_byte(addr+1,cluster>>16);eeprom_write_byte(addr+2,cluster>>8);eeprom_write_byte(addr+3,cluster>>0);*/}DWORD GetFolderCluster(WORD addr){/* DWORD temp;temp = eeprom_read_byte(addr);temp <<= 8;temp += eeprom_read_byte(addr+1);temp <<= 8;temp += eeprom_read_byte(addr+2);temp <<= 8;temp += eeprom_read_byte(addr+3);#if FAT_DEBUGprintf_P(PSTR("\r\nRead EEPROM address: %d value is: %ld"),addr,temp);#endifreturn temp;*/}#endifstruct direntry fdt;void Get_Fdt_Info(unsigned char *p){unsigned char i;for(i=0; i<8; i++) fdt.deName[i] = p[i];for(i=0; i<3; i++) fdt.deExtension[i] = p[i+8];fdt.deAttributes = p[11];//2byts check :12, 13for(i=0; i<2; i++) fdt.deCTime[i] = p[i+14];for(i=0; i<2; i++) fdt.deCDate[i] = p[i+16];for(i=0; i<2; i++) fdt.deADate[i] = p[i+18];fdt.deHighClust = p[21]<<8;fdt.deHighClust |= p[20];for(i=0; i<2; i++) fdt.deMTime[i] = p[i+22];for(i=0; i<2; i++) fdt.deMDate[i] = p[i+24];fdt.deStartCluster = p[27]<<8;fdt.deStartCluster |= p[26];fdt.deFileSize = p[31]<<24;fdt.deFileSize |= p[30]<<16;fdt.deFileSize |= p[29]<<8;fdt.deFileSize |= p[28];}void delay(unsigned long p){unsigned long i,j,k=0;for(i=0; i<p; i++){for(j=0; j<100000; j++)k++;}}struct BMP_HEADER{unsigned int iFile_Type; // 0unsigned long lFile_Size; // 2//rsv 2bytes // 6//rsv 2bytes // 8unsigned long lBmp_Data_Offset; //offset=10};struct BMP_INFO{unsigned long lInfo_Size; // 14unsigned long lBmp_Width; // 18unsigned long lBmp_Height; // 22//2bytes //26unsigned int iBit_Count; // 28//2bytes // 30unsigned long lImage_Size; // 32unsigned long lXPels_Per_Meter; // 36unsigned long lYPels_Per_Meter; // 40//4bytes};struct BMP_HEADER bmp_header;struct BMP_INFO bmp_info;void Get_Bmp_Info(unsigned char *p){bmp_header.lBmp_Data_Offset = p[13]<<24;bmp_header.lBmp_Data_Offset |= p[12]<<16;bmp_header.lBmp_Data_Offset |= p[11]<<8;bmp_header.lBmp_Data_Offset |= p[10];bmp_info.lBmp_Width = p[21]<<24;bmp_info.lBmp_Width |= p[20]<<16;bmp_info.lBmp_Width |= p[19]<<8;bmp_info.lBmp_Width |= p[18];bmp_info.lBmp_Height = p[25]<<24;bmp_info.lBmp_Height |= p[24]<<16;bmp_info.lBmp_Height |= p[23]<<8;bmp_info.lBmp_Height |= p[22];bmp_info.iBit_Count = p[28];}//注:// 1.目前只做了24位BMP测试,其他没做.// 2.没做4字节对齐处理unsigned char Disp_Bmp(void){unsigned char i, k;unsigned int j;unsigned char cbuf[512];unsigned char cbmp[512];WORD count= 1;unsigned char type , rgb,first ,color_byte,byte1,byte2,byte3 ;unsigned int y,x;unsigned long p,color,tmp_color; //簇指示值//cluster//uint16 color_16bit = 0; //列地址自动加1时使用for(i=0; i<32; i++){ //32扇区根目录if(FAT_ReadSector(lFirst_Dir_Sector+i, cbuf))return 1;for(j=0; j<512; j+=32){Get_Fdt_Info(&(cbuf[j]));//.bpmif((fdt.deName[0] != '.') && (fdt.deName[0] != 0x00) && (fdt.deName[0] != 0xe5)){//if(fdt.deAttributes )if(((fdt.deExtension[0] == 'B') && (fdt.deExtension[1] == 'M') && (fdt.deExtension[2] == 'P'))\|((fdt.deExtension[0] == 'b') && (fdt.deExtension[1] == 'm') && (fdt.deExtension[2] == 'p'))){//Lcd_Fill(0,0,480,272,0);p = fdt.deStartCluster;x = 0 ;y = 0 ;rgb = 0 ;count = 0 ;first = 0 ;smallen_puts(0,0,fdt.deName);CLR_CS_CPLD();FAT_LoadPartCluster(p, k, cbmp);Get_Bmp_Info(cbmp);//read 1 bmp file//未做4bytes对齐转换,图象宽度须为4的倍数while(1){for(k=0; k<bpb.cSectors_Per_Clust; k++){。
51单片机与迪文DGUS屏通信合作,下载及模拟调试
51单片机与迪文DGUS屏通信合作,下载及模拟调试迪文DGUS屏的所有硬件参数和资料下载,都是通过屏上的SD/SDHC接口来完成的,文件必须使用FAT32文件格式。
第一次使用SD卡前,推荐先格式化一次,流程如下:1、右键单击SD卡,在弹出来的菜单中选择“格式化”:2、在弹出的“格式化SD卡”属性框中,我们需要将SD卡的文件系统设置成FAT32格式,分配单元大小设置成4096字节,这两点尤其重要,否则,可能识别不到SD卡。
SD卡成功格式化后,我们就可以将DGUS工程中的DWIN_SET文件夹复制到SD卡中了开始下载程序了,这里需要注意的是,SD卡中不要有其他的文件或文件夹,只能放一个DWIN_SET文件夹。
接下来,我们就可以把SD卡插到DGUS屏的SD卡接口上,DGUS屏检测到SD卡后,会显示蓝屏提示用户检测到SD卡,然后开始下载SD卡中的文件到屏中。
在下载SD卡文件的时候,需要注意的是:两次SD卡热插拔之间必须间隔至少6秒,不然DGUS屏会认为是同一张卡,而不会启动SD卡操作。
如果用户已经禁止SD卡接口,要启用SD卡接口,除非事先解锁或在SD卡的CONFIG.TXT文件中有解锁指令。
SD卡下载完成,DGUS屏会自动复位一次,拔出SD卡,下载结束。
因为现在没有跟单片机程序通信上,所以,屏上也都只是显示一些变量的初始值,或许还有小伙伴们在下载工程文件后,发现显示位置不对,或者说有点偏位,那么该怎么快速调整呢?这个时候,DGUS软件的在线下载功能就可以为我们提供便利了,毕竟,只是修改一下变量的属性的话,在线下载功能还是很方便的,既能马上看到效果,又可以避免每次插拔SD卡的麻烦,下面接跟着笔者来体验以下该功能吧。
首先,我们需要准备一条USB转232的线,然后,将USB转232线的RXD、TXD、GND。
单片机读取FLASH
FAT32文件系统的存储机制及其在单片机上的实现FA T32文件系统您一定不会陌生,最多看到它是在windows操作系统里,但在一些嵌入式产品(如手机、MP3、MP4等)中,也能看到它的身影。
从某种意义上来讲,FA T32文件系统是非常成功的,使我们可以脱离底层储存设备驱动,更为方便高效地组织数据。
给单片机系统中的大容量存储器(如SD卡、CF卡、硬盘等)配以FA T32文件系统,将是非常有意义的(如创建的数据文件可以在windows等操作系统中直接读取等)。
FA T32本身是比较复杂的,对其进行讲解的最好方法就是实际演练。
笔者手里持有一张刚以FA T32格式化的SD卡,我们就围绕它来讲解FA T32的实现机理。
FA T32分为几个区域,这里将用实例的方法对它们的结构与在文件存储中的功能进行详细的剖析。
1、实例说明此实例首先在一张空的SD卡(已被格式化为FA T32格式)上创建一个文本文件,并在其中输入20个字符。
再将它插入到单片机系统中,实现对这个文件的读取,将文件内容输出在调试终端上。
2、实现过程1)格式化与创建文件Windows上的磁盘格式化与文件创建就不用多说了。
如下图:2)DBR(DOS BOOT RECORD 操作系统引导记录区)DBR是我们进军FA T32的首道防线。
其实DBR中的BPB部分才是这一区域的核心部分(第12~90字节为BPB),只有深入详实的理解了BPB的意义,才能够更好的实现和操控FA T32。
关于DBR在FA T32中的地位就不多说了,以下面实际的DBR内图所示:上面的数据看起来杂乱不堪,无从下手,其实对我们有用的数据只不过90个字节(如图中彩色线标记的字节)。
仅仅是这90个字节就可以告诉我们关于磁盘的很多信息,比如每扇区字节数、每簇扇区数、磁道扇区数等等。
对于这些信息的读取,只要遵循DBR中的字段定义即可。
(比如图中紫色字段的两个字节表示这张磁盘的每一个扇区有512个字节,具体的计算方法见下文)字段定义如下表(BPB后面的422个字节对我们的意义不大,表中省略):DBR的实现代码:struct FAT32_DBR{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_NumFAT s[1]; //此卷中FAT表数offset:16 unsigned char BPB_RootEntCnt[2]; //FAT32为0 offset:17 unsigned char BPB_T otSec16[2]; //FAT32为0 offset:19 unsigned char BPB_Media[1]; //存储介质offset:21 unsigned char BPB_FATSz16[2]; //FAT32为0 offset:22 unsigned char BPB_SecPerT rk[2]; //磁道扇区数offset:24 unsigned char BPB_NumHeads[2]; //磁头数offset:26 unsigned char BPB_HiddSec[4]; //FAT区前隐扇区数offset:28unsigned char BPB_T otSec32[4]; //该卷总扇区数offset:32unsigned char BPB_FATSz32[4]; //一个FAT表扇区数offset:36unsigned char BPB_ExtFlags[2]; //FAT32特有offset:40unsigned char BPB_FSVer[2]; //FAT32特有offset:42unsigned char BPB_RootClus[4]; //根目录簇号offset:44unsigned char FSInfo[2]; //保留扇区FSINFO扇区数offset:48unsigned char BPB_BkBootSec[2]; //通常为6 offset:50unsigned char BPB_Reserved[12]; //扩展用offset:52unsigned char BS_DrvNum[1]; // offset:64unsigned char BS_Reserved1[1]; // offset:65unsigned char BS_BootSig[1]; // offset:66unsigned char BS_VolID[4]; // offset:67unsigned char BS_FilSysT ype[11]; // offset:71unsigned char BS_FilSysT ype1[8]; //"FAT32 " offset:82};在程序中我们采用以上的结构体指针对扇区数据指针进行转化,就可以直接读取数据中的某一字段,如要读取BPB_BytesPerSec,可以这样来作:((struct FAT32_DBR *)pSector)-> BPB_BytesPerSec用如上语句就可以得到这一字段的首地址。
MCS51 MCU读写SD卡版(单片机论文)
摘要摘要近年来, SD存储卡在嵌入式产品中的应用越来越广泛, 但SD卡接口一般仅集成在32位高端处理器中, 一般51单片机则由于资源限制没有该接口。
因此,如何解决51单片机应用系统存取SD卡大容量数据就显得很有实际意义。
本系统使用MXT8051F04A作为单片机与SD卡的接口芯片, 采用SPI串行方式对SD卡的扇区进行读写,读写过程和结果通过串口调试助手在主机上显示。
本论文的核心主要从硬件设计和软件编程两个大的方面介绍了系统的实现。
硬件电路设计主要包括MXT8051F04A最小系统电路、电源电路、串口电路、SD卡接口电路。
程序采用C语言在Keil软件下进行编写、调试,程序主要包括SD卡扇区读写程序、串口程序等软件模块。
系统实现了对SD卡扇区的读写,达到了设计的要求和目的。
关键字:MXT8051F04A,SD卡,KeilIABSTRACTABSTRACTIn recent years, SD memory card applications in the embedded products more widely, but generally only the integrated SD card interface in 32-bit high-end processor, microcontroller 51 is generally not the interface due to resource constraints. Therefore, how to solve the 51 SCM applications to access data on large-capacity SD cards seem very practical.The system uses MXT8051F04A as SCM and SD card interface chip, using SPI mode on the SD card serial read and write sectors, reading and writing process and results through the serial port on the host display debugging assistant. The core of this thesis, the main hardware and software design introduces two major aspects of the system implementation. Hardware design includes MXT8051F04A minimum system circuit, power circuit, the serial port circuitry, SD card interface circuit. Program using C language under the Keil software write, debug, the program includes reading and writing SD card sector program, serial procedures of software modules. System realizes the SD card read and write sectors, meets the design requirements and objectives.Keywords: MXT8051F04A,SD Card,KeilII目录第1章引言 (1)1.1 选题背景 (1)1.2 研究目标和意义 (1)1.3 本文要完成的工作 (1)第2章单片机读写SD卡的硬件电路设计 (3)2.1 系统硬件平台组成 (3)2.2 电源模块 (3)2.3 MXT8051F04A单片机最小系统电路设计 (4)2.3.1 MXT8051F04A简介 (4)2.3.2 晶振复位电路 (8)2.4 SD卡电路设计 (8)2.4.1 通讯模式 (9)2.4.2 电平匹配 (9)2.4.3 硬件接口设计 (10)2.5 串口电路设计 (12)2.6 PCB绘制 (13)2.7 本章小结 (14)第3章单片机读写SD卡的软件设计 (14)3.1 SD卡的扇区读写 (14)3.1.1 模拟SPI协议 (14)3.1.2 SD卡命令 (15)3.1.3 SD卡的初始化 (19)3.1.4 数据块的读写 (20)3.2 串口程序 (25)第4章调试 (26)4.1 系统硬件调试 (26)4.2 软件调试 (27)4.3 软硬件的联合调试 (27)III4.4 本章小结 (29)第5章结束语 (30)5.1 总结 (30)5.2 展望 (30)参考文献 (31)致谢 (32)附录 (33)附录一:单片机读写SD卡的完整原理图 (33)附录二:单片机读写SD卡的完整程序 (36)外文资料原文 (63)译文 (64)IV第1章引言第1章引言1.1选题背景SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如个人数码助理(PDA)、数码相机和多媒体播放器等。
基于51单片机和FAT32文件系统的SDHC卡读写系统设计
o p e n i n g i f l e a n d r e a d i n g a n d w r i t i n g i f l e . I n a d d i t i o n ,we t e s t e d t h e r a t e o f a c c e s s i n g d a t a . E x p e i r me n t s s h o w t h a t z n F A T i f l e s y s t e m c a n b e e a s i l y t r a n s p l a n t e d t o t h e 5 1 mi c r o — c o n t r o l l e r ,a n d t h e r a t e o f a e — c e s s i n g d a t a c a n f u l l y me e t t h e n e e d s o f e n g i n e e r i n g .
Ab s t r a c t :I n v i e w o f t h e l i mi t e d s t o r a g e c a p a c i t y o f 5 1 mi c r o —c o n t r o l l e r ,a s y s t e m o f a c c e s s i n g d a t a f r o m S DHC c a r d b a s e d o n 5 1 mi c r o —c o n r t o l l e r a n d t h e F AT 3 2 i f l e s y s t e m i s p r o p o s e d .T h i s p a p e r ma k e s a r e s e a r c h o n t h e d i r v i n g p r i n c i p l e o f S DHC c a r d,a n d d e s i g n s t h e h a r d wa re c i r c u i t b e t we e n 5 1 mi c r o — c o n ro t l l e r a n d S DHC c r d,a a n d p r o g r a ms t h e i n i t i a l i z a t i o n a n d s e c t o r o p e r a t i o n o f S D HC c rd a .
FAT32文件系统实现单片机MP3播放器 源代码要点
#include <sd.h>#include <ctype.h>/*SD卡MP3播放器源代码*/sbit XDCS =P2^2;sbit DREQ =P3^5;sbit XRESET=P3^4;sbit XCS =P2^5;sbit CLK =P3^3;sbit DATA =P2^3;#define VOL_V ALUE 0x0000/*分区记录结构*/struct PartRecord{unsigned char Active; //0x80表示此分区有效unsigned char StartHead; //分区的开始头unsigned char StartCylSect[2];//开始柱面与扇区unsigned char PartType; //分区类型unsigned char EndHead; //分区的结束头unsigned char EndCylSect[2]; //结束柱面与扇区unsigned char StartLBA[4]; //分区的第一个扇区unsigned char Size[4]; //分区的大小};/*分区扇区(绝对0扇区)定义如下*/struct PartSector{unsigned char PartCode[446]; //MBR的引导程序struct PartRecord Part[4]; //4个分区记录unsigned char BootSectSig0;unsigned char BootSectSig1;};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:32unsigned 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_V olID[4]; // offset:67 unsigned char BS_FilSysType[11]; // offset:71 unsigned char BS_FilSysType1[8]; //"FAT32 " offset:82 };// Structure of a dos directory entry. 一个dos目录结构的入口struct direntry{unsigned char deName[8]; // filename, blank filled (文件名)unsigned char deExtension[3]; // extension, blank filled (扩展)unsigned char deAttributes; // file attributes (文件属性)unsigned char deLowerCase; // NT VFAT lower case flags (set to zero)(系统保留)unsigned char deCHundredth; // hundredth of seconds in CTime (创建时间的10毫秒位)unsigned char deCTime[2]; // create time (文件创建时间)unsigned char deCDate[2]; // create date (文件创建日期)unsigned char deADate[2]; // access date (文件最后访问日期)unsigned char deHighClust[2]; // high unsigned chars of cluster number(文件起始簇号的高16位)unsigned char deMTime[2]; // last update time(文件的最近修改的时间)unsigned char deMDate[2]; // last update date(文件的最近修改日期)unsigned char deLowCluster[2]; // starting cluster of file (文件起始簇号的低16位)unsigned char deFileSize[4]; // size of file in unsigned chars (表示文件的长度)};// Stuctures 结构struct FileInfoStruct{unsigned char FileName[12]; //文件名unsigned long FileStartCluster; //< file starting cluster for last file accessed(文件首簇号)unsigned long FileCurCluster; //文件当前簇号unsigned long FileNextCluster; //下一簇号unsigned long FileSize; //< file size for last file accessed(文件大小)unsigned char FileAttr; //< file attr(属性)for last file accessed(文件属性)unsigned short FileCreateTime; //< file creation time for last file accessed (文件建立时间)unsigned short FileCreateDate; //< file creation date for last file accessed (文件建立日期)unsigned short FileMTime; //文件修改时间unsigned short FileMDate; //文件修改日期unsigned long FileSector; //<file record place(文件当前扇区)unsigned long FileOffset; //<file record offset (文件偏移量)};/*FAT32初始化时初始参数装入如下结构体中*/struct FAT32_Init_Arg{unsigned char BPB_Sector_No; //BPB所在扇区号unsigned long Total_Size; //磁盘的总容量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; //根目录下的目录与文件数};//#define FIND_BPB_UP_RANGE 2000 //BPB不一定在0扇区,对0~FINE_BPB_UP_RANGE扇区进行扫描unsigned char xdata FAT32_Buffer[512]; //扇区数据读写缓冲区struct FAT32_Init_Arg Init_Arg; //初始化参数结构体实体struct FileInfoStruct FileInfo; //文件信息结构体实体unsigned char * FAT32_ReadSector(unsigned long LBA,unsigned char *buf) //FAT32中读取扇区的函数{MMC_get_data_LBA(LBA,512,buf);return buf;}unsigned char FAT32_WriteSector(unsigned long LBA,unsigned char *buf)//FAT32中写扇区的函数{return MMC_write_sector(LBA,buf);}unsigned long lb2bb(unsigned char *dat,unsigned char len) //小端转为大端{unsigned long temp=0;unsigned long fact=1;unsigned char i=0;for(i=0;i<len;i++){temp+=dat[i]*fact;fact*=256;}return temp;}unsigned long FAT32_FindBPB() //寻找BPB所在的扇区号{MMC_Init(); //SD卡初始化FAT32_ReadSector(0,FAT32_Buffer);if(FAT32_Buffer[0]!=0xeb)return lb2bb(((((struct PartSector *)(FAT32_Buffer))->Part[0]).StartLBA),4);elsereturn 0;}unsigned long FAT32_Get_Total_Size() //存储器的总容量,单位为M{MMC_Init(); //SD卡初始化FAT32_ReadSector(Init_Arg.BPB_Sector_No,FAT32_Buffer);return ((float)(lb2bb((((struct FAT32_BPB *)(FAT32_Buffer))->BPB_TotSec32),4)))*0.0004883; }void FAT32_Init(struct FAT32_Init_Arg *arg){struct FAT32_BPB *bpb;bpb=(struct FAT32_BPB *)(FAT32_Buffer); //将数据缓冲区指针转为struct FAT32_BPB 型指针arg->BPB_Sector_No =FAT32_FindBPB(); //FAT32_FindBPB()可以返回BPB所在的扇区号arg->Total_Size =FAT32_Get_Total_Size(); //FAT32_Get_Total_Size()可以返回磁盘的总容量,单位是兆arg->FATsectors =lb2bb((bpb->BPB_FATSz32) ,4); //装入FAT表占用的扇区数到FATsectors中arg->FirstDirClust =lb2bb((bpb->BPB_RootClus) ,4); //装入根目录簇号到FirstDirClust中arg->BytesPerSector =lb2bb((bpb->BPB_BytesPerSec),2); //装入每扇区字节数到BytesPerSector中arg->SectorsPerClust =lb2bb((bpb->BPB_SecPerClus) ,1); //装入每簇扇区数到SectorsPerClust 中arg->FirstFATSector =lb2bb((bpb->BPB_RsvdSecCnt) ,2)+arg->BPB_Sector_No;//装入第一个FAT表扇区号到FirstFATSector 中arg->RootDirCount =lb2bb((bpb->BPB_RootEntCnt) ,2); //装入根目录项数到RootDirCount中arg->RootDirSectors =(arg->RootDirCount)*32>>9; //装入根目录占用的扇区数到RootDirSectors中arg->FirstDirSector =(arg->FirstFATSector)+(bpb->BPB_NumFATs[0])*(arg->FATsectors); //装入第一个目录扇区到FirstDirSector中arg->FirstDataSector =(arg->FirstDirSector)+(arg->RootDirSectors); //装入第一个数据扇区到FirstDataSector中send_s("FATchushihuachengong"); //FAT初始化成功}void FAT32_EnterRootDir(){unsigned long iRootDirSector;unsigned long iDir;struct direntry *pDir;for(iRootDirSector=(Init_Arg.FirstDirSector);iRootDirSector<(Init_Arg.FirstDirSector)+(Init_Ar g.SectorsPerClust);iRootDirSector++){FAT32_ReadSector(iRootDirSector,FAT32_Buffer);for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry)){pDir=((struct direntry *)(FAT32_Buffer+iDir));if((pDir->deName)[0]!=0x00 /*无效目录项*/ && (pDir->deName)[0]!=0xe5 /*无效目录项*/ && (pDir->deName)[0]!=0x0f /*无效属性*/){Printf_File_Name(pDir->deName);}}}}void FAT32_CopyName(unsigned char *Dname,unsigned char *filename){unsigned char i=0;for(;i<11;i++){Dname[i]=filename[i];}Dname[i]=0;}unsigned long FAT32_EnterDir(char *path){unsigned long iDirSector;unsigned long iCurSector=Init_Arg.FirstDirSector;unsigned long iDir;struct direntry *pDir;unsigned char DirName[12];unsigned char depth=0,i=0;while(path[i]!=0){if(path[i]=='\\'){depth++;}i++;}if(depth==1){return iCurSector; //如果是根目录,直接返回当前扇区号}for(iDirSector=iCurSector;iDirSector<(Init_Arg.FirstDirSector)+(Init_Arg.SectorsPerClust);iDirS ector++){FAT32_ReadSector(iDirSector,FAT32_Buffer);for(iDir=0;iDir<Init_Arg.BytesPerSector;iDir+=sizeof(struct direntry)){pDir=((struct direntry *)(FAT32_Buffer+iDir));if((pDir->deName)[0]!=0x00 /*无效目录项*/ && (pDir->deName)[0]!=0xe5 /*无效目录项*/ && (pDir->deName)[0]!=0x0f /*无效属性*/){Printf_File_Name(pDir->deName);}}}}unsigned char FAT32_CompareName(unsigned char *sname,unsigned char *dname){unsigned char i,j=8;unsigned char name_temp[12];for(i=0;i<11;i++) name_temp[i]=0x20;name_temp[11]=0;i=0;while(sname[i]!='.'){name_temp[i]=sname[i];i++;}i++;while(sname[i]!=0){name_temp[j++]=sname[i];i++;}//Printf(name_temp,0);for(i=0;i<11;i++){if(name_temp[i]!=dname[i]) return 0;}//Printf(name_temp,0);return 1;}unsigned long FAT32_GetNextCluster(unsigned long LastCluster) //给出一个簇号,计算出它的后继簇号的函数{unsigned long temp;struct FAT32_FAT *pFAT;struct FAT32_FAT_Item *pFAT_Item;temp=((LastCluster/128)+Init_Arg.FirstFATSector);//计算给定簇号对应的簇项的扇区号FAT32_ReadSector(temp,FAT32_Buffer);pFAT=(struct FAT32_FAT *)FAT32_Buffer;pFAT_Item=&((pFAT->Items)[LastCluster%128]);//在算出的扇区中提取簇项return lb2bb(pFAT_Item,4); //返回下一簇号}/*我们最终要实现的是对文件的读取,须要作到给定文件名后,可以得到相应文件的首簇。
(参考)基于stm32的fat32文件系统
(参考)基于stm32的fat32文件系统Main.c/******************************************************************* ** * * * STM32- 3.2寸TFT液晶屏字符和汉字显示程序 ** ********************************************************************* ***/#include "stm32f10x_lib.h"#include "LCD_driver.h"#include "fat.h"#include "MMC.h"struct FAT32_Init_Arg Init_Arg_SD; //初始化参数结构体实体struct FAT32_Init_Arg *pArg;struct FileInfoStruct FileInfo; //文件信息结构体实体uchar file_buf[150]; //文件数据缓冲区,读取到的文件数据放在其中uchar Dev_No=0; //设备号,SDCARD的SD卡设备号的宏定义,根据设备号,znFAT会将底层存储设备驱动连接到相应的存储设备驱动//动态的切换设备号,就可以实现在各种存储设备之间进行切换,这也是znFAT实现多设备的重要手段。
比如,我//可以将SD卡上的文件拷贝到CF卡或U盘上,这就是多设备的最典型应用#define COLOR(r,g,b)(((((((uint)r)>>3)<<6)|(((uint)g)>>2))<<5)|(((uint)b)>>3)) //r红色分量0~31 g绿色分量 0~63 b蓝色分量 0~31#include "LCD.c"/******************************** 变量定义---------------------------------------------------------*/GPIO_InitTypeDef GPIO_InitStructure;ErrorStatus HSEStartUpStatus;unsigned char csd_data[16];unsigned char cid_data[16];unsigned char by;unsigned int c_size, c_size_mult, read_bl_len; unsigned longdrive_size;unsigned long size_mb;/*********************************声明函数 -----------------------------------------------*/void RCC_Configuration(void);void NVIC_Configuration(void);void Delay(vu32 nCount);/******************************************************************* ************主函数******************************************************************** ***********/int main(void){uchar item;RCC_Configuration(); //系统时钟配置函数NVIC_Configuration(); //NVIC配置函数//启动GPIO模块时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);//把调试设置普通IO口GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //所有GPIO为同一类型端口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出的最大频率为50HZGPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA端口GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB端口GPIO_Write(GPIOA,0xffff); //将GPIOA 16个端口全部置为高电平GPIO_Write(GPIOB,0xffff); //将GPIOB 16个端口全部置为高电平GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //所有GPIO为同一类型端口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出的最大频率为50HZGPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA端口LCD_Init();LCD_clear(2); // 这句是显示背景颜色。
基于51单片机FAT32文件系统程序
#ifndef __ZNFAT_H__#define __ZNFAT_H__#include "mytype.h" //类型重定义/*******************************************************///znFAT的裁减宏---------------------------------------------------------//#define ZNFAT_ENTER_DIR //有此宏,函数 znFAT_Enter_Dir() 参与编译#define ZNFAT_OPEN_FILE //有此宏,函数 znFAT_Open_File() 参与编译//#define ZNFAT_SEEK_FILE //有此宏,函数 znFAT_Seek_File() 参与编译//#define ZNFAT_READ_FILE //有此宏,函数 znFAT_Read_File() 参与编译//#define ZNFAT_READ_FILEX //有此宏,函数 znFAT_Read_FileX() 参与编译//#define ZNFAT_ADD_DAT //有此宏,函数 znFAT_Add_Dat() 参与编译//#define ZNFAT_CREATE_DIR //有此宏,函数 znFAT_Create_Dir() 参与编译//#define ZNFAT_CREATE_FILE //有此宏,函数 znFAT_Create_File() 参与编译//#define ZNFAT_DEL_FILE //有此宏,函数 znFAT_Del_File() 参与编译//#define ZNFAT_XCOPY_FILE //有此宏,函数 znFAT_XCopy_File() 参与编译//#define ZNFAT_RENAME_FILE //有此宏,函数 znFAT_Rename_File() 参与编译//#define ZNFAT_GET_TOTAL_SIZE //有此宏,函数 znFAT_Get_Total_Size() 参与编译//#define znFAT_GET_REMAIN_CAP //有此宏,函数 znFAT_Get_Remain_Cap() 参与编译#include "cj.h"#include "cj.h"//----------------------------------------------------------------------#define SOC(c) (((c-pArg->FirstDirClust)*(pArg->SectorsPerClust))+pArg->FirstDirSector) // 用于计算簇的开始扇区#define CONST const//设备表#define SDCARD 0 //SD卡#define UDISK 1 //U盘#define CFCARD 2 //CF卡#define OTHER 3 //其它//这里的存储设备表,可以灵活扩充,以实现对更多存储设备的支持//-------------------------------------------#define MAKE_FILE_TIME(h,m,s) ((((unsigned int)h)<<11)+(((unsigned int)m)<<5)+(((unsigned int)s)>>1))/* 生成指定时分秒的文件时间数据 */#define MAKE_FILE_DATE(y,m,d) (((((unsigned int)y)+20)<<9)+(((unsigned int)m)<<5)+((unsigned int)d))/* 生成指定年月日的文件日期数据 *///DPT:分区记录结构如下struct PartRecord{UINT8 Active; //0x80表示此分区有效UINT8 StartHead; //分区的开始磁头UINT8 StartCylSect[2];//开始柱面与扇区UINT8 PartType; //分区类型UINT8 EndHead; //分区的结束头UINT8 EndCylSect[2]; //结束柱面与扇区UINT8 StartLBA[4]; //分区的第一个扇区UINT8 Size[4]; //分区的大小};//MBR:分区扇区(绝对0扇区)定义如下struct PartSector{UINT8 PartCode[446]; //MBR的引导程序struct PartRecord Part[4]; //4个分区记录UINT8 BootSectSig0; //55UINT8 BootSectSig1; //AA};//znFAT中对BPB的定义如下一共占用90个字节struct znFAT_BPB{UINT8 BS_jmpBoot[3]; //跳转指令 offset: 0 UINT8 BS_OEMName[8]; // offset: 3 UINT8 BPB_BytesPerSec[2];//每扇区字节数 offset:11 UINT8 BPB_SecPerClus[1]; //每簇扇区数 offset:13 UINT8 BPB_RsvdSecCnt[2]; //保留扇区数目 offset:14 UINT8 BPB_NumFATs[1]; //此卷中FAT表数 offset:16 UINT8 BPB_RootEntCnt[2]; //znFAT为0 offset:17 UINT8 BPB_TotSec16[2]; //znFAT为0 offset:19 UINT8 BPB_Media[1]; //存储介质 offset:21 UINT8 BPB_FATSz16[2]; //znFAT为0 offset:22 UINT8 BPB_SecPerTrk[2]; //磁道扇区数 offset:24 UINT8 BPB_NumHeads[2]; //磁头数 offset:26 UINT8 BPB_HiddSec[4]; //FAT区前隐扇区数 offset:28 UINT8 BPB_TotSec32[4]; //该卷总扇区数 offset:32 UINT8 BPB_FATSz32[4]; //一个FAT表扇区数 offset:36 UINT8 BPB_ExtFlags[2]; //znFAT特有 offset:40 UINT8 BPB_FSVer[2]; //znFAT特有 offset:42 UINT8 BPB_RootClus[4]; //根目录簇号 offset:44 UINT8 FSInfo[2]; //保留扇区FSINFO扇区数offset:48 UINT8 BPB_BkBootSec[2]; //通常为6 offset:50 UINT8 BPB_Reserved[12]; //扩展用 offset:52 UINT8 BS_DrvNum[1]; // offset:64 UINT8 BS_Reserved1[1]; // offset:65 UINT8 BS_BootSig[1]; // offset:66 UINT8 BS_VolID[4]; // offset:67 UINT8 BS_FilSysType[11]; // offset:71 UINT8 BS_FilSysType1[8]; //"znFAT " offset:82 };struct znFAT_FAT_Item{UINT8 Item[4];};struct znFAT_FAT{struct znFAT_FAT_Item Items[128];};struct direntry{UINT8 deName[8]; // 文件名,不足部分以空格补充UINT8 deExtension[3]; // 扩展名,不足部分以空格补充UINT8 deAttributes; // 文件属性UINT8 deLowerCase; // 0UINT8 deCHundredth; // 世纪UINT8 deCTime[2]; // 创建时间UINT8 deCDate[2]; // 创建日期UINT8 deADate[2]; // 访问日期UINT8 deHighClust[2]; // 开始簇的高字UINT8 deMTime[2]; // 最近的修改时间UINT8 deMDate[2]; // 最近的修改日期UINT8 deLowCluster[2]; // 开始簇的低字UINT8 deFileSize[4]; // 文件大小};//znFAT初始化时初始参数装入如下结构体中struct znFAT_Init_Arg{UINT8 DEV_No;UINT8 BPB_Sector_No; //BPB所在扇区号UINT32 Total_Size; //磁盘的总容量UINT32 FirstDirClust; //根目录的开始簇UINT32 BytesPerSector; //每个扇区的字节数UINT32 FATsectors; //FAT表所占扇区数UINT32 SectorsPerClust; //每簇的扇区数UINT32 FirstFATSector; //第一个FAT表所在扇区UINT32 FirstDirSector; //第一个目录所在扇区};struct Date{UINT16 year;UINT8 month;UINT8 day;};struct Time{UINT8 hour;UINT8 min;UINT8 sec;};struct FileInfoStruct{UINT8 FileName[15]; //文件名UINT32 FileStartCluster; //文件的开始簇UINT32 FileCurCluster; //文件的当前簇UINT32 FileSize; //文件大小UINT32 FileCurSector; //文件的当前扇区UINT16 FileCurPos; //文件在当前扇区中的位置UINT32 FileCurOffset; //文件的当前偏移量UINT32 Rec_Sec; //文件的文件/目录项所在的扇区UINT16 nRec; //文件的文件/目录项所在扇区中的位置 UINT8 FileAttr; //文件属性struct Time FileCreateTime; //文件的创建时间struct Date FileCreateDate; //文件的创建日期struct Time FileMTime; //文件的修改时间struct Date FileMDate; //文件的修改日期struct Date FileADate; //文件的访问日期};struct FSInfo //znFAT的文件系统信息结构{UINT8 Head[4];UINT8 Resv1[480];UINT8 Sign[4];UINT8 Free_Cluster[4];UINT8 Last_Cluster[4];UINT8 Resv2[14];UINT8 Tail[2];};extern struct znFAT_Init_Arg *pArg; //初始化参数结构体指针,用以指向某一存储设备的初始化参数结构体,由外部提供extern UINT8 Dev_No;//设备号,外部变量//函数声明void znFAT_Device_Init();UINT32 znFAT_Get_Total_Size(void); //获取总容量UINT32 znFAT_Get_Remain_Cap(void); //获取剩余容量void znFAT_Init(void); //文件系统初始化UINT32 znFAT_Enter_Dir(CONST INT8 *path); //进入目录UINT8 znFAT_Open_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,UINT32 item,UINT8 is_file); //打开文件,支持通配UINT8 znFAT_Seek_File(struct FileInfoStruct *pfi,UINT32 offset); //文件定位UINT32 znFAT_Read_File(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,UINT8 *pbuf); //读取文件数据UINT32 znFAT_Read_FileX(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,void (*pfun)(UINT8)); //读取文件数据并进行数据处理UINT32 znFAT_Add_Dat(struct FileInfoStruct *pfi,UINT32 len,UINT8 *pbuf); //向文件追加数据UINT8 znFAT_Create_Dir(CONST INT8 *dirpath,UINT8 *ptd); //创建目录,支持创建时间UINT8 znFAT_Create_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,UINT8 *ptd); //创建文件,支持创建时间UINT8 znFAT_Del_File(CONST INT8 *filepath); //删除文件unsigned char znFAT_XCopy_File(struct znFAT_Init_Arg *pArg1,struct znFAT_Init_Arg *pArg2,CONST INT8*sfilename,CONST INT8 *tfilename,UINT8 *file_buf,UINT32 buf_size,unsigned char *pt); //文件拷贝,支持多设备中文件互拷UINT8 znFAT_File_Close(struct FileInfoStruct *pfi); //文件关闭UINT8 znFAT_Rename_File(CONST INT8 *filename,CONST INT8 *newfilename); //文件重命名#endif#include "znfat.h"#include "sd.h" //存储设备的扇区读写驱动,这里是SD卡//#include "ch375.h" //存储设备的扇区读写驱动,这里是U盘//#include "cf.h" //存储设备的扇区读写驱动,这里是CF盘#include "string.h"//全局变量定义struct direntry temp_rec;INT8 temp_dir_name[13];UINT32 temp_dir_cluster;UINT32 temp_last_cluster;UINT8 znFAT_Buffer[512]; //扇区数据读写缓冲区,由外部提供/****************************************************************** - 功能描述:znFAT的存储设备初始化函数- 隶属模块:znFAT文件系统模块- 函数属性:外部(用于对存储设备进行初始化)- 参数说明:无- 返回说明:无- 注:在调znFAT其它函数之前,必须先对存储设备进行成功的初始化。
基于单片机的硬盘FAT32文件系统访问的设计与实现
dbr.bytes_per_sector = Ide buf er 口 f 中偏 移 O Bb xO 的内容; xO C
2.硬盘结构
2.1 硬 盘物理 结构
/ / sectors per cluster 每族的 数 扇区
dbr.sectors_per_cluster = Ide_buf er[O f xD]; / / reserved sectors 保留 数 扇区
硬盘由很多盘片(platter)组成, ( 每个盘片 的每个面都有一个读写磁头。如果有 N 个盘 片, 2N 个面, 2N 个磁头(Heads) , 就有 对应 ( 从 0, 1,2 开始编号。每个盘片被划分成若干个同 心圃磁道(2 辑上的.是不可见的)。 这样每个盘 片的半径相同的同心圆在逻辑上形成了一个以 电机主轴为轴的柱面(Cylinders) , ( 从外至里编号 为0, 1, 2-二 每个盘片上的每个磁道又被划分为 几十个扇区(Sector) , 通常的容量是 512byte, 并 按 照 一 定 规 则 编 号 为 0 , 1,2 一 形 成
/ / root cluster num 根 目录第一簇的簇 4.系统软件设计 号, 一般为20 4.1 硬盘 的访 问 dbr.root- cluster num 二Ide_buf er口 f 中偏 移 O "O 的内容; x2C x2F IDE 硬盘中有一个驱动器,是硬盘和 / / FAT 开始扇区二 分区开始扇区+保留扇 MCU 之间的通信接口。 在扇区读写操作时, 区 一次按 16 位长度通过内部的高速 PIO 数据寄 存器实现传输,输人输出操作均通过对相应寄 FAT_start_sector 二 即t.star e sector +dbr. t 存器的读/ 写来完成。 首先进行(命令和参数)寄 reserve走sectors;
一种基于51单片机的音乐播放器的设计
一种基于51单片机的音乐播放器的设计作者:何谐唐大权张淑廷陈雪来源:《现代电子技术》2014年第16期摘要:主要介绍一种基于51单片机的音乐播放器的硬件设计方法,并研究在FAT32文件系统下音乐播放器的程序设计。
该音乐播放器采用STC12C5A60S2单片机为主控制器,SD 卡作为音乐文件的存储介质,VS1003芯片作为解码器。
STC12C5A60S2单片机从 SD卡中读取音乐文件,并不断将数据流传送至VS1003解码,最后连接耳机播放,同时STC12C5A60S2连接OLED液晶显示屏实时显示音乐播放信息。
实验表明,该音乐播放器连接耳机能流畅播放多种格式的音乐文件。
关键词: STC12C5A60S2;音乐播放器; FAT32文件系统;程序设计中图分类号: TN912.2⁃34 文献标识码: A 文章编号: 1004⁃373X(2014)16⁃0011⁃03Design of music player based on MCU STC12C5A60S2HE Xie, TANG Da⁃quan, ZHANG Shu⁃ting, CHEN Xue(Jiangyin Polytechnic College, Jiangyin, 214400, China)Abstract: The hardware design method of the music player based on MCU STC12C5A60S2 is introduced in this paper. The program design of the music player based on principle of FAT32 file system is studied. In the music player, MCU STC12C5A60S2 is taken as a main controller, SD card as a memory medium of music files and VS1003 chip as a decoder unit. When the player is running, MCU STC12C5A60S2 reads the music file from the SD card and continuously transfers data flow to VS1003 for decoding. In the meantime, the OLED liquid crystal display shows the message of the music in real time. The tested results from experiments show the music player can play the music files in multiple formats fluently if the player is connected with ear phone.Keywords: STC12C5A60S2; music player; FAT32 file system; program design随着电子科技的进步,在生活中人们越来越多的使用便携音乐播放器来欣赏音乐,这样的音乐播放器以MP3播放器为主流,小巧便携,但音质不佳,容量有限,且不能兼容播放多种格式音乐文件[1]。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于51单片机FAT32文件系统程序#ifndef __ZNFAT_H__#define __ZNFAT_H__#include "mytype.h" //类型重定义/*******************************************************///znFAT的裁减宏---------------------------------------------------------//#define ZNFAT_ENTER_DIR //有此宏,函数 znFAT_Enter_Dir() 参与编译#define ZNFAT_OPEN_FILE //有此宏,函数 znFAT_Open_File() 参与编译//#define ZNFAT_SEEK_FILE //有此宏,函数 znFAT_Seek_File() 参与编译//#define ZNFAT_READ_FILE //有此宏,函数 znFAT_Read_File() 参与编译//#define ZNFAT_READ_FILEX //有此宏,函数 znFAT_Read_FileX() 参与编译//#define ZNFAT_ADD_DAT //有此宏,函数 znFAT_Add_Dat() 参与编译//#define ZNFAT_CREATE_DIR //有此宏,函数 znFAT_Create_Dir() 参与编译//#define ZNFAT_CREATE_FILE //有此宏,函数 znFAT_Create_File() 参与编译//#define ZNFAT_DEL_FILE //有此宏,函数 znFAT_Del_File() 参与编译//#define ZNFAT_XCOPY_FILE //有此宏,函数 znFAT_XCopy_File() 参与编译//#define ZNFAT_RENAME_FILE //有此宏,函数 znFAT_Rename_File() 参与编译//#define ZNFAT_GET_TOTAL_SIZE //有此宏,函数 znFAT_Get_Total_Size() 参与编译//#define znFAT_GET_REMAIN_CAP //有此宏,函数 znFAT_Get_Remain_Cap() 参与编译#include "cj.h"#include "cj.h"//----------------------------------------------------------------------#define SOC(c) (((c-pArg->FirstDirClust)*(pArg->SectorsPerClust))+pArg->FirstDirSector) // 用于计算簇的开始扇区#define CONST const//设备表#define SDCARD 0 //SD卡#define UDISK 1 //U盘#define CFCARD 2 //CF卡#define OTHER 3 //其它//这里的存储设备表,可以灵活扩充,以实现对更多存储设备的支持//-------------------------------------------#define MAKE_FILE_TIME(h,m,s) ((((unsigned int)h)<<11)+(((unsigned int)m)<<5)+(((unsigned int)s)>>1))/* 生成指定时分秒的文件时间数据 */#define MAKE_FILE_DATE(y,m,d) (((((unsigned int)y)+20)<<9)+(((unsigned int)m)<<5)+((unsigned int)d))/* 生成指定年月日的文件日期数据 *///DPT:分区记录结构如下struct PartRecord{UINT8 Active; //0x80表示此分区有效UINT8 StartHead; //分区的开始磁头UINT8 StartCylSect[2];//开始柱面与扇区UINT8 PartType; //分区类型UINT8 EndHead; //分区的结束头UINT8 EndCylSect[2]; //结束柱面与扇区UINT8 StartLBA[4]; //分区的第一个扇区UINT8 Size[4]; //分区的大小//MBR:分区扇区(绝对0扇区)定义如下struct PartSector{UINT8 PartCode[446]; //MBR的引导程序struct PartRecord Part[4]; //4个分区记录UINT8 BootSectSig0; //55UINT8 BootSectSig1; //AA};//znFAT中对BPB的定义如下一共占用90个字节struct znFAT_BPB{UINT8 BS_jmpBoot[3]; //跳转指令 offset: 0 UINT8 BS_OEMName[8]; // offset: 3 UINT8 BPB_BytesPerSec[2];//每扇区字节数 offset:11 UINT8 BPB_SecPerClus[1]; //每簇扇区数 offset:13 UINT8 BPB_RsvdSecCnt[2]; //保留扇区数目 offset:14 UINT8 BPB_NumFATs[1]; //此卷中FAT表数 offset:16 UINT8 BPB_RootEntCnt[2]; //znFAT为0 offset:17 UINT8 BPB_TotSec16[2]; //znFAT为0 offset:19 UINT8 BPB_Media[1]; //存储介质 offset:21 UINT8 BPB_FATSz16[2]; //znFAT为0 offset:22 UINT8 BPB_SecPerTrk[2]; //磁道扇区数 offset:24 UINT8 BPB_NumHeads[2]; //磁头数 offset:26 UINT8 BPB_HiddSec[4]; //FAT区前隐扇区数 offset:28 UINT8 BPB_TotSec32[4]; //该卷总扇区数 offset:32 UINT8 BPB_FATSz32[4]; //一个FAT表扇区数 offset:36 UINT8 BPB_ExtFlags[2]; //znFAT特有 offset:40 UINT8 BPB_FSVer[2]; //znFAT特有 offset:42 UINT8 BPB_RootClus[4]; //根目录簇号 offset:44 UINT8 FSInfo[2]; //保留扇区FSINFO扇区数offset:48 UINT8 BPB_BkBootSec[2]; //通常为6 offset:50 UINT8 BPB_Reserved[12]; //扩展用 offset:52 UINT8 BS_DrvNum[1]; // offset:64 UINT8 BS_Reserved1[1]; // offset:65 UINT8 BS_BootSig[1]; // offset:66 UINT8 BS_VolID[4]; // offset:67 UINT8 BS_FilSysType[11]; // offset:71 UINT8 BS_FilSysType1[8]; //"znFAT " offset:82 };struct znFAT_FAT_Item{UINT8 Item[4];};struct znFAT_FAT{struct znFAT_FAT_Item Items[128];};struct direntryUINT8 deName[8]; // 文件名,不足部分以空格补充 UINT8 deExtension[3]; // 扩展名,不足部分以空格补充 UINT8 deAttributes; // 文件属性UINT8 deLowerCase; // 0UINT8 deCHundredth; // 世纪UINT8 deCTime[2]; // 创建时间UINT8 deCDate[2]; // 创建日期UINT8 deADate[2]; // 访问日期UINT8 deHighClust[2]; // 开始簇的高字UINT8 deMTime[2]; // 最近的修改时间UINT8 deMDate[2]; // 最近的修改日期UINT8 deLowCluster[2]; // 开始簇的低字UINT8 deFileSize[4]; // 文件大小};//znFAT初始化时初始参数装入如下结构体中struct znFAT_Init_Arg{UINT8 DEV_No;UINT8 BPB_Sector_No; //BPB所在扇区号UINT32 Total_Size; //磁盘的总容量UINT32 FirstDirClust; //根目录的开始簇UINT32 BytesPerSector; //每个扇区的字节数UINT32 FATsectors; //FAT表所占扇区数UINT32 SectorsPerClust; //每簇的扇区数UINT32 FirstFATSector; //第一个FAT表所在扇区UINT32 FirstDirSector; //第一个目录所在扇区};struct Date{UINT16 year;UINT8 month;UINT8 day;};struct Time{UINT8 hour;UINT8 min;UINT8 sec;};struct FileInfoStruct{UINT8 FileName[15]; //文件名UINT32 FileStartCluster; //文件的开始簇UINT32 FileCurCluster; //文件的当前簇UINT32 FileSize; //文件大小UINT32 FileCurSector; //文件的当前扇区UINT16 FileCurPos; //文件在当前扇区中的位置 UINT32 FileCurOffset; //文件的当前偏移量UINT32 Rec_Sec; //文件的文件/目录项所在的扇区UINT16 nRec; //文件的文件/目录项所在扇区中的位置UINT8 FileAttr; //文件属性struct Time FileCreateTime; //文件的创建时间struct Date FileCreateDate; //文件的创建日期struct Time FileMTime; //文件的修改时间struct Date FileMDate; //文件的修改日期struct Date FileADate; //文件的访问日期};struct FSInfo //znFAT的文件系统信息结构{UINT8 Head[4];UINT8 Resv1[480];UINT8 Sign[4];UINT8 Free_Cluster[4];UINT8 Last_Cluster[4];UINT8 Resv2[14];UINT8 Tail[2];};extern struct znFAT_Init_Arg *pArg; //初始化参数结构体指针,用以指向某一存储设备的初始化参数结构体,由外部提供extern UINT8 Dev_No;//设备号,外部变量//函数声明void znFAT_Device_Init();UINT32 znFAT_Get_Total_Size(void); //获取总容量UINT32 znFAT_Get_Remain_Cap(void); //获取剩余容量void znFAT_Init(void); //文件系统初始化UINT32 znFAT_Enter_Dir(CONST INT8 *path); //进入目录UINT8 znFAT_Open_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,UINT32 item,UINT8 is_file); //打开文件,支持通配UINT8 znFAT_Seek_File(struct FileInfoStruct *pfi,UINT32 offset); //文件定位UINT32 znFAT_Read_File(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,UINT8 *pbuf); //读取文件数据UINT32 znFAT_Read_FileX(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,void (*pfun)(UINT8)); //读取文件数据并进行数据处理UINT32 znFAT_Add_Dat(struct FileInfoStruct *pfi,UINT32 len,UINT8 *pbuf); //向文件追加数据UINT8 znFAT_Create_Dir(CONST INT8 *dirpath,UINT8 *ptd); //创建目录,支持创建时间UINT8 znFAT_Create_File(struct FileInfoStruct *pfi,CONST INT8 *filepath,UINT8 *ptd); //创建文件,支持创建时间UINT8 znFAT_Del_File(CONST INT8 *filepath); //删除文件unsigned char znFAT_XCopy_File(struct znFAT_Init_Arg *pArg1,struct znFAT_Init_Arg *pArg2,CONST INT8*sfilename,CONST INT8 *tfilename,UINT8 *file_buf,UINT32 buf_size,unsigned char *pt); //文件拷贝,支持多设备中文件互拷UINT8 znFAT_File_Close(struct FileInfoStruct *pfi); //文件关闭UINT8 znFAT_Rename_File(CONST INT8 *filename,CONST INT8 *newfilename); //文件重命名#endif#include "znfat.h"#include "sd.h" //存储设备的扇区读写驱动,这里是SD卡//#include "ch375.h" //存储设备的扇区读写驱动,这里是U盘//#include "cf.h" //存储设备的扇区读写驱动,这里是CF盘#include "string.h"//全局变量定义struct direntry temp_rec;INT8 temp_dir_name[13];UINT32 temp_dir_cluster;UINT32 temp_last_cluster;UINT8 znFAT_Buffer[512]; //扇区数据读写缓冲区,由外部提供/****************************************************************** - 功能描述:znFAT的存储设备初始化函数- 隶属模块:znFAT文件系统模块- 函数属性:外部(用于对存储设备进行初始化)- 参数说明:无- 返回说明:无- 注:在调znFAT其它函数之前,必须先对存储设备进行成功的初始化。