随着计算机应用技术的飞速发展,移动存储设备得到了广泛的应用。其中CF(Compact Flash)卡诞生于1994年,是早推出的闪存卡,在众多产品中其普及率也。由于CF卡具有价格低廉、体积小、存储容量大、高速等特点,因此被广泛地应用于数码相机、PDA和笔记本电脑等当前十分热门的消费类电子产品中。CF卡在其他领域中也得到了广泛的应用。如本文所述内容就是将CF卡应用于动态脑电图系统中存储脑电信号。
由于CF卡中存储的脑电图信号要能够从PC机上读取出来,所以必须把脑电图信号以相应的文件格式存储。下面将介绍采用C8051F020微控制器控制CF卡的文件存储,并详细地介绍其软、硬件的设计。
1 C8051F020与CF卡的接口电路
C8051F020是完全集成的混合信号系统级MCU芯片,使用了Cygnal的高速、流水线结构以及与MCS-51指令集完全兼容的CIP-51微处理器内核,具有64条数字I/O引脚,片内有64KB可在系统编程的Flash存储器,有4 352B的片内RAM,片内有看门狗定时器、VDD监视器和温度传感器等;片内的JTAG调试电路允许使用安装在终应用系统上的产品MCU进行非侵入式、全速、在系统调试;其MCU都可在工业温度范围(-45℃-+85℃)内用2.7~3.6V的电压工作;端口I/O、RST和JTAG引脚都兼容5V的输入信号电压。C8051F020其他功能可参考文献。
CF卡有3种工作模式可供选择:I/O模式、存储器模式和IDE模式。CF卡的默认模式是存储器模式,使用也为普遍。如果使用存储器模式则不需要配置任何寄存器。每一种模式的电路连接各不相同。在I/O模式和存储器模式下,可以采用8位的访问方式,也可以采用16位的访问方式。本文所采用的是8位的存储器模式。
C8051F020的外部数据存储器接口(EMIF)可用于访问片外存储器和存储器映射的I/O器件。若设置EMIF的配置寄存器EMIOCF的PRTSEL位为'1',可使EMIF位于端口7、6、5、4;设置EMD2位为'1',可使EMIF工作于非复用方式;设置EMDl~0为'01',可使EMIF工作于不带块选择的分片方式。这样P7口就为数据线D0~D7,P6口为A0~A7,P5口为A8~A15,P4.6、P4.7分别为读(RD)、写(WE)线。
由于C8051F020是8位的单片机,所以对CF卡的访问采用8位的方式较为方便。通过把-CE2设为'1'即可通过访问CF卡的D0~D7来存取数据。而-CEl可以作为CF卡的片选信号,通过设-CEl为'0'来选通CF卡,即-CEl接C8051F020的高位地址P5.7来线选CF卡。当CF卡插入其插座时,CDl和CD2都连接到地(CND);C8051F020的P1.1、P1.2分别连到CDl和CD2,并可以通过检测P1.1和P1.2来判断CF卡是否插入CF卡插座。CF卡工作于存储器模式下,-OE和-WE分别接C8051F020的读(P1.6)、写(P1.7)线。当REG为'0'时,访问CF卡的属性寄存器;REG为'1'时,CF卡在存储器模式下对数据进行读写操作。
2 C8051F020对CF卡的数据读写
CF卡1个扇区为512B,这些数据都是从表1中的第0个寄存器中读出,而且每次读写数据为1个扇区,但也可以设置从第2个寄存器中读出,1次读写几个扇区。
C8051F020对CF卡读扇区数据的过程是:首先读取第7个寄存器的状态字,如果为50H表示没有错误,并且CF卡已经准备好;然后再分别向第2、3、4、5、6个寄存器写入相应的数据指定需要读写的扇区;向第7个寄存器写20H或21H,读取状态字为58H后读取数据。
C8051F020对CF卡向指定扇区写数据的命令是30H或31H,其操作亦与读数据相似,只不过在写入数据后要等到CF卡中数据稳定并进入空闲状态才能结束这一过程。
在CF卡读写时,分别向第2、3、4、5、6个寄存器写入CF卡需要访问的扇区位置,其写入模式有2种:即CHS(Cylinder/Head/Sector)模式和LBA(Logical Block Address)模式。通过设置第6个寄存器的第6位LBA确定其模式:即如果LBA=0,则为CHS模式;如果LBA=I,则为LBA模式。
其中LBA是逻辑块地址,Cn是柱面号,HpC是每个柱面的磁头数,Hn是磁头数,Sn是扇区号,SpH是每个磁头(簇)的扇区数。
3 CF卡的文件存储
FAT(File Allocation Table)文件系统产生于20世纪70年代末到80年代初,是微软的MS-DOS操作系统所支持的文件系统。目前FAT文件系统有3种类型:FATl2、FATl6和FAT32。它们的不同是在磁盘上实际的FAT结构中每个记录(Entry)所占的位数不同。FATl2占12位(1.5字节),FATl6占16位(2字节),FAT32占32位(4字节)。每一个记录中的数据都按照低字节在前、高字节在后排列。
在CF卡格式化时,首先要了解CF卡的容量等一系列信息。通过对CF卡写入命令ECH就可以读出1个扇区,其中包含了该CF卡的一些参数的信息,如容量、默认的柱面数、默认的磁头数、每个扇区的字节数、每个磁道的扇区数和CF卡上总的扇区数等。这为格式化CF卡提供了重要的数据。
在格式化后的CF卡中,FAT文件系统由如下4部分组成:
0区:保留区(引导区)。
1区:FAT区。
2区:根目录区(FAT32中存在的是浮动的FDT表)。
3区:文件、目录与数据区(下面简称数据区)。
引导区中包含了整个FAT文件系统的重要信息,即BPB(BIOS Parameter Block)。下面为BPB的几个重要数据结构:
在FAT32格式下,BPB﹒RootEntCnt为'0',因此RootDirSec总是为'0'。
如果BPB.FATSzl6不为'0',就可以根据下面公式计算数据区的个扇区地址。
FirstDataSec=BPB.ResvdSecCnt+(BPB.NumFATs*BPB.FATSzl6)+RootDirSec (4)
因此数据区所占用的扇区数:
DataSec=BPB.TotSecl6-FirstDataSec (5)
根目录的个扇区地址(在FATl2、FATl6下):
FirstRootDirSec=BPB.ResvdSecCnt+(BPB.NumFATs*BPB.FATSzl6)
如果BPB.FATSzl6为'0',则BPB.FATSz32一定不为'0',则有:
FirstDataSec=BPB.ResvdSecCnt+fBPB.NumFATs*BPB.FATSz32)+RootDirSec (6)
DataSec=BPB.TotSec32-FirstDataSec (7)
FirstRootDirSec=BPB.ResvdSecCnt+(BPB.NumFATs*BPB.FATSz32) (8)
如果CF卡有多个分区,则(3)~(8)式计算出的参数只是相对当前分区而言的,且数据区所占用的簇数为:
CntofClus=DataSec/BPB.SecPerClus (9)
在格式化CF卡时,根据CF卡容量的大小决定FAT数据结构中的一些参数,再由式(9)算出数据区总的簇数,并根据总簇数的大小确定FAT形式。一般来说,如果CntofClus<4 084簇,则可以格式化成FATl2的形式;如果≥4 084簇而<65 524簇,则可以格式化成FATl6的形式;如果≥65 524簇,则格式化成FAT32的形式。
若给定一个簇的序号N(N≥2),则在数据区对应该簇的个扇区序号为:
FirstSecofClus=((N-2)*BPB.SecPerClus)+FirstDataSec (10)
|
式(10)表示了FAT与数据区的对应关系。在FAT区每一个记录的位置与数据区中的一簇数据相对应,同时,这个记录又存储着下一簇序号,从而一个件在FAT区形成一个链表。至于每一簇的序号在FAT中的存储位置,可以根据格式化的形式(FATl2、FAT16、FAT32)确定。设每一记录占i个字节,则第N个记录在N×i的位置上。
文件的结束符在FATl2下为0xFFF,在FATl6下为0xFFFF,在FAT32下为0x0FFFFFFF。如果在写入时遇到损坏的簇,则在对应位置写损坏的标志(FATl2下为0xFF5FATl6下为0xFFF7,FAT32下为0x0FFFFFF7),并且在{表中跳过这一损坏的簇。在删除一个文件时,要把该文{在FAT区的链表全部写'0',释放空间。这样,该链表中所对应的数据区又可以被新的文件分配。 一个FAT的目录项或文件项通常占用32字节,并存储该目录或文件的相关信息。其数据结构如下
这个数据结构中12字节的名字是目录名还是文件名,由成员Attr决定。如果是目录Attr可设为10H;如果j文件,Attr可设为20H,也可以是几个属性的组合;如果为长文件名,Attr可设为OFH。有关详细的长文件名可参见文献。
成员FstClusHI和FstClusL0记录了文件簇数据对应FAT中的记录序号,簇的序号,从而可以根据链表查找下一簇数据。在FATl2和FATl6下,成员FstClusHI总为'0'。
4 讨论
本文只介绍了动态脑电图系统的有关文件存储的部分,C8051F020的功能并没有得到充分利用。实际上C8051F020还要完成系统的其他很多功能。用户可以根据自己系统的实际需要选择合适的单片机。本系统在设计时着重考虑系统的功耗、体积、速度等方面的因素,所以C8051F020采用非复用的方式,以求节省1片锁存器对低位地址的锁存。
CF卡在写入文件时,由于要记录24小时的脑电图信号。为了防止异常发生使文件写入失败,可以定时地更新FAT区该文件的记录链表和所存放文件数据结构的根目录区或数据区中该文件的大小。只有保存了这些信息,所写入的数据才能正常地读取。 此外,在写入文件时,如果遇到一个扇区写入失败,则整个簇都不能用。为此:(1)必须查找下一个未占用的簇,再把这一簇中已经正确写入的扇区中的数据复制到下一簇中。这样缓冲区中只要保存一个扇区的脑电信号就可以。(2)先对这一簇进行检测,确定没有错误后再向该簇写人数据。这种方法虽然比较简单,但占用系统的时间比较多,且在检测到没有错误后也不能完全保证下写入时不发生错误。所以种方法的可靠性要高。
实验证明,SanDisk和EagleTec等公司的不同容量的CF卡用于本系统中都能够正确地对采集到的脑电图信号进行存取。
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。