51單片機如何實(shí)現對CF卡的讀寫(xiě)
由于CF卡(Compact Flash Card)具有容量大、體積小、高性能、攜帶方便等優(yōu)點(diǎn),而且讀寫(xiě)速度快,可與多種電腦操作系統平臺兼容,因此在數據采集系統中的數據記錄或與PC機之間的數據轉存多采用CF卡。為了在PC機中能方便地進(jìn)行數據處理,在下位機端必須采用一種標準的格式組織數據,即將數據按照Windows標準文件格式寫(xiě)入,在PC機端通過(guò)讀卡器將寫(xiě)入CF的內容以標準文件形式讀出。Windows標準文件格式有FAT、FAT32和NTFS??紤]到廣泛使用的Windows 98系統的CF卡的容量等因素,通常采用FAT(File Allocation Table)文件系統。單片機系統對CF卡的讀寫(xiě),就是從底層對它進(jìn)行直接操作,包括尋址、創(chuàng )建文件和讀寫(xiě)等。
1 CF卡簡(jiǎn)介
CF卡內集成了控制器、Flash Memory陣列和讀寫(xiě)緩沖區,如圖1所示。內置的智能控制器,使外圍電路設計大大簡(jiǎn)化,而且完全符合PC機內存卡的國際聯(lián)合會(huì )PCMCIA(Personal Computer Memory Card International Association)和ATA(Advanced Technology Attachment)接口規范。實(shí)際上,控制器起到了一種協(xié)議轉換的作用,即將對Flash Memory的讀寫(xiě)轉化成了對控制器的訪(fǎng)問(wèn),這樣不同的CF卡都可以用單一的機構來(lái)讀寫(xiě),而不用擔心兼容性問(wèn)題。CF卡的緩沖區結構,使得外部設備與CF卡通信的同時(shí),CF卡的片內控制器可以對Flash進(jìn)行讀寫(xiě)。這種設計可以增加CF卡數據讀寫(xiě)的可靠性,同時(shí)提高數據傳輸速率。
CF卡支持多種接口訪(fǎng)問(wèn)模式,有符合PCMCIA規范的Memory Mapped模式、I/O Card模式和符合ATA規范的True IDE模式。上電時(shí),OE(9腳)為低電平,CF卡進(jìn)入True IDE模式,此時(shí)引腳OE也叫ATA SEL;上電時(shí),OE(9腳)為高電平,CF卡進(jìn)入PCMCIA模式,即Memory Mapped模式或I/O Card模式,此時(shí)可通過(guò)修改配置選項寄存器進(jìn)入相應的模式。
配置選項寄存器格式如下:
SRESET | LevelREQ | conf5 | conf4 | conf3 | conf2 | conf1 | conf0 |
SRESET—軟復位信號;
Level REQ—中斷模式選擇(電平或邊沿觸發(fā))。
例如,要加入Memory mapped模式,只需要在上電時(shí)保證OE為高電平,因為配置選項寄存器的conf5~conf0位的初始化值為“00000”;而要進(jìn)入I/O Card模式,除了上電時(shí)保證OE為高電平外,還要進(jìn)一步設置conf5~conf0,如表1所列。但是對于具體型號的CF卡而言,下面三種情況也是被CFA(CF card Association)所允許的:①上電時(shí)進(jìn)入True IDE模式,工作過(guò)程中,只要監測到OE變?yōu)楦?,就退出True IDE模式;②允許卡在復位時(shí)重新配置;③上電時(shí)進(jìn)入PCMCIA模式,允許過(guò)程中,只要監測到OE變?yōu)榈?,就進(jìn)入True IDE模式。
表1 模式選擇
conf5 | conf4 | conf3 | conf2 | conf1 | conf0 | ?!∈?/TD> |
0 | 0 | 0 | 0 | 0 | 0 | Memory map |
0 | 0 | 0 | 0 | 0 | 1 | I/O Mapped,對應16位系統 |
0 | 0 | 0 | 0 | 1 | 0 | I/O,對應1F0h-1F7h/3F6h-3F3h |
0 | 0 | 0 | 0 | 1 | 1 | I/O,對應170h-177h/376h-377h |
2 CF卡與51單片機的接口
CF卡在PC Memory方式與51芯片的接口電路如圖2所示。由于采用CF卡上電后自動(dòng)進(jìn)入的Memory模式,而且不存在對特性寄存器的讀寫(xiě),故可將REG接高電平。片選信號CE1和CE2組合可選擇數據位寬度,如表2所列。圖2中CE2接VCC,選用的是8位(D7~D0)數據寬度。
表2 數據寬度選擇
8位(D7~D0) | 8位(D15~D8) | 16位 | 高 阻 | |
CE1 | 0 | 1 | 0 | 1 |
CE2 | 1 | 0 | 0 | 1 |
為了實(shí)現即插即用的功能,CE卡上提供了兩個(gè)用來(lái)檢測卡是否存在的引腳(CD1、CD2),由卡內部接地。當主機檢測到與其相連的CD1和CD2兩個(gè)引腳同時(shí)為低電平時(shí),可判斷出卡與主機相連;否則,卡未與主機相連。
由于I/O口緊張,RDY/BSY引腳懸空不用,通過(guò)查詢(xún)狀態(tài)寄存器能判斷CF卡是否準備就緒。在實(shí)際應用中,由于一次至少要讀寫(xiě)一個(gè)扇區512字節,所以要擴充一塊RAM。我們選用的是62256,容量為32KB,這樣便可以支持大到2GB的CF卡(參見(jiàn)下文),增加了其擴展性。
[next]
3 FAT文件系統
FAT文件系統是基于DOS的文件系統。常說(shuō)的FAT有12位的FAT12和16位的FAT16,另外就是32位的FAT32??紤]到CF卡的容量有限,宜選用FAT16。這里只對FAT文件系統作一簡(jiǎn)單介紹,更詳細的內容請見(jiàn)參考文獻。
磁盤(pán)的尋址方式有兩種:物理尋址C/H/S(柱面/磁頭/扇區)方式和邏輯塊LBA(Logical Block Addressing)尋址方式。二者之間的轉換關(guān)系為:
LBA地址=(柱面號×磁頭數+磁頭號)×扇區數+扇區數-1
采用LBA尋址方式,沒(méi)有磁頭和磁道的轉換操作,在訪(fǎng)問(wèn)連續的扇區時(shí),操作速度比物理尋址方式要快,而且也簡(jiǎn)化了對磁盤(pán)的訪(fǎng)問(wèn)。
硬盤(pán)的結構布局分為MBR(主引導扇區)和最多4個(gè)邏輯分區(含DOS分區或非DOS分區),而在DOS邏輯分區中的磁盤(pán)組織如下:
引導扇區 | FAT1 | FAT2 | 根目標區 | 數據區 |
引導扇區DBR(DOS Boot Record):位于LBA 0扇區,包含跳轉指令、廠(chǎng)商標識和DOS版本號、BPB(BIOS Parameter Block,BIOS參數塊)、DOS引導程序、結束標志字AA55。其中BPB包含每扇區字節數、每簇扇區數、每個(gè)FAT扇區數、扇區總線(xiàn)、根目錄項數等等參數。
FAT是給每個(gè)文件分配磁盤(pán)物理空間的表格。FAT16簇數的上限是2 16,即65536個(gè),每簇扇區數的上限是64個(gè),因此其分區空間的上限為2G。FAT1位于邏輯1扇區。FAT簇映射中,0000表示空簇,FFF0~FFF6備用,FFF8~FFFF表示簇鏈結束,FFF7表示壞簇,其余值表示其后續簇的簇號。圖3所示的文件起始簇號為2,結束簇號為4,共占用2、3、4三個(gè)簇。
簇是存儲文件的最小單位,可以包含多個(gè)扇區。當文件本身或文件的最后一簇哪怕只有1個(gè)字節,也要占去1簇。這樣,當這種文件很多時(shí),空間的浪費是很可觀(guān)的。
文件目錄表FDT(File Directory Table)是操作系統尋找文件的入口,其內容是每一個(gè)文件的目錄。FDT中的每一個(gè)目錄項由32個(gè)字節組成。前8個(gè)字節是文件名,不足時(shí)用空格填滿(mǎn)。緊跟著(zhù)的3個(gè)字節是文件擴展名,接下來(lái)是10個(gè)字節的系統保留字。然后是文件產(chǎn)生的時(shí)刻和日期占8個(gè)字節,再后的2個(gè)字節是文件首簇號,最后4個(gè)字節是文件大小。FDT的起始扇區可由FAT的大小計算出,而FAT的大小可在DBR中讀出。
4 軟件實(shí)現
按照FAT16方式存儲文件,是一個(gè)通用的解決方案。因為這樣可以得到現有的DOS和Windows系統的支持,但是代價(jià)是浪費一部分空間,也就是說(shuō)存儲效率下降了。為了改善這一情況,采用了改進(jìn)的存儲方法。就是先創(chuàng )建一個(gè)空文件,并根據需要為其分配一個(gè)大的存儲空間,寫(xiě)入動(dòng)作只是從尾部追加數據。這樣就避免了很多小文件的產(chǎn)生,既可以充分利用存儲空間,又可以使地址連續。
CF卡的讀寫(xiě)是通過(guò)卡內的緩沖區進(jìn)行的,不支持直接讀寫(xiě)存儲區域。緩沖區為一個(gè)FIFO結構,讀寫(xiě)順序進(jìn)行,不支持隨機存取,系統只能一次性地按順序讀完或寫(xiě)完所有一個(gè)或多個(gè)扇區。
設計時(shí)使用LBA方式訪(fǎng)問(wèn)CF卡比較方便,讀寫(xiě)時(shí)只需要先在相應的寄存器寫(xiě)入LBA地址即可。要設定LBA方式,需訪(fǎng)問(wèn)驅動(dòng)器/磁頭寄存器。內存模式下部分寄存器譯碼如表3所列。
表3 內存模式下部分寄存器譯碼
REG | A10 | A9~A4 | A3~A0 | offset | OE=0 | WE=0 |
1 | 0 | X | 0000 | 0 | 偶字節讀 | 側字節寫(xiě) |
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 | 驅動(dòng)器/磁頭(LBA27~24) | 驅動(dòng)器/磁頭(LBA27~24) |
1 | 0 | X | 0111 | 7 | 狀態(tài)寄存器 | 命令寄存器 |
驅動(dòng)器/磁頭寄存器結構如下:
1 | LBA | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
LBA—1為L(cháng)BA方式,0為C/H/S(柱面/磁頭/扇區)方式;DRV—選擇驅動(dòng)器0或驅動(dòng)器1;HS3~HS0—LBA27~24,或為C/H/S方式的磁頭號。
文件創(chuàng )建過(guò)程也就是針對FAT和FDT的讀寫(xiě)過(guò)程。首先在FDT中申請表項,創(chuàng )建文件名稱(chēng)、屬性、起始簇號、文件大小等,然后修改FAT,分配數據空間,備份FAT。文件存儲就是要先從FDT和FAT中獲得文件的起始簇號和簇號鏈,即LBA地址。然后,將此地址送給寄存器3、4、5、6(表3中的offset3、4、5、6),向扇區數寄存器填寫(xiě)讀寫(xiě)數據所占的扇區個(gè)數,再向CF卡的命令寄存器寫(xiě)入操作的命令字,寫(xiě)操作30H,讀操作20H。當寫(xiě)入命令或寫(xiě)入數據后要查詢(xún)狀態(tài)寄存器的狀態(tài),以判定CF卡是否準備就緒或寫(xiě)入成功。狀態(tài)寄存器結構如下:
BUSY | RDY | DWF | DSC | DRQ | CORR | 0 | ERR |
各位的值為1時(shí)含義如下:
BUSY—CF卡記,此時(shí)不能接受其它命令;
RDY—卡可以接受命令;
DWF—寫(xiě)錯誤;
DSC—卡準備就緒;
DRQ—CF卡請求數據傳送;
CORR—數據錯誤但被修正,不會(huì )終止多扇區讀操作;
ERR—在上一命令以某種錯誤結束,可以在錯誤寄存器中查看錯誤類(lèi)型。
下面以向CF卡寫(xiě)一個(gè)扇區數據為例,給出圖4所示流程和C程序代碼。
bit flag_1,flag_2;void cfwr(){unsigned char status;cfwr_comm(0xe0,0x00,0x00,0x6c);//寫(xiě)參數命令,指向邏輯6c扇區do{status=PBYTE[0x07]; //讀狀態(tài)寄存器if((status 0x01)==0x01)flag_1=1; //若ERR=1,置出錯標志,做相應處理while(status!=0x58);cfwr_dat(); //寫(xiě)入數據do{status=PBYTE[0x07]; //讀狀態(tài)寄存器if((status 0x20)==0x20)flag_2=1; //若DWF=1時(shí),置出錯標志,做相應處理while(status!=0x50);}void cfwr_comm(unsigned char lba27,lba23,la15,lba7) //寫(xiě)參數命令函數{PBYTE[0x02] 扇區數為1PBYTE[0x03]=lba7;PBYTE[0x04]=la15;PBYTE[0x05]=lba23;PBYTE[0x06]=lba27; //設定LBA方式PBYTE[0x07]=0x30; //送寫(xiě)入命令30H}void cfwr_dat() //寫(xiě)數據函數{unsigned int i,temp;unsigned char xdata dat[512]; //dat[]存放一個(gè)扇區的數據for (i=0;i512;i++) //連續寫(xiě)512字節{P1=P1 0xf8; //選中外部RAMtemp=dat[i];P1++; //根據實(shí)際電路選擇中CF卡PBYTE[0x00]=temp;}}
5 結論
筆者在濕度檢測儀中,根據本文所介紹的方法,用CF卡向計算機轉存數據,可以非常方便地對數據進(jìn)行維護。
評論