4 软件实现
按照FAT16方式存储文件,是一个通用的解决方案。因为这样可以得到现有的DOS和 Windows系统的支持,但是代价是浪费一部分空间,也就是说存储效率下降了。为了改善这一情况,采用了改进的存储方法。就是先创建一个空文件,并根据需要为其分配一个大的存储空间,写入动作只是从尾部追加数据。这样就避免了很多小文件的产生,既可以充分利用存储空间,又可以使地址连续。
CF卡的读写是通过卡内的缓冲区进行的,不支持直接读写存储区域。缓冲区为一个FIFO结构,读写顺序进行,不支持随机存取,系统只能一次性地按顺序读完或写完所有一个或多个扇区。
设计时使用LBA方式访问CF卡比较方便,读写时只需要先在相应的寄存器写入LBA地址即可。要设定LBA方式,需访问驱动器/磁头寄存器。内存模式下部分寄存器译码如表3所列。
表3 内存模式下部分寄存器译码
REG |
A10 |
A9~A4 |
A3~A0 |
offset |
OE=0 |
WE=0 |
1 |
0 |
X |
0000 |
0 |
偶字节读 |
侧字节写 |
1 |
0 |
X |
0001 |
1 |
错误寄存器 |
特性寄存器 |
1 |
0 |
X |
0010 |
2 |
扇区数 |
扇区数 |
1 |
0 |
X |
0011 |
3 |
扇区号(LBA7~0) |
扇区号(LBA7~0) |
1 |
0 |
X |
0100 |
4 |
低柱面号(LBA15~8) |
低柱面号(LBA15~8) |
1 |
0 |
X |
0101 |
5 |
高柱面号(LBA23~16 |
高柱面号(LBA23~16) |
1 |
0 |
X |
0110 |
6 |
驱动器/磁头(LBA27~24) |
驱动器/磁头(LBA27~24) |
1 |
0 |
X |
0111 |
7 |
状态寄存器 |
命令寄存器 |
驱动器/磁头寄存器结构如下:
1 |
LBA |
1 |
DRV |
HS3 |
HS2 |
HS1 |
HS0 |
LBA—1为LBA方式,0为C/H/S(柱面/磁头/扇区)方式;DRV—选择驱动器0或驱动器1;HS3~HS0—LBA27~24,或为C/H/S方式的磁头号。
文件创建过程也就是针对FAT和FDT的读写过程。首先在 FDT中申请表项,创建文件名称、属性、起始簇号、文件大小等,然后修改FAT,分配数据空间,备份FAT。文件存储就是要先从FDT和FAT中获得文件的起始簇号和簇号链,即LBA 地址。然后,将此地址送给寄存器3、4、5、6(表3中的offset3、4、5、6),向扇区数寄存器填写读写数据所占的扇区个数,再向CF卡的命令寄存器写入操作的命令字,写操作30H,读操作20H。当写入命令或写入数据后要查询状态寄存器的状态,以判定CF卡是否准备就绪或写入成功。状态寄存器结构如下:
BUSY |
RDY |
DWF |
DSC |
DRQ |
CORR |
0 |
ERR |
各位的值为1时含义如下:
BUSY—CF卡记,此时不能接受其它命令;
RDY—卡可以接受命令;
DWF—写错误;
DSC—卡准备就绪;
DRQ—CF卡请求数据传送;
CORR—数据错误但被修正,不会终止多扇区读操作;
ERR—在上一命令以某种错误结束,可以在错误寄存器中查看错误类型。
下面以向CF卡写一个扇区数据为例,给出图4所示流程和C程序代码。
bit flag_1,flag_2;
void cfwr()
{
unsigned char status;
cfwr_comm(0xe0,0x00,0x00,0x6c);
//写参数命令,指向逻辑6c扇区
do{status=PBYTE[0x07]; //读状态寄存器
if((status & 0x01)==0x01)
flag_1=1; //若ERR=1,置出错标志,做相应处理
while(status!=0x58);
cfwr_dat(); //写入数据
do{status=PBYTE[0x07]; //读状态寄存器
if((status & 0x20)==0x20)
flag_2=1; //若DWF=1时,置出错标志,做相应处理
while(status!=0x50);
}
void cfwr_comm(unsigned char lba27,lba23,la15,lba7) //写参数命令函数
{PBYTE[0x02] 扇区数为1
PBYTE[0x03]=lba7;
PBYTE[0x04]=la15;
PBYTE[0x05]=lba23;
PBYTE[0x06]=lba27; //设定LBA方式
PBYTE[0x07]=0x30; //送写入命令30H
}
void cfwr_dat() //写数据函数
{unsigned int i,temp;
unsigned char xdata dat[512]; //dat[]存放一个扇区的数据
for (i=0;i<512;i++) //连续写512字节
{P1=P1 & 0xf8; //选中外部RAM
temp=dat[i];
P1++; //根据实际电路选择中CF卡
PBYTE[0x00]=temp;}
}
5 结论
笔者在湿度检测仪中,根据本文所介绍的方法,用CF卡向计算机转存数据,可以非常方便地对数据进行维护。
2/2 首页 上一页 1 2 |