📄 fat.lst
字号:
C51 COMPILER V7.20 FAT 11/03/2007 17:08:48 PAGE 1
C51 COMPILER V7.20, COMPILATION OF MODULE FAT
OBJECT MODULE PLACED IN .\output\fat.obj
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE src\lib\fat.c LARGE ORDER INCDIR(.\src\include) DEBUG OBJECTEXTEND PRINT(.\
-output\fat.lst) OBJECT(.\output\fat.obj)
line level source
1 //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fat文件系统函数&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2 //*文件名称:fat.c
3
4 //*文件作用:fat文件系统函数
5
6 //*文件作者:翟 鹏
7
8 //*创建日期:2005年5月
9 //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
10
11
12
13 #include <include.h>
14
15
16
17 static ulong xdata DiskStart=0;//逻辑盘的起始绝对扇区号LBA
18 static uchar xdata SecPerClus;//逻辑盘的每簇扇区数
19 static uchar xdata RsvdSecCnt;//逻辑盘的保留扇区数
20 static uint xdata FATSz16;//FAT16逻辑盘的FAT表占用的扇区数
21 static ulong data position=0;//文件偏移量
22
23
24 uchar fat_init(void)
25 {
26 1 uchar data temp;
27 1
28 1 //初始化SD卡
29 1 if(SD_Init())return 1;
30 1 //读取逻辑引导扇区标志 判断是不是逻辑引导扇区
31 1 SD_Set_SectorAddr(0);
32 1 if(SD_Read_SectorByte(0,&temp))return 2;
33 1 //如果不是逻辑引导扇区 提取逻辑引导扇区号
34 1 if(temp!=0xEB && temp!=0xE9)
35 1 {
36 2 if(SD_Read_SectorByte(0x1C6,&temp))return 2;
37 2 DiskStart=temp;
38 2 if(SD_Read_SectorByte(0x1C7,&temp))return 2;
39 2 DiskStart|=(uint)temp<<8;
40 2 if(SD_Read_SectorByte(0x1C8,&temp))return 2;
41 2 DiskStart|=(ulong)temp<<16;
42 2 if(SD_Read_SectorByte(0x1C9,&temp))return 2;
43 2 DiskStart|=(ulong)temp<<24;
44 2 }
45 1 //是逻辑引导扇区 逻辑引导扇区号=0
46 1 else
47 1 {
48 2 DiskStart=0;
49 2 }
50 1
51 1 //提取逻辑盘参数
52 1 SD_Set_SectorAddr(DiskStart);
53 1 if(SD_Read_SectorByte(0x0D,&temp))return 3;SecPerClus=temp;//每簇扇区数
54 1 if(SD_Read_SectorByte(0x0E,&temp))return 3;RsvdSecCnt=temp;//逻辑盘的保留扇区数
C51 COMPILER V7.20 FAT 11/03/2007 17:08:48 PAGE 2
55 1 if(SD_Read_SectorByte(0x16,&temp))return 3;FATSz16=(uint)temp;//FAT表占用扇区数
56 1 if(SD_Read_SectorByte(0x17,&temp))return 3;FATSz16|=(uint)temp<<8;//FAT表占用扇区数
57 1
58 1 return 0;
59 1 }
60
61 uint fopen(uchar *file_name, uchar *open_flag)
62 {
63 1 uchar data temp;
64 1 uint data StartCluster=0xFFFF;//文件的首簇
65 1 uchar data sector;
66 1
67 1 if(*open_flag=='r' && *open_flag=='w')return 0xFFFF;
68 1
69 1 //读取FAT16逻辑盘的根目录,寻找文件 通常根目录占用32个扇区
70 1 for(sector=0;sector<SecPerClus;sector++)
71 1 {
72 2 uint CurrentDir;
73 2
74 2 dog();
75 2
76 2 //遍历当前扇区
77 2 SD_Set_SectorAddr(DiskStart+RsvdSecCnt+FATSz16*2+sector);
78 2 for(CurrentDir=0;CurrentDir<512;CurrentDir+=32)
79 2 {
80 3 if(SD_Read_SectorByte(CurrentDir+0,&temp))return 0xFFFF;
81 3 if(temp==0)break;//目录结束了 跳出循环
82 3 if(temp!=0xE5)//文件没有被删除
83 3 {
84 4 if(SD_Read_SectorByte(CurrentDir+0x0B,&temp))return 0xFFFF;
85 4 if((temp&0x08)==0)//正常已知文件
86 4 {
87 5 uchar data i;
88 5
89 5 //比较文件名
90 5 for(i=0;i<11;i++)
91 5 {
92 6 if(SD_Read_SectorByte(CurrentDir+i,&temp))return 0xFFFF;
93 6 #ifdef DEBUG
DEBUG_SEND_CHAR(temp);
#endif
96 6 if(temp!=file_name[i])break;
97 6 }
98 5 #ifdef DEBUG
DEBUG_SEND_STR("\r\n");
#endif
101 5
102 5 //文件找到 提取文件的首簇
103 5 if(i==11)
104 5 {
105 6 if(SD_Read_SectorByte(CurrentDir+0x1A,&temp))return 0xFFFF;
106 6 StartCluster =(uint)temp;
107 6 if(SD_Read_SectorByte(CurrentDir+0x1B,&temp))return 0xFFFF;
108 6 StartCluster |=(uint)temp<<8;
109 6 if(StartCluster!=0xFFFF)return StartCluster;
110 6 }
111 5 }
112 4 }
113 3 }
114 2 }
115 1
116 1 if(StartCluster!=0xFFFF)return StartCluster;
C51 COMPILER V7.20 FAT 11/03/2007 17:08:48 PAGE 3
117 1
118 1 return 0xFFFF;
119 1 }
120
121
122 void fseek(ulong offset)
123 {
124 1 position=offset;
125 1 }
126
127 uchar fread(char *buf, uint length, uint fp)
128 {
129 1 uchar data temp;
130 1 uint data ClusterOffset=fp+(position>>9)/SecPerClus;
131 1
132 1
133 1 //显示文件所有内容
134 1 while(ClusterOffset<=0xFFEF && length)
135 1 {
136 2 //计算当前簇的开始扇区
137 2 ulong data ClusterStartSector=DiskStart+RsvdSecCnt+FATSz16*2+32+(ulong)(ClusterOffset-2)*SecPerClus;
138 2 //计算当前簇内的扇区偏移量
139 2 uint data SectorOffset=(position>>9)%SecPerClus;
140 2 //循环读取32个扇区的循环变量
141 2 uchar data sector;
142 2
143 2 dog();
144 2
145 2 //判断文件为空文件
146 2 if(ClusterOffset==0)return 1;
147 2
148 2 //读取当前簇的 SecPerClus个扇区
149 2 for(sector=SectorOffset;sector<SecPerClus;sector++)
150 2 {
151 3 //当前扇区内的字节偏移量
152 3 uint data ByteOffset=position%512;
153 3 //当前扇区内的数据长度
154 3 uint data count=512-ByteOffset;
155 3
156 3 //长度不够一个扇区
157 3 if(length<count)count=length;
158 3
159 3 //读取扇区内的数据
160 3 SD_Set_SectorAddr(ClusterStartSector+sector);
161 3 if(SD_Read_Sector_Offset(ByteOffset,buf,count))return 2;
162 3 //写入和读取的位置都向后移动
163 3 buf+=count;
164 3 position+=count;
165 3 length-=count;
166 3 if(length==0)return 0;
167 3 }
168 2 //获取链接簇
169 2 SD_Set_SectorAddr(DiskStart+RsvdSecCnt+(ClusterOffset>>8));
170 2 if(SD_Read_SectorByte(ClusterOffset+ClusterOffset,&temp))return 3;
171 2 ClusterOffset=(uint)temp;
172 2 if(SD_Read_SectorByte((ClusterOffset+ClusterOffset)+1,&temp))return 4;
173 2 ClusterOffset|=(uint)temp<<8;
174 2 }
175 1
176 1 return 0;
177 1 }
178
C51 COMPILER V7.20 FAT 11/03/2007 17:08:48 PAGE 4
179
180
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1442 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 8 15
PDATA SIZE = ---- ----
DATA SIZE = 4 20
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -