摘 要:本文闡述了無SDRAM控制器環(huán)境中使用單片機K60的GPIO口驅動SDRAM的硬件組成和軟件設計,并測試了該系統(tǒng)的主要性能,給出了該系統(tǒng)的應用舉例,具有低功耗、功能齊全、人機界面友好等優(yōu)點。
關鍵詞:SDRAM;單片機;MK60DN512ZVLQ10;存儲管理;控制程序
中圖文分類號:TP368
隨著集成電路技術與工藝的發(fā)展進步,單片機應用領域也逐漸擴廣,進入到社會生產(chǎn)生活的方方面面。在某些成本敏感的應用場合迫切需要具有速度高、容量大的深度嵌入式系統(tǒng),技術的進步,使得以低廉的價格獲得高性能,低功耗單片機成為可能。借助極高的接口速度,我們就可以使用普通GPIO口在沒有SDRAM控制器的廉價單片機上實現(xiàn)軟件驅動SDRAM。
1 硬件介紹
1.1 單片機
Kinetis系列是飛思卡爾(Freescale)公司于2010年下半年推出的業(yè)內首款基于ARM Cortex.M4內核的微控制器,K60系列是Kinetis系列的第一階段產(chǎn)品之一[1]。K60具有豐富的外設接口:(1)高速16位模數(shù)轉換器;(2)12位數(shù)模轉換器,帶有片上模擬電壓參考;(3)多個高速比較器和可編程增益放大器;(4)低功耗觸摸感應功能,通過觸摸能將器件從低功耗狀態(tài)喚醒;(5)多個串行接口,包括UART;(6)強大靈活的定時器;(7)片外系統(tǒng)擴展和數(shù)據(jù)存儲選項。
1.2 SDRAM
本文選用Hynix的H57V2562GTR-60C 256Mb SDRAM,其為4M x 4Bank x16bit組織結構。操作SDRAM的主要命令[2]有:
MRS (Mode Register Set,模式寄存器設置),
NOP (No Operation,空操作),BA(Bank Active,存儲器激活),RD(Read,讀,可設置是否自動預充電),WR(Write,寫,可設置是否自動預充電),PB(Precharge Bank,預充電存儲器,可設置全部/選定Bank),BS(Burst stop,停止突發(fā)傳輸),DQM(DQM,數(shù)據(jù)掩碼),AR(Auto Refresh,自動刷新),BRSW(Burst-Read Single-Write,突發(fā)讀單一寫),SR(Self Refresh,自刷新,進入/退出),PPD(Precharge Power Down,掉電預充電,可設置進入/退出),CSS(Clock Suspend,時鐘掛起可設置進入/退出)。
1.3 顯示器LCD及攝像頭Ov7725
本文選用2.4英寸240*320像素LCD作為顯示器,攝像頭采用Ov7725。
2 硬件連接
2.1 MCU與SDRAM接口
SDRAM需要一組16位寬的接口進行數(shù)據(jù)傳輸,13位寬的接口進行地址設定,兩根Bank選擇線,CS,CLK,CKE,WE,CAS,RAS,LDQM,UDQM各一根。K60的C口和E口均為完整16位口,可以用作地址線和數(shù)據(jù)線接口,剩余控制線使用單片機未用接口即可。
2.2 MCU與LCD接口
該LCD控制器一共需要13根控制線,其數(shù)據(jù)線需要一個完整的8位口,接在K60的口8至15位,剩余控制線使用單片機未用接口即可。
2.3 MCU與Ov7725接口
Ov7725[3]是一片CMOS的集成圖像傳感器,一共需要13根控制線,其數(shù)據(jù)線需要一個完整的8位口,接在K60的B口0至7位,剩余控制線使用單片機未用接口即可。
3 軟件設計
3.1 SDRAM底層驅動構件
本層構件的功能是以軟件方式實現(xiàn)基本的內存命令,為上層軟件提供服務。主要函數(shù)原型和說明如下所述:
GPIO_Initial()初始化驅動SDRAM的GPIO口;MRS(u16 mode)設置模式寄存器,參數(shù)mode為模式寄存器控制字;BA(u8 bank,u16 addr)激活BANK,發(fā)送行地址,參數(shù)bakn為BANK編號,address為行地址;RD(u8 bank,u16 addr,u8 AutoPreCharge)讀取指定地址處數(shù)據(jù),參數(shù)bank為BANK編號,addr為列地址,AutoPreCharge表示是否自動預充電;WR(u8 bank,u16 addr,u8 AutoPreCharge)在指定地址處寫入,參數(shù)bank為BANK編號,addr為列地址,AutoPreCharge表示是否自動預充電;PBAll()給所有BANK預充電;PBOne(u8 bank)給選定BANK預充電,參數(shù)bank為BANK編號
AR()自動刷新;SREntry()自刷新進入;SRExit()自刷新退出;NOP()空操作;CLK_Count(u16 total),參數(shù)total是向SDRAM傳送的有效時鐘數(shù);Initial()SDRAM初始化函數(shù);NOP_Read()空操作讀;NOP_Write()空操作寫;NOP_Burst()空操作突發(fā)讀寫。
其中,NOP_Write函數(shù)在給SDRAM產(chǎn)生有效時鐘信號的同時自動將緩沖區(qū)第一個字放到數(shù)據(jù)線上;NOP_Read函數(shù)在給SDRAM產(chǎn)生有效時鐘信號的同時自動將地址線上的一個字取回放到緩沖區(qū)。NOP_Burst函數(shù)根據(jù)突發(fā)讀寫標識(Burst Flag),為1時,從緩沖區(qū)第二個字開始依次將余下的字放到地址線上,為0時,從地址線上取回指定字數(shù)存放到緩沖區(qū)從第二個字開始處,并給SDRAM產(chǎn)生有效時鐘信號。其執(zhí)行方式如圖1所示。
3.2 SDRAM中間級基本讀寫功能構件設計
本層構件的功能是實現(xiàn)SDRAM單個字(WORD)讀寫,以及突發(fā)讀寫功能,能夠將SDRAM的物理地址轉換為線性邏輯地址,并完成定時自動刷新。為實現(xiàn)以上功能,定義一些全局變量,下面將說明。Buffer類型為unsigned short int*,長度16字節(jié),在內存讀寫時作為數(shù)據(jù)交換區(qū)域。BurstFlag類型為Unsigned char,長度1字節(jié),其值0為突發(fā)讀,1為突發(fā)寫。BurstLength類型為Unsigned char,長度1字節(jié),指明突發(fā)長度。
首先為保持SDRAM內數(shù)據(jù)不丟失,必須在64ms以內進行一次刷新操作。在K60的中斷定時器(PIT)中開啟一個周期中斷通道,設置其周期小于64ms即可,在其終端服務函數(shù)中調用自動刷新函數(shù)AR,然后再調用CLK_Count以產(chǎn)生數(shù)個自動刷新節(jié)拍,這樣自動刷新功能就完成了。
單個字讀、寫(函數(shù)名定義為Read_Word和Write_Word)實現(xiàn)過程類似。由于系統(tǒng)中存在周期中斷,并且該中斷同是對SDRAM進行操作的,所以在進行讀寫之前,必須先關閉周期中斷,以保證操作進行的正確性。緊接著便可以執(zhí)行相應讀取或寫入操作。
當為讀取操作時,先調用Bank激活命令BA同時傳入相應Bank編號和行地址;然后調用CLK_Count,給SDRAM發(fā)送幾個有效時鐘,具體有效時鐘數(shù)量,視存儲器芯片和設定的RCD周期而定,完成行選通到列選通延遲;然后調用RD讀函數(shù),并傳入相應的列地址;然后調用CLK_Count,給SDRAM發(fā)送幾個有效時鐘,具體有效時鐘數(shù)量,視存儲器芯片和CL周期而定,這段時間為讀取潛伏期;之后便可以調用NOP_Read,將數(shù)據(jù)線上的一個字取回緩沖區(qū),開啟周期中斷后就可以返回給主函數(shù)調用者了。
當為寫入操作時,先從緩沖區(qū)取出欲寫入的一個字放到數(shù)據(jù)線上,然后調用Bank激活命令BA同時傳入相應Bank編號和行地址;然后調用CLK_Count,給SDRAM發(fā)送幾個有效時鐘,具體有效時鐘數(shù)量,視存儲器芯片和設定的RCD周期而定,完成行選通到列選通延遲;然后調用WR讀函數(shù)。需要注意的是,這里與讀取操作不同,并不存在潛伏期,也就是說此時欲寫入的數(shù)據(jù)已經(jīng)在SDRAM里等待被寫入了,只需要短暫的寫回延時即可。為與讀操作函數(shù)對稱,使程序結構易于被程序員讀懂,本文仍以NOP_Write函數(shù)形式實現(xiàn)寫回延時。至此寫入操作便完成,將周期中斷打開即可。圖2是單個字讀寫函數(shù)的流程圖,右為寫,左為讀。
對于突發(fā)讀和突發(fā)寫,只要在進行讀寫前設置突發(fā)讀寫標識BurstFlag為突發(fā)讀(值為0)、突發(fā)寫(值為1),將單個字讀寫函數(shù)中相應的NOP_Read、NOP_Write更改為NOP_Burst,并計算好NOP_Burst的數(shù)量即可。
3.3 SDRAM內存管理模型設計
本文使用鏈表式的內存管理算法[4]來管理系統(tǒng)上掛載的容量為32M字節(jié)SDRAM存儲器。該SDRAM的組織結構為4Bank×213行×29列×16位,因此本文將動態(tài)內存塊大小設置為1K字節(jié),剛好是一行中所有存儲體的總容量。這樣就32M字節(jié)存儲器將被劃分為131072個存儲塊。顯然即便是每個存儲塊只用一個字節(jié)記錄相關信息,對于單片機來說開銷也是巨大的,K60DN512單片機配備了128KB的SRAM,盡管在深度嵌入領域這個容量已經(jīng)相當大,也是不夠用的。因此需要設計一種算法用來動態(tài)創(chuàng)建和刪除鏈表中的節(jié)點,控制鏈表中節(jié)點的數(shù)量,來完成SDRAM存儲管理。
每一個內存(指系統(tǒng)掛載的SDRAM存儲器,下同)塊對應一個節(jié)點,該節(jié)點的結構定義如下:
typedef struct BlockNode
{ unsigned long int BlockAddr; unsigned char State;
struct BlockNode *left;
struct BlockNode *right;
} BNode, *pBNode;
BlockAddr存儲該內存塊的首地址,State標記該內存塊是否被分配,值為0未被分配,其他值已被分配,left存儲左邊一個節(jié)點指針,right存儲右邊一個節(jié)點指針。
該結構體占據(jù)13個字節(jié)存儲量,若在單片機上用13KB存儲器來存儲該鏈表則可以方便管理1MB的SDRAM存儲器,還是非常劃算的。
本文采用就大法分[5]配動態(tài)分配內存塊。其算法流程圖3所示。
回收內存的算法相對簡單,只需要根據(jù)需要回收的內存塊首址刪除掉相應節(jié)點即可。
3.4 系統(tǒng)整體設計
在完成了所有基本構件的設計以后,便可以進行系統(tǒng)整體設計了。這只需要調用基本構件初始化函數(shù),按照一定時序建立服務函數(shù)即可,系統(tǒng)啟動流程如圖4所示。
4 系統(tǒng)性能測試
本文以多種方式測試了該系統(tǒng)對SDRAM讀寫數(shù)據(jù)的能力,測試結果如表1所示。
由實際測試數(shù)據(jù)可知,突發(fā)傳輸可得大大提高SDRAM的讀寫速度。
5 應用舉例
在深度嵌入的單片機上實現(xiàn)高速圖像采集、存儲、處理、顯示是比較困難的,其原因在于MCU運算速度有限,存儲容量有限。該系統(tǒng)采用的K60單片機已經(jīng)具有DSP處理器,可以實現(xiàn)對大量數(shù)據(jù)的高速處理。
在場終端到來時設置行計數(shù)為0并打開場中斷,在行中斷到來時開啟DMA,跟隨PCLK時鐘采集640字節(jié)數(shù)據(jù),DMA操作結束后對行計數(shù)執(zhí)行加1操作,判斷行計數(shù)有沒有達到240,如果達到240,關閉行中斷并設置行計數(shù)為0,否則跳過此步驟繼續(xù)執(zhí)行將640字節(jié)數(shù)據(jù)存入SDRAM。在主函數(shù)中讀取SDRAM中存儲的數(shù)據(jù)發(fā)送到LCD上顯示便實現(xiàn)了動態(tài)顯示。主函數(shù)中也可以對SDRAM中存儲的數(shù)據(jù)進行處理變換后再重組發(fā)送到顯示器或作他用。
6 結語
在深度嵌入的現(xiàn)代生活中,單片機的速度越來越快,人們對存儲容量的需求也越來越大,相對于花費大量資金購買一塊昂貴的帶有SDRAM控制器的MCU,本文介紹的GPIO口控制和管理SDRAM具有設備簡單,技術門檻低,開發(fā)周期短的優(yōu)點。系統(tǒng)有待改進的地方在于可移植性不夠強,通用性不夠好,從編程角度看,最基本的指針訪問內存的方式必須以函數(shù)代替,這樣無法實現(xiàn)某些算法。該系統(tǒng)適合數(shù)據(jù)量大,對數(shù)據(jù)存取速度要求高,頻繁改寫數(shù)據(jù)的系統(tǒng),比如在圖像采集系、處理等系統(tǒng)。
參考文獻:
[1]王宜懷,吳瑾,蔣銀珍.嵌入式系統(tǒng)原理與實踐[M].北京:電子工業(yè)出版社,2012:22-35.
[2]金新強,白雪飛,張璠.一種DDRSDRAM控制器的設計[J].微型機與應用,2013,32(8):23-25.
[3]任志敏.一種基于OV7725的圖像實時顯示系統(tǒng)設計[J].福建電腦.2013,29(1):128-130.
[4]張榮華,田澤,韓煒.基于鏈表的動態(tài)存儲器管理設計與實現(xiàn)[J].計算機技術與發(fā)展.2011,21(7):250-253.
[5]何煦嵐,何曉嵐.基于多鏈表結構的嵌入式系統(tǒng)內存管理[J].計算機應用與軟件.2008,25(4):58-59,81.
作者簡介:周成龍(1992-),男,山東臨沭,中國礦業(yè)大學,本科,電氣工程與自動化。