基于c语言的文件系统FAT16操作源代码
ctring format 16进制

ctring format 16进制如果你想将16进制数格式化为字符串(CString)在C++中,你可以使用各种方法。
以下是几种常见的方法:使用sprintf函数:cpp#include <cstring>#include <iostream>int main() {unsigned int hexNumber = 0x1234;char buffer[10];sprintf(buffer, "%04X", hexNumber); // 使用%04X确保总是4位十六进制数CString hexString = CString(buffer);std::cout << hexString << std::endl;return 0;}使用CString的Format方法:cpp#include <afxwin.h> // 如果你使用的是MFCint main() {unsigned int hexNumber = 0x1234;CString hexString;hexString.Format(_T("%04X"), hexNumber); // 使用%04X确保总是4位十六进制数AfxMessageBox(hexString);return 0;}**使用C++11的std::hex和std::stringstream**:cpp#include <sstream>#include <iostream>#include <iomanip>int main() {unsigned int hexNumber = 0x1234;std::stringstream ss;ss << std::hex << std::setfill('0') << std::setw(4) << hexNumber;CString hexString = CString(ss.str().c_str());std::cout << hexString << std::endl;return 0;}以上三种方法都可以将16进制数转换为CString格式的字符串。
UltraEdit和 WinHex使用简介及十六进制转换说明.

用于新建一个文件,可以是一个Txt文件,也可以是十六进制文件,C、HTML等格式的文件;
用于打开一个文件;
关闭已打开文件;
保存正在编辑的文件;
打印文件;
打印预览;
插入一个分页符;
设置是否自动折行;
这个按钮上写个H,作用就是将文件转为十六进制文件;
4.保存为项目文件
如果我们经常要修改一些文件,可以将这些文件全部打开,然后保存为一个项目文件,以后只要打开这个项目文件,就自动打开了此项目下的所有文件。现在已打开了好几个文件,选择“Project”菜单下的“New Project/Workspace”,就能将这些文件保存为一个项目文件。以后可以直接打开所保存的项目文件进行编辑。
UltraEdit是一套功能强大的文本编辑器,可以编辑文字、Hex、ASCII码,可以取代记事本,内建英文单字检查、C++及VB指令突显,可同时编辑多个文件,而且即使开启很大的文件速度也不会慢。软件附有HTML Tag颜色显示、搜寻替换以及无限制的还原功能,一般大家喜欢用其来修改EXE或DLL文件,众多的游戏玩家喜欢用它来修改存盘文件或是可执行文件。
在Winhex中集成了强大的工具,包括磁盘编辑器,计算器,Hex转换器和RAM编辑工具,使用十分方便。按F9,弹出磁盘编辑器对话框,首先选择磁盘分区,然后按确定按钮就可以方便的对磁盘的空余空间进行清理。点击工具栏中的RAM编辑工具按钮,弹出RAM编辑器,选择需要浏览或编辑修改的RAM区,选择确定就可以了,RAM的内容就显示在主窗口了。在未登记注册的版本中,只能浏览而不能修改编辑RAM区域。按F8,弹出十六进制和十进制转换器,左边栏显示十六进制数字,右边栏显示十进制数字。如果你在左边输入十六进制数,按Enter其十进制结果就出现在右边的矩形框中了,反之亦然。如果你按组合键Alt+F8,弹出计算器,和Windows自带的计算器工具完全一样,相信你已经会使用,这里就不多说了。
Fatfs文件系统2015-04

2015-04-18FATFS文件管理系统一、FATFS简介FATFS 是一个完全免费开源的FAT 文件系统模块,专门为小型的嵌入式系统而设计。
它完全用标准 C 语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM 等系列单片机上而只需做简单的修改。
它支持FATl2、FATl6 和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8 位单片机和16 位单片机做了优化。
FATFS 的特点有:✧ 代码量少、效率高✧ 多种配置选项✧ 支持多卷(物理驱动器或分区,最多10 个卷)✧ 多个ANSI/OEM 代码页包括DBCS✧ 支持长文件名、ANSI/OEM 或Unicode✧ 支持RTOS✧ 支持多种扇区大小✧ 只读、最小化的API 和I/O 缓冲区等二、FATFS层次结构图最顶层是应用层,使用者无需理会FATFS 的内部结构和复杂的FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如f_open,f_read,f_write 和f_close 等,就可以像在PC 上读/写文件那样简单。
中间层FATFS 模块,实现了FAT 文件读/写协议。
FATFS 模块提供的是ff.c 和ff.h。
除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。
需要我们编写移植代码的是FATFS 模块提供的底层接口,它包括存储媒介读/写接口(disk I/O)和供给文件创建修改时间的实时时钟。
三、FATFS源码1.源码下载(1)在/fsw/ff/00index_e.html下载FatFs源码R0.10b版本;(2)打开压缩包,里面有doc和src两个文件夹,doc是对FatFs的一些介绍及更新说明,src为FatFs的源码;2.FatFs源码介绍(1)与硬件平台无关的文件✧ffconf.h FATFS 模块配置文件✧ff.h FATFS 和应用模块公用的包含文件✧ff.c FATFS 模块✧diskio.h FATFS 和disk I/O 模块公用的包含文件✧interger.h 数据类型定义✧option 可选的外部功能(比如支持中文等)(2) 与硬件平台相关的文件✧diskio.c FATFS 和disk I/O 模块接口层文件(3) 移植时,重要的选项配置✧_FS_TINY。
CRC16校验C语言程序源码-(附完整的可执行的C语言代码)

CRC16校验C语言程序源码(附完整的可执行的C语言代码)//CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的2种//实现方法进行测试。
方法一:查表法(256长度的校验表)速度快,准确,但是对于单片机设备存储占用大,且校验表长度大,输入时容易出现错误。
// ---------------- POPULAR POLYNOMIALS ----------------// CCITT: x^16 + x^12 + x^5 + x^0 (0x1021) // CRC-16: x^16 + x^15 + x^2 + x^0 (0x8005) #define CRC_16_POLYNOMIALS 0x8005const BYTE chCRCHTalbe[] = // CRC 高位字节值表{0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40};const BYTE chCRCLTalbe[] = // CRC 低位字节值表{0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,0x41, 0x81, 0x80, 0x40};WORD CRC16_1(BYTE* pchMsg, WORD wDataLen){BYTE chCRCHi = 0xFF; // 高CRC字节初始化BYTE chCRCLo = 0xFF; // 低CRC字节初始化WORD wIndex; // CRC循环中的索引while (wDataLen--){// 计算CRCwIndex = chCRCLo ^ *pchMsg++ ;chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex];chCRCHi = chCRCLTalbe[wIndex] ;}return ((chCRCHi << 8) | chCRCLo) ;}方法一:列表法(简单表)const WORD wCRCTalbeAbs[] ={0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400,};WORD CRC16_2(BYTE* pchMsg, WORD wDataLen){WORD wCRC = 0xFFFF;WORD i;BYTE chChar;for (i = 0; i < wDataLen; i++){chChar = *pchMsg++;wCRC = wCRCTalbeAbs[(chChar ^ wCRC) & 15] ^ (wCRC >> 4);wCRC = wCRCTalbeAbs[((chChar >> 4) ^ wCRC) & 15] ^ (wCRC >> 4);}return wCRC;}方法二:定义法根据CRC16/MODBUS原理直接计算,算法简单但对单片机计算压力大。
[解读]fat32文件长文件名
![[解读]fat32文件长文件名](https://img.taocdn.com/s3/m/6770eb1853ea551810a6f524ccbff121dd36c5d4.png)
FAT32文件长文件名转一段网上的文章,或许对你有用:================英文版长文件名实现================先用实例说明:在CF卡上保存一个名为“longname12345678901234567890.txt”的英文长文件名文件,用WinHEX读取盘片目录扇区,得到如下数据:0 1 2 3 4 5 6 7 8 9 A B C D E F------------------------------------------------43 39 00 30 00 2E 00 74 00 78 00 0F 00 F4 74 00 | C9.0...t.x...魌.00 00 FF FF FF FF FF FF FF FF 00 00 FF FF FF FF | ..02 36 00 37 00 38 00 39 00 30 00 0F 00 F4 31 00| .6.7.8.9.0...?..32 00 33 00 34 00 35 00 36 00 00 00 37 00 38 00 |2.3.4.5.6...7.8.01 6C 00 6F 00 6E 00 67 00 6E 00 0F 00 F4 61 00 | .l.o.n.g.n...鬭.6D 00 65 00 31 00 32 00 33 00 00 00 34 00 35 00 |m.e.1.2.3...4.5.4C 4F 4E 47 4E 41 7E 31 54 58 54 20 00 07 D6 99 | LONGNA~1TXT ..謾58 39 58 39 00 00 D7 99 58 39 00 00 00 00 00 00 | X9X9..讬X9......你会发现长文件名是倒着排放的(每目录项存13个字节文件名),最下面是短文件名LONGNA~1TXTFAT32的一个重要的特点是完全支持长文件名。
CRC16算法实现(C++MFC)

CRC16算法实现(C++MFC)//后加的函数,转换为十六进制的函数,以上结束int String2Hex(CString str, CByteArray &senddata) {int hexdata,lowhexdata;int hexdatalen=0;int len=str.GetLength();senddata.SetSize(len/2);for(int i=0;i{char lstr,hstr=str[i];if(hstr==' '){i++;continue;}i++;if(i>=len)break;lstr=str[i];hexdata=ConvertHexChar(hstr);lowhexdata=ConvertHexChar(lstr);if((hexdata==16)||(lowhexdata==16))break;elsehexdata=hexdata*16+lowhexdata;i++;senddata[hexdatalen]=(char)hexdata;hexdatalen++;}senddata.SetSize(hexdatalen);return hexdatalen;}char ConvertHexChar(char ch){if((ch>='0')&&(ch<='9'))return ch-0x30;else if((ch>='A')&&(ch<='F'))return ch-'A'+10;else if((ch>='a')&&(ch<='f'))return ch-'a'+10;elsereturn (-1);}//后加的函数,转换为十六进制的函数,到此结束void CCRC16Dlg::OnButton1() //进行数据转换按键{// TODO: Add your control notification handler code here UpdateData(TRUE); //读取编辑框内容//m_Receive=m_send;//测试用lenstr=String2Hex(m_send, senddata);//接收的字符转换成十六进制CByteArray类型Arraylen=senddata.GetSize();//CByteArray类型数组长度Receivedata.SetSize(Arraylen+2); //设置Receivedata数组的长度for(int i=0;i{Receivedata[i]=senddata[i];}//增加校验位*********/**cc='0xFF';//测试用的R1=0xF0FF;char c[2];c[0] = (R1 >> 8) & 0xff;c[1] = R1 & 0xff;Receivedata[Arraylen]=(R1 >> 8) & 0xff;Receivedata[Arraylen+1]=R1 & 0xff;**//*******生成CRC16 校验字节的步骤************************** 生成CRC16 校验字节的步骤如下:1、装入一个16 位寄存器,所有数位均为1;2、该16 位寄存器的低位字节与开始8 位字节数进行“异或”运算;3、把这个16 位寄存器向右移一位,高位补零;4、若向右移出的数位为1,则生成多项式1010000000000001(A001H)和这个寄存器进行“异或”运算,若向右移出的数位为0 则返回;5、重复3 和4,直至移出8 位;6、其余8 位字节数依次重复2—5 之运算直至结束;这个16 位寄存器即为2 字节的CRC 错误校验字节。
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++){。
AVR ATmega16 EEPROM读写程序源码

void delay(uint ms) //延迟函数 { uint i,j; for (i=0;i<ms;i++) for (j=0;j<1141;j++); } /********************************************************** LCD1602相关定义 **********************************************************/ void wr_com(uchar com) //写命令函数 { CTRL_PORT &=~BIT(0); CTRL_PORT &=~BIT(1); DATA_PORT =com; CTRL_PORT &=~BIT(2); delay(1); CTRL_PORT |=BIT(2); delay(1); } void wr_data(uchar data) { //写数据函数 //RS置0 //RW置1 //E置0 //E置1,产生上升沿,开始写入
第7页 共 9页
AVR ATmega16 EEPROM 读写程序
CTRL_PORT |=BIT(0); CTRL_PORT &=~BIT(1); DATA_PORT = data; CTRL_PORT &=~BIT(2); delay(1); CTRL_PORT |=BIT(2); delay(1); }
(3) EEPROM 控制寄存器- EECR
Bit
读/写 初始值
7
-
6
-
5
-
4
-
3
EERIE
2
EEMWE
1
EEWE
0
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
文件: FAT.H//微控设计网原创 作者: debug版主typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;#pragma pack(1)typedef struct{uint8 BS_jmpBoot[3];uint8 BS_OEMName[8];uint16 BPB_BytesPerSec;uint8 BPB_SecPerClus;uint16 BPB_RsvdSecCnt;uint8 BPB_NumFATs;uint16 BPB_RootEntCnt;uint16 BPB_TotSec16;uint8 BPB_Media;uint16 BPB_FATSz16;uint16 BPB_SecPerTrk;uint16 BPB_NumHeads;uint32 BPB_HiddSec;uint32 BPB_TotSec32;uint8 BS_DrvNum;uint8 BS_Reservedl;uint8 BS_BootSig;uint32 BS_VolID;uint8 BS_VolLab[11];uint8 BS_FilSysType[8];uint8 ExecutableCode[448];uint8 ExecutableMarker[2];} FAT_BPB;typedef struct{uint8 NAME[8];uint8 TYPE[3];} FILE_NAME;typedef struct{uint16 Start;uint32 Size;} FILE_POSIT;typedef struct{FILE_NAME FileName;uint8 FileAttrib;uint8 UnUsed[10];uint8 FileUpdateTime[2];uint8 FileUpdateData[2];FILE_POSIT FilePosit;} DIR;typedef struct{uint16 ClusID;uint16 SecOfClus;uint16 ByteOfSec;} DATA_POSIT;#pragma pack()//************************************************************************** //读一个扇区void ReadBlock(uint32 LBA);//************************************************************************** //写一个扇区void WriteBlock(uint32 LBA);//************************************************************************** void CopyBytes(void* S, void* D, uint16 size);//************************************************************************** uint8 IsEqual(void* A, void* B, uint8 Size);//************************************************************************* void EmptyBytes(void* D, uint16 size);//************************************************************************** //读取BPB数据结构void ReadBPB(void);//*************************************************************************** //获取根目录开始扇区号uint32 DirStartSec(void);//**************************************************************************** //获取数据区开始扇区号uint32 DataStartSec(void);//*************************************************************************** //目录项占用的扇区数uint16 GetDirSecCount(void);//**************************************************************************** //获取一个簇的开始扇区uint32 ClusConvLBA(uint16 ClusID);//**************************************************************************** //读取文件分配表的指定项uint16 ReadFAT(uint16 Index);//****************************************************************************//写文件分配表的指定项void WriteFAT(uint16 Index, uint16 Value);//**************************************************************************//获取根目录中可以使用的一项uint16 GetEmptyDIR(void);//****************************************************************************//获得和文件名对应的目录项uint8 GetFileID(uint8 Name[11], DIR* ID);//***************************************************************************//获取一个空的FAT项uint16 GetNextFAT(void);//****************************************************************************//读取根目录的指定项void ReadDIR(uint16 Index, DIR* Value);//****************************************************************************//写根目录的指定项void WriteDIR(uint16 Index, DIR* Value);//****************************************************************************//创建一个空文件void CreateFile(uint8* FileName[11], uint32 Size);//************************************************************************//复制文件分配表,使其和备份一致void CopyFAT(void);//****************************************************************************//操作文件的数据void OperateFile(uint8 Write ,uint8 Name[11], uint32 Start, uint32 Length, void* Data); //-------------------------------------------------------------------------------文件:FAT.C//微控设计网原创 作者: debug版主#include <stdio.h>#include "FAT16.h"uint8 BUFFER[512];uint16 BPB_BytesPerSec;uint8 BPB_SecPerClus;uint16 BPB_RsvdSecCnt;uint8 BPB_NumFATs;uint16 BPB_RootEntCnt;uint16 BPB_TotSec16;uint16 BPB_FATSz16;uint32 BPB_HiddSec;//******************************************************************************** //读一个扇区void ReadBlock(uint32 LBA)//******************************************************************************** {return;}//******************************************************************************** //写一个扇区void WriteBlock(uint32 LBA)//******************************************************************************** {return;}//******************************************************************************** void CopyBytes(void* S, void* D, uint16 size)//******************************************************************************** {uint8 *s = S, *d = D;uint16 i;for(i = 0; i < size; i++)*d++ = *s++;}//********************************************************************************* uint8 IsEqual(void* A, void* B, uint8 Size)//**********************************************************************************uint8 i, *a = A, *b = B;for(i = 0; i < Size; i++)if(a[i] != b[i])return 0;return 1;}//*********************************************************************************** void EmptyBytes(void* D, uint16 size)//*********************************************************************************** {uint16 i;uint8* data = (uint8*)D;for(i = 0; i < size; i++){*data++ = 0;}}//**********************************************************************************//读取BPB数据结构void ReadBPB(void)//*********************************************************************************** {FAT_BPB* BPB = (FAT_BPB*)BUFFER;ReadBlock(0);//获取参数BPB_BytesPerSec = BPB->BPB_BytesPerSec;BPB_SecPerClus = BPB->BPB_SecPerClus;BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt;BPB_NumFATs = BPB->BPB_NumFATs;BPB_RootEntCnt = BPB->BPB_RootEntCnt;BPB_TotSec16 = BPB->BPB_TotSec16;BPB_FATSz16 = BPB->BPB_FATSz16;BPB_HiddSec = BPB->BPB_HiddSec;}//************************************************************************************* //获取根目录开始扇区号uint32 DirStartSec(void)//************************************************************************************* {return BPB_RsvdSecCnt + BPB_NumFATs * BPB_FATSz16;//************************************************************************************ //获取数据区开始扇区号uint32 DataStartSec(void)//************************************************************************************ {return (uint32)(DirStartSec() + BPB_RootEntCnt * 32 / BPB_BytesPerSec);}//************************************************************************************ //目录项占用的扇区数uint16 GetDirSecCount(void)//************************************************************************************ {return BPB_RootEntCnt * 32 / 512;}//************************************************************************************ //获取一个簇的开始扇区uint32 ClusConvLBA(uint16 ClusID)//************************************************************************************* {return DataStartSec() + BPB_SecPerClus * (ClusID - 2);}//************************************************************************************* //读取文件分配表的指定项uint16 ReadFAT(uint16 Index)//*********************************************************************************** {uint16 *RAM = (uint16*)BUFFER;ReadBlock(BPB_RsvdSecCnt + Index / 256);return RAM[Index % 256];}//*********************************************************************************** //写文件分配表的指定项void WriteFAT(uint16 Index, uint16 Value)//*********************************************************************************** {uint16 *RAM = (uint16*)BUFFER;uint32 SecID;SecID = BPB_RsvdSecCnt + Index / 256;ReadBlock(SecID);RAM[Index % 256] = Value;WriteBlock(SecID);}//*********************************************************************************** //获取根目录中可以使用的一项uint16 GetEmptyDIR()//*********************************************************************************** {uint16 DirSecCut, DirStart, i, m, ID = 0;DirSecCut = GetDirSecCount();DirStart = DirStartSec();for(i = 0; i < DirSecCut; i++){ReadBlock(DirStart + i);for(m = 0; m < 16; m++){if((BUFFER[m * 32] == 0) || (BUFFER[m * 32] == 0xe5))return ID;elseID++;}}return ID;}//************************************************************************************ //获得和文件名对应的目录项uint8 GetFileID(uint8 Name[11], DIR* ID)//************************************************************************************ {uint16 DirSecCut, DirStart, i, m;DirSecCut = GetDirSecCount();DirStart = DirStartSec();for(i = 0; i < DirSecCut; i++){ReadBlock(DirStart + i);for(m = 0; m <16; m++){if(IsEqual(Name, &((DIR*)&BUFFER[m * 32])->FileName, 11)){*ID = *((DIR*)&BUFFER[m * 32]);return 1; //找到对应的目录项,返回1.}}}return 0; //没有找到对应的目录项,返回0.}//************************************************************************************** //获取一个空的FAT项uint16 GetNextFAT(void)//************************************************=************************************* {uint16 FAT_Count, i;FAT_Count = BPB_FATSz16 * 256; //FAT表总项数for(i = 0; i < FAT_Count; i++){if(ReadFAT(i) == 0)return i;}return 0;}//************************************************************************************** //读取根目录的指定项void ReadDIR(uint16 Index, DIR* Value)//************************************************************************************ {uint32 DirStart = DirStartSec();ReadBlock(DirStart + Index / 16);CopyBytes(&BUFFER[(Index % 16) * 32], Value, 32);}//************************************************************************************* //写根目录的指定项void WriteDIR(uint16 Index, DIR* Value)//************************************************************************************* {uint32 LBA = DirStartSec() + Index / 16;ReadBlock(LBA);CopyBytes(Value, &BUFFER[(Index % 16) * 32], 32);WriteBlock(LBA);}//************************************************************************************* //创建一个空文件void CreateFile(uint8* FileName[11], uint32 Size)//************************************************************************************* {uint16 ClusID, ClusNum, ClusNext, i;DIR FileDir;ClusNum = Size / (BPB_SecPerClus * 512) + 1;EmptyBytes(&FileDir, sizeof(DIR));CopyBytes(FileName, &FileDir.FileName, 11);FileDir.FilePosit.Size = Size;FileDir.FilePosit.Start = GetNextFAT();ClusID = FileDir.FilePosit.Start;for(i = 0; i < ClusNum - 1; i++){WriteFAT(ClusID, 0xffff);ClusNext = GetNextFAT();WriteFAT(ClusID, ClusNext);ClusID = ClusNext;}WriteFAT(ClusID, 0xffff);WriteDIR(GetEmptyDIR(), &FileDir);}//************************************************************************************ //复制文件分配表,使其和备份一致void CopyFAT(void)//************************************************************************************ {uint16 FATSz16, RsvdSecCnt, i;FATSz16 = BPB_FATSz16;RsvdSecCnt = BPB_RsvdSecCnt;for(i = 0; i < FATSz16; i++){ReadBlock(RsvdSecCnt + i);WriteBlock(RsvdSecCnt + FATSz16 + i);}}//************************************************************************************* //操作文件的数据void OperateFile(uint8 Write ,uint8 Name[11], uint32 Start, uint32 Length, void* Data) //************************************************************************************* {uint8 *data = Data;uint16 BytePerClus, SecPerClus, ClusNum, ClusID, m;uint32 LBA, i;DIR FileDir;SecPerClus = BPB_SecPerClus;BytePerClus = BPB_SecPerClus * 512; // 每簇的字节数GetFileID(Name, &FileDir);//计算开始位置所在簇的簇号ClusNum = Start / BytePerClus;ClusID = FileDir.FilePosit.Start;for(i = 0; i < ClusNum; i++)ClusID = ReadFAT(ClusID);//计算开始位置所在扇区簇内偏移i = (Start % BytePerClus) / 512;//计算开始位置扇区内偏移m = (Start % BytePerClus) % 512;LBA = ClusConvLBA(ClusID) + m;if(Write)ReadBlock(LBA);elseReadBlock(LBA++);goto Start;while(1){ClusID = ReadFAT(ClusID); //下一簇簇号LBA = ClusConvLBA(ClusID);for(i = 0; i < SecPerClus; i++){if(Write)ReadBlock(LBA);elseReadBlock(LBA++);for(m = 0; m < 512; m++){Start:if(Write)BUFFER[m] = *data++;else*data++ = BUFFER[m];//如果读取完成就退出if(--Length == 0){if(Write)WriteBlock(LBA); //回写扇区return;}}if(Write)WriteBlock(LBA++); //回写扇区,指针下移}}}//--------------------------------------------------------------------------------------11。