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; } }

近期下载者

相关文件


收藏者