STC12-MP3
所属分类:单片机开发
开发工具:C/C++
文件大小:118KB
下载次数:14
上传日期:2013-02-03 14:10:47
上 传 者:
xuxygwl
说明: stc12c5a60s2 vs1003 程序,成功
(stc12c5a60s2 vs1003 program, success)
文件列表:
STC12-MP3 (0, 2012-03-04)
STC12-MP3\debug (0, 2012-03-04)
STC12-MP3\debug\Debug.c (546, 2012-02-20)
STC12-MP3\debug\Debug.h (969, 2012-01-18)
STC12-MP3\delay (0, 2012-03-04)
STC12-MP3\delay\delay.c (403, 2012-03-04)
STC12-MP3\delay\delay.h (150, 2011-12-12)
STC12-MP3\FAT (0, 2012-03-04)
STC12-MP3\FAT\FAT_FS.c (60310, 2012-03-05)
STC12-MP3\FAT\FAT_FS.h (2675, 2012-03-04)
STC12-MP3\FAT\fat_fs_log.txt (7913, 2012-02-16)
STC12-MP3\FAT\FileInfo.h (2264, 2012-03-04)
STC12-MP3\gpio (0, 2012-03-04)
STC12-MP3\gpio\gpio.c (1810, 2012-02-20)
STC12-MP3\gpio\gpio.h (358, 2011-11-22)
STC12-MP3\Interrupt (0, 2012-03-04)
STC12-MP3\Interrupt\interrupt.h (485, 2012-02-24)
STC12-MP3\main (0, 2012-03-04)
STC12-MP3\main\main.c (1656, 2012-03-05)
STC12-MP3\main\STARTUP.A51 (6376, 2010-09-03)
STC12-MP3\Memory (0, 2012-03-04)
STC12-MP3\Memory\memory.c (7489, 2012-03-04)
STC12-MP3\Memory\memory.h (526, 2012-03-04)
STC12-MP3\MMC_SD (0, 2012-03-04)
STC12-MP3\MMC_SD\MMC_SD.c (25993, 2012-03-04)
STC12-MP3\MMC_SD\MMC_SD.H (2809, 2012-01-20)
STC12-MP3\MMC_SD\mmc_sd_old_functions.h (4191, 2012-01-20)
STC12-MP3\power_rst (0, 2012-03-04)
STC12-MP3\power_rst\power_clk_rst.c (30, 2011-12-16)
STC12-MP3\power_rst\power_clk_rst.h (2227, 2012-02-20)
STC12-MP3\power_rst\power_clk_rst_test.c (6930, 2012-01-14)
STC12-MP3\proj (0, 2012-03-06)
STC12-MP3\proj\C51Test.plg (195, 2012-03-06)
STC12-MP3\proj\C51Test.uvgui.Pony (294485, 2012-03-06)
STC12-MP3\proj\C51Test.uvgui_Pony.bak (292507, 2012-03-06)
STC12-MP3\proj\C51Test.uvopt (23051, 2012-03-06)
STC12-MP3\proj\C51Test.uvproj (20811, 2012-03-05)
STC12-MP3\proj\C51Test_uvopt.bak (22867, 2012-03-06)
STC12-MP3\proj\C51Test_uvproj.bak (20475, 2012-03-05)
... ...
//注意:
//1. 现在只支持FAT32文件系统
//2. 硬盘碎片越少,文件系统的性能就越好
//3. 最好一次只打开一个文件
//4. 初始化文件系统前,要先初始化动态内存管理模块(这里是init_mempool(mem_pool, MEM_POOL_SIZE))
// (参考KEIL的库函数说明文档),
// 和初始化相应的函数设备
使用说明:
1.首先调用FileSysInit();
a. 注意在此之前请先初始化相应的存储设备,如果是基于SD卡,那么就初始化SD卡
b.文件系的代码采用了KEIL的动态内存管理机制,所以在调用FileSysInit之前还需要调用init_mempool函数
init_mempool函数的详细说明请参考KEIL的帮助文档
如果初始化失败(参考FileSysInit()的返回值说明,请不要继续使用文件系统里的其它函数,
并参考注意事项里的内容都已经被满足,如果还有问题,
那么,开启.c文件里的调试开关,即注释掉前面的#define NO_DEBUG
在串口调试助手中查看调试信息,如果还是找不出问题,那么我也不知道了。。。
2.声明File* p_file;
3.p_file = fopen("a.txt", FILE_READ); //打开文件a.txt,读模式
4.fread(p_file); 读取到的内容在RWbuffer中,fread返回读取到多少个字节,
fread的返回值一般为512,如果小于512,说明文件读完了,
这里的意思是说如果这次返回值小于512,那么下次再fread就返回0了,如果大于512,说明出现了错误
5.当你不再使用这个文件的时候,一定要调用fclose(p_file),这样可以腾出内存供其它目的使用
使用示例
#include
#include "FAT_FS.H"
#define MEM_POOL_SIZE 300 //用作动态内存的区域的大小
static u8 xdata mem_pool[MEM_POOL_SIZE];
u8* code name = "folder\\a.txt"; // '\\'是文件分隔符
void main()
{
u16 read_count;
File* p_file;
//初始化
//初始化动态内存
init_mempool(mem_pool, MEM_POOL_SIZE);
//初始化SD卡
while(SD_Init()); /* 等待SD卡初始化正确完成,NO_ERROR时返回为0 */
if(FileSysInit())
{ //如果初始化失败了,就不要进行下去了,你也可以在这里添加调试信息
while(1);
}
p_file = fopen(name, FILE_READ); //打开文件,读模式(暂不支持写。。。)
if(p_file == NULL)
while(1); //如果p_file == NULL,说明打开文件失败
read_count = fread(p_file); //读文件,内容将被读到RWbuffer数组中
while(read_count)
{
//对RWbuffer数组的内容进行处理
...
//处理完后继续读后面的内容
read_count = fread(p_file);
}
fclose(p_file); //不再使用文件,关闭文件
while(1); //处理完毕,停机
}
////////////////////////////以下为无用内容,纯粹是为了保留删除掉的函数的代码////////////////////////////
////////////////////////////以下为无用内容,纯粹是为了保留删除掉的函数的代码////////////////////////////
////////////////////////////以下为无用内容,纯粹是为了保留删除掉的函数的代码////////////////////////////
//说明:
// 将p_file指向的结构体的 next_cluster, next_sector_offset 更新到文件的下一个扇区
//参数:
// p_file 指向要被更新的对象
//返回:
// 0 成功
// 0xff 文件结束
// 其它 错误
//u8 SetNextSector(struct FileInfo* p_file)
//{
// //if(p_file->attribute & SUB_DIR)
// //{ //若是一个目录文件
// if(p_file->next_sector_offset == 7)
// { //如果现在在当前簇的最后一个扇区
// p_file->next_sector_offset = 0;
// return SetNextCluster(p_file);
//
// }
// else if(p_file->next_sector_offset < 7)
// {
// p_file->next_sector_offset++;
// return 0;
// }
// else //p_file->next_sector_offset > 7,错误
// {
// p_file->next_sector_offset = 0;
// DB_SendString("Set next sector error!");
// return 1;
// }
//
//}
//
//说明:
// 将p_file指向的结构体的next_cluster更新到文件的下一个簇
//参数:
// 指向要被更新的结构体
//返回:
// 0 成功
// 0xff 文件结束
// 其它 未定义错误
//u8 SetNextCluster(struct FileInfo* p_file)
//{
// u32 xdata sector_offset; //FAT1偏移扇区
// sector_offset = ((p_file->next_cluster << 2) >> 9); // * 4 / 512
// DB_SendString("FAT1 sector offset :");
// DB_SendDec(sector_offset);
//
// UpdateRBuffer(FAT1_address + sector_offset, 0);
//
// //(p_file->next_cluster << 2) & 0x1ff 等于 p_file->next_cluster*4%512
// p_file->next_cluster = GetDWord_S(RWbuffer,(p_file->next_cluster << 2) & 0x1ff);
// DB_SendString("\nsector bytes offset :");
// DB_SendDec((p_file->next_cluster << 2) & 0x1ff);
//
// if(p_file->next_cluster == 0x0fffffff)
// { //如果是结束标记
// DB_SendString("\ncluster end.\n");
// return 0xff;
// }
// else
// { //如果不是结束标记
// DB_SendString("\nSet next cluster succeed!\n");
// return 0;
// }
//}
//
//说明:
// 将文件的下一个扇区讲到缓冲RWbuffer
//参数:
// p_file, 提供当前扇区信息,函数执行后将被更新
//返回:
// 实际读取到的字节数(其实实际读取的都是512,只不过在中间文件就结束了,后面的就是未使用的了)
// 0xff 错误
//u16 FileNextSector(struct FileInfo* p_file)
//{
// u8 temp;
// u32 cluster;
// u8 sector;
// //struct FileInfo xdata temp_file;
//
// if((p_file->next_cluster == 0x0fffffff) || (p_file->next_pos == p_file->size))
// { //已在文件尾了
// DB_SendString("\nEnd of file.\n");
// return 0; //读到0个字节
// }
//
// //temp_file = *p_file; //仅仅是保存当前需要读的扇区的相关信息
// cluster = p_file->next_cluster;
// sector = p_file->next_sector_offset;
//
// //将当前扇区更新为文件的下一个扇区
// //因为这个函数可能要读FAT1到缓冲区,所以要放在UpdateRBuffer的前面
// temp = SetNextSector(p_file);
//
// temp = UpdateRBuffer(GetSectorAddr(cluster, sector), 1);
// if(temp)
// {
// DB_SendString("\nFile next sector Reading error!\n");
// DB_SendString("temp = ");
// DB_SendDec(temp);
// return 0xff;
// }
//
// if( ((p_file->size - p_file->next_pos) <= 512) && !(p_file->attribute & SUB_DIR) )
// { //不是目录且读到文件尾了
// //更新下一要读的位置
// p_file->next_pos = p_file->size; //下一要读的位置设置到文件尾
// DB_SendString("\nFile next sector read ");
// DB_SendDec(p_file->size - p_file->next_pos);
// DB_SendString("bytes.\n");
// return (p_file->size - p_file->next_pos );
// }
// else //if(!(p_file->attribute & SUB_DIR))//不是目录
// {
// //更新下一要读的位置
// DB_SendString("\nFile Next sector read 512 bytes.\n");
// p_file->next_pos += 512;
// return 512;
// }
// /* else
// { //是目录
// DB_SendString("\ndirectory read next 512 bytes.\n");
// return 512;
// } */
//}
////文件的当前位置的使用与标准C库里的有所不同,因为8051的内存实在太小,要不然缓存就可以大些,
////然后 就可以定义这个函数了。。。
////u32 FileRead(struct FileInfo, u8* buffer)
//
//
//
//说明:
// 将文件的第一个扇区读入缓存
//参数:
// p_file 为函数提供文件信息
//返回:
// 实际读到的字节数 <= 512
// 0xff 错误 //----------------------------------------------------------
//u16 FileFirstSector(struct FileInfo* p_file)
//{
// p_file->next_sector_offset = 0; //设置下一簇内扇区偏移为1
// p_file->next_cluster = p_file->cluster; //下一要读簇为首簇
// p_file->next_pos = 0; //下一要读的位置为0
//
// return FileNextSector(p_file);
//}
//说明:
// 读一个扇区到读缓存中
//参数:
// sector_address 扇区地址
// is_mandatory 0 表示效率优先,如果原缓存内容对应地址和参数sector_address相同
// ,那么就直接退出,返回0x80
// 非0,表示强制更新
//返回:
// 0x80 参数所给的地址与原缓存内容对应的物理地址相同,不更新缓冲区
// 0 更新成功
// 1 更新失败,buffer_addr将被设为0xffffffff,RWbuffer的内容未定义
static
u8 UpdateRBuffera(u32 sector_address, u8 is_mandatory) //update read buffer
{
if((sector_address == buffer_addr))
{
if(is_mandatory)
{
}
else
{
DB_SendString("\nNo need to Read sector ");
DB_SendDec(sector_address);
DB_SendString("\n It's already in the buffer.");
return 0x80;
}
}
DB_SendString("\nRead sector ");
DB_SendDec(sector_address);
DB_SendString("\n");
//is_mandatory 这个变量已经没用了,这里借来用作返回值 ^_^
is_mandatory = ReadSector(sector_address, RWbuffer);
if(is_mandatory) //如果更新buffer失败了
{
DB_SendString("\n read sector error.\n");
DB_SendString("SD_ReadSingleBlock return ");
DB_SendDec(is_mandatory);
buffer_addr = 0xffffffff;
return 1;
}
else //如果更新buffer成功了
{
DB_SendString("\n read sector succeed.\n");
buffer_addr = sector_address; //更新buffer_addr
return 0;
}
}
近期下载者:
相关文件:
收藏者: