方 明 林建中
[摘要]給出利用FPGA上實(shí)現(xiàn)的UART IP核,實(shí)現(xiàn)在微處理器S3C2440A總線上動(dòng)態(tài)擴(kuò)展多串口電路,論述基于發(fā)送和接收FIFO下的UART接口模塊設(shè)計(jì)以及各主要功能模塊實(shí)現(xiàn)。另外,給出節(jié)省中斷資源的用于實(shí)現(xiàn)串口動(dòng)態(tài)擴(kuò)展的電路。最后,給出WINCE5.0下多串口設(shè)備驅(qū)動(dòng)程序的實(shí)現(xiàn)框架。
[關(guān)鍵詞]UART S3C2440A WINCE 5.0
中圖分類號(hào):TP3文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):16717597(2009)0310015-03
一、引言
由于基于FPGA/CPLD實(shí)現(xiàn)的電路在靈活性,體積,成本方面都有其優(yōu)勢(shì)。本文從實(shí)際應(yīng)用的角度出發(fā),為了滿足高速數(shù)據(jù)傳輸要求,利用FPGA實(shí)現(xiàn)了分別擁有512字節(jié)的發(fā)送和接收FIFO的UART接口模塊,并采用接口電路動(dòng)態(tài)擴(kuò)展UART,以實(shí)現(xiàn)微處理器S3C2440A上實(shí)現(xiàn)擴(kuò)展多串口的目的,在最少改動(dòng)電路下滿足要求高速傳輸?shù)亩啻趫?chǎng)合。同時(shí),本文還給出了在嵌入式操作系統(tǒng)WINCE5.0下的多串口驅(qū)動(dòng)實(shí)現(xiàn)過(guò)程。
二、硬件電路總體設(shè)計(jì)
硬件電路實(shí)現(xiàn)如圖(1)所示,主要有微處理器S3C2440A,兩片緩沖器74LVTH162245分別用于地址總線/片選和數(shù)據(jù)總線的緩沖,以及一塊FPGA模塊組成。微處理器是三星32bit ARM920T內(nèi)核的S3C2440A,其主頻在400MHZ,最高可達(dá)533MHZ,可擴(kuò)展外部存器,具有豐富的I2C,SPI,CAN,以太網(wǎng),USB等控制接口,還可通過(guò)總線擴(kuò)展其他接口電路,應(yīng)用層面非常廣泛。而FPGA模塊的功能是使用VHDL實(shí)現(xiàn)了UART IP核以及多串口擴(kuò)展控制電路,該控制電路通過(guò)產(chǎn)生多個(gè)串口的片選以及通過(guò)微處理器的1個(gè)GPIO口作為中斷使能信號(hào)來(lái)高效管理多個(gè)串口中斷共用一個(gè)中斷的有效方法來(lái)實(shí)現(xiàn)多串口的擴(kuò)展,通過(guò)這不僅節(jié)約了中斷資源,同時(shí),也保證了多個(gè)串口中斷的無(wú)漏檢測(cè)和服務(wù)。另外,通過(guò)電平轉(zhuǎn)換芯片,如MAX232,MAX485,MAX491它們可以分別實(shí)現(xiàn)RS232,RS485以及RS422接口串口。
(一)微處理器S3C2440A資源分配
S3C2440A中的內(nèi)存控制器提供了要求外部?jī)?nèi)存訪問(wèn)的內(nèi)存控制信號(hào),總共有8個(gè)塊,地址從0x0000_000~0x4000_0000,每個(gè)塊的大小為128MB,6個(gè)塊可以用于擴(kuò)展ROM,SRAM,其他兩個(gè)用于ROM,SDRAM。每個(gè)塊都有一個(gè)片選信號(hào)nGs0~nGs7,當(dāng)某塊的片選信號(hào)有效時(shí),就可以通過(guò)讀寫(xiě)信號(hào)訪問(wèn)該塊數(shù)據(jù)。在擴(kuò)展多串口的電路,我們采用了第6塊內(nèi)存塊,地址從0x2800_0000~0x3000_0000,片選信號(hào)為nGs5,來(lái)作為訪問(wèn)多串口數(shù)據(jù)的區(qū)域。
(二)UART IP核的設(shè)計(jì)
采用硬件描述語(yǔ)言VHDL,在ALTERA公司的現(xiàn)場(chǎng)可編程門(mén)陣列(FPGA)上實(shí)現(xiàn)了擁有512字節(jié)接收和發(fā)送FIFO的軟件上兼容16550的UART核。在UART IP核中主要由讀寫(xiě)控制模塊,寄存器和發(fā)送/接收FIFO模塊,接收模塊,發(fā)送模塊,波特率發(fā)生器以及中斷控制產(chǎn)生模塊組成。圖(2)顯示了UART的數(shù)據(jù)發(fā)送/接收的格式,從CPU端和設(shè)備端看,UART接收部分實(shí)現(xiàn)在設(shè)定波特率下將設(shè)備端的串行數(shù)據(jù)轉(zhuǎn)換成并行數(shù)據(jù)給CPU,而發(fā)送部分實(shí)現(xiàn)將CPU端的并行數(shù)據(jù)轉(zhuǎn)換成串行數(shù)據(jù)再以設(shè)定的波特率發(fā)送給設(shè)備。其中,在設(shè)備端的數(shù)據(jù)幀格式中,起始位為兩個(gè)比特寬度,用于在UART接收時(shí)的辨別一幀數(shù)據(jù)開(kāi)始的判斷;通過(guò)對(duì)UART內(nèi)部寄存器的配置,可以將配置數(shù)據(jù)位數(shù)5~8位,是否有校驗(yàn)位和校驗(yàn)類型,以及停止位的位數(shù)為1或1.5或2。
1.UART實(shí)現(xiàn)的各功能描述
(1)讀寫(xiě)控制模塊主要負(fù)責(zé)處理與系統(tǒng)處理器那邊的通信,所有內(nèi)部寄存器的讀和寫(xiě)通過(guò)這個(gè)模塊完成。
(2)UART寄存器模塊處理所有內(nèi)部寄存器,其他模塊的寄存器信息在這個(gè)模塊中被匯集并且對(duì)所有塊都可得到。
(3)接收模塊接收串行數(shù)據(jù),通過(guò)預(yù)先設(shè)置可以識(shí)別數(shù)據(jù)寬度諸如5,6,7,8比特,不同的校驗(yàn)設(shè)置比如寄校驗(yàn),偶校驗(yàn)或無(wú)校驗(yàn),以及不同的停止位諸如1,1.5,2比特。該模塊還對(duì)接收數(shù)據(jù)流進(jìn)行錯(cuò)誤檢測(cè)諸如溢出錯(cuò)誤,幀錯(cuò)誤,校驗(yàn)錯(cuò)誤以及超時(shí)錯(cuò)誤。如果接收數(shù)據(jù)沒(méi)有錯(cuò)誤,將其數(shù)據(jù)放入接收FIFO中。
(4)中斷控制模塊依賴發(fā)送FIFO的狀態(tài)和它的發(fā)送的和接收的數(shù)據(jù)的狀態(tài)來(lái)發(fā)送一個(gè)中斷信號(hào)給處理器。
(5)波特率發(fā)生器將輸入的時(shí)鐘信號(hào)除以一個(gè)可編程的數(shù)值,再將其接口除以16就得到了發(fā)送和接收用的波特率。
(6)發(fā)送模塊處理將發(fā)送的數(shù)據(jù)寫(xiě)入到發(fā)送FIFO中,并且按照UART的數(shù)據(jù)格式再數(shù)據(jù)發(fā)送的時(shí)候加上開(kāi)始位,校驗(yàn)位以及停止位,這樣保證接收設(shè)備可以做適當(dāng)錯(cuò)誤處理和接收。
2.發(fā)送模塊實(shí)現(xiàn)
由于微處理器在較高時(shí)鐘頻率上發(fā)送數(shù)據(jù)給UART,為了保證UART在發(fā)送保持寄存器(THR)中的數(shù)據(jù)不被后一幀數(shù)據(jù)給覆蓋,在UART中設(shè)計(jì)了容量為512字節(jié)的發(fā)送FIFO,基于FIFO設(shè)計(jì)的發(fā)送數(shù)據(jù)有限狀態(tài)機(jī)如圖(3)所示,一開(kāi)始,發(fā)送FIFO處于空的狀態(tài),通過(guò)使能FIFO寫(xiě)入信號(hào)將數(shù)據(jù)先放入FIFO(只要FIFO處于非全滿狀態(tài)將一直可以接收來(lái)自CPU的數(shù)據(jù))。然后,通過(guò)地址、片選和寫(xiě)控制信號(hào)讀取發(fā)送保持寄存器的狀態(tài),當(dāng)判斷其為空時(shí),在第一時(shí)鐘周期先使能FIFO讀取信號(hào),將FIFO中的一個(gè)數(shù)據(jù)先放在總線上,然后在后面的時(shí)鐘周期里產(chǎn)生UART的寫(xiě)控制信號(hào),將放在總線上的數(shù)據(jù)寫(xiě)入到UART的發(fā)送保持寄存器,再通過(guò)移位寄存器將數(shù)據(jù)按波特率發(fā)送到設(shè)備接收端。這樣做即可保證發(fā)送數(shù)據(jù)的完整性,同時(shí)提高了數(shù)據(jù)的發(fā)送速度。
3.接收模塊實(shí)現(xiàn)
當(dāng)處理器由于某種原因,導(dǎo)致在接收來(lái)自外部串行設(shè)備的數(shù)據(jù)不被后面的數(shù)據(jù)給覆蓋,在設(shè)計(jì)中采用了一個(gè)512字節(jié)的接收FIFO來(lái)緩沖接收數(shù)據(jù)。圖(4)顯示了基于接收FIFO的接收模塊的狀態(tài)機(jī),當(dāng)UART檢測(cè)到起始數(shù)據(jù)位并將接收到的一幀完整數(shù)據(jù)去除開(kāi)始位,校驗(yàn)位和停止位后放入接收緩沖寄存器(RBR),然后,發(fā)出接收數(shù)據(jù)準(zhǔn)備信號(hào)(TXRDY置位),接著在第一時(shí)鐘周期產(chǎn)生訪問(wèn)UART的讀信號(hào)(RDn)將其RBR中的數(shù)據(jù)讀到接收FIFO輸入數(shù)據(jù)線上,在隨后時(shí)鐘周期里再使能接收FIFO寫(xiě)入信號(hào),將FIFO輸入數(shù)據(jù)線上的數(shù)據(jù)存到FIFO中。當(dāng)接收FIFO中的數(shù)據(jù)達(dá)到FIFO觸發(fā)等級(jí)(在FIFO控制器中預(yù)先設(shè)置了觸發(fā)中斷數(shù),通常是1,4,8,14個(gè)字節(jié))時(shí)發(fā)送中斷信號(hào)給處理器請(qǐng)求接收數(shù)據(jù),這時(shí)當(dāng)接收到處理器的讀信號(hào)有效時(shí),就產(chǎn)生接收FIFO的讀取使能信號(hào),將FIFO中的數(shù)據(jù)按照先入先出的方式放到外部數(shù)據(jù)總線上以讓處理器讀取。
(三)多串口擴(kuò)展控制電路
該電路主要負(fù)責(zé)對(duì)擴(kuò)展的UART進(jìn)行片選控制,以及通過(guò)微處理器的1個(gè)GPIO口作為中斷使能信號(hào)來(lái)高效管理多個(gè)串口中斷共用一個(gè)中斷。為了選種擴(kuò)展的UART,通過(guò)處理器的地址訪問(wèn)片選信號(hào)nGs5以及地址線addr[15..3]來(lái)譯碼器產(chǎn)生UART的片選信號(hào)。對(duì)擴(kuò)展四個(gè)UART來(lái)說(shuō),其地址依次為0x001x,0x002x,0x003x,0x004x。另外中斷使能信號(hào)(inten)的地址為0x0100。各UART中斷采用或運(yùn)算合并產(chǎn)生一個(gè)中斷,當(dāng)中斷使能信號(hào)有效時(shí),發(fā)送中斷給處理器。在硬件驅(qū)動(dòng)層處理器響應(yīng)中斷并進(jìn)入中斷服務(wù)程序,在中斷服務(wù)過(guò)程中,處理器按順序逐個(gè)檢查多個(gè)擴(kuò)展口的串口中斷源,有中斷請(qǐng)求的就給予服務(wù),并置中斷使能信號(hào)(inten)無(wú)效。當(dāng)剛剛檢測(cè)過(guò)的中斷又出現(xiàn)時(shí),一方面靠擴(kuò)展控制電路中的移位寄存器將INTR鎖存,另一方面,擴(kuò)展控制電路中的8位狀態(tài)機(jī)保證了一定的延時(shí),使得上一中斷服務(wù)順利完成,完成后再將中斷使能信號(hào)(inten)變?yōu)橛行б越邮蘸罄m(xù)的中斷。在延時(shí)中,中斷控制程序把堆棧中的內(nèi)容返回給處理器的寄存器,恢復(fù)能獲得的響應(yīng)。這樣,即使在多個(gè)串口中斷密集發(fā)生的環(huán)境下,擴(kuò)展的多個(gè)串口仍可獲得實(shí)時(shí)性和可靠性較高的中斷。具體VHDL實(shí)現(xiàn)代碼如下:
con_pro : process(nreset,clk)
begin
if ngcs5='0' and a(15 downto 3)="0000000000010" then cs(0)<='1'; else cs(0)<='0';
end if;--片選UART1
if ngcs5='0' and a(15 downto 3)="0000000000100" then cs(1)<='1'; else cs(1)<='0';
end if;-- 片選UART2
if ngcs5='0' and a(15 downto 3)="0000000000110" then cs(2)<='1'; else cs(2)<='0';
end if;-- 片選UART3
if ngcs5='0' and a(15 downto 3)="0000000001000" then cs(3)<='1'; else cs(3)<='0';
end if;-- 片選UART4
add<=a(2 downto 0);--訪問(wèn)UART內(nèi)部寄存器地址
reset<=not(nreset);--復(fù)位UART信號(hào)
if ngcs5='0' and a="0000000100000000" then
lck_sel<='1';
else lck_sel<='0'; end if;--中斷使能信號(hào)
if nreset='0' then LCK<='0';
elsif rising_edge(nwe) then if lck_sel='1' then dffin<=data(0);-- 數(shù)據(jù)輸入到中斷鎖存寄存器 LCK<='1';-- 中斷鎖存寄存器時(shí)鐘信號(hào)
elseLCK<='0'; end if; end if;
if rising_edge(clk) then
if(inten='1') then
intr<= not(inta or intb or intc or intd );--中斷(inta,intb,intc,intd 分別為四個(gè)UART的中斷信號(hào))
elseinter<='1'; end if; end if;
end process con_pro;
// 中斷有限狀態(tài)機(jī)
Interput_Proc: process(nreset,clk10k)
begin
if (nreset='0') then State <= s0;
elsif rising_edge(clk10k) then
case State is
when s0 =>
if (inten='1') and (intr='0') then
State <= s1;--產(chǎn)生中斷
else State <= s0; end if;
when s1 =>
if (inten='0') then
State <= s2; --中斷使能無(wú)效
else State <= s1; end if;
when s2 =>
if (inten='1') then--中斷服務(wù)完成,置中斷使能有效
State <= s3;
else State <= s2; end if;
// 延時(shí)50US保證中斷服務(wù)程序完全退出
when s3 => State <= s4;--10us
when s4 => State <= s5;--10us
when s5 => State <= s5;--10us
when s6 => State <= s7;--10us
when s7 => State <= s0;--10us
when others => State <= s0;
end case; end if;
end processInterput_Proc;
end beha;
三、WINCE5.0下實(shí)現(xiàn)多串口驅(qū)動(dòng)
在WINCE 5.0下開(kāi)發(fā)的設(shè)備驅(qū)動(dòng)有兩種模式:本機(jī)設(shè)備驅(qū)動(dòng)和流接口設(shè)備驅(qū)動(dòng)。而本系統(tǒng)的多串口設(shè)備驅(qū)動(dòng)采用流接口設(shè)備驅(qū)動(dòng)方式,它以動(dòng)態(tài)鏈接庫(kù)(DLL)即文件系統(tǒng)的一個(gè)特殊文件形式來(lái)實(shí)現(xiàn)把外設(shè)使用傳遞給應(yīng)用程序。圖(5)顯示了其設(shè)備驅(qū)動(dòng)如何下WINCE5.0操作系統(tǒng)中集成的,其中,設(shè)備驅(qū)動(dòng)程序分為兩層,上層是模型設(shè)備驅(qū)動(dòng)驅(qū)動(dòng)程序(MDD),該層驅(qū)動(dòng)對(duì)平臺(tái)和函數(shù)來(lái)講是通用的,即是源代碼也是庫(kù),負(fù)責(zé)鏈接PDD層并定義它希望調(diào)用的函數(shù)以及把不同的函數(shù)集提供給設(shè)備管理器來(lái)統(tǒng)一加載、管理和卸載,這些函數(shù)集叫流接口函數(shù);而下層是依賴平臺(tái)的設(shè)備驅(qū)動(dòng)程序(PDD),它是直接訪問(wèn)硬件的驅(qū)動(dòng)程序,同時(shí)通過(guò)設(shè)備驅(qū)動(dòng)程序提供器接口(DDIS)接口提供給MDD層調(diào)用。
每一個(gè)流接口驅(qū)動(dòng)程序必須實(shí)現(xiàn)一組標(biāo)準(zhǔn)的函數(shù),用來(lái)完成標(biāo)準(zhǔn)的文件I/O函數(shù)和電源管理函數(shù),這些函數(shù)提供給WINCE操作系統(tǒng)內(nèi)核使用,由于篇幅的限制這里只列出多串口流接口驅(qū)動(dòng)程序要實(shí)現(xiàn)的DLL接口:COM_Close它是在串口驅(qū)動(dòng)關(guān)閉是應(yīng)用程序通過(guò)CloseHandle( )函數(shù)調(diào)用這個(gè)函數(shù);COM_Init它完成串口的初始化;COM_Open在打開(kāi)一個(gè)串口驅(qū)動(dòng)程序時(shí)應(yīng)用程序可以通過(guò)CreatFile( )函數(shù)調(diào)用這個(gè)函數(shù);COM_Deinit該函數(shù)完成串口驅(qū)動(dòng)程序的卸載;COM_IOControl該函數(shù)用于向串口設(shè)備發(fā)送命令,應(yīng)用層可以通過(guò)DeviceIOControl函數(shù)來(lái)通知操作系統(tǒng)調(diào)用這個(gè)函數(shù);COM_Read()在串口處于打開(kāi)狀態(tài)時(shí)應(yīng)用程序通過(guò)ReadFile( )函數(shù)調(diào)用這個(gè)函數(shù)來(lái)讀取串口數(shù)據(jù);COM_Write()在串口處于打開(kāi)狀態(tài)時(shí)應(yīng)用程序通過(guò)WriteFile( )函數(shù)調(diào)用這個(gè)函數(shù)來(lái)向串口寫(xiě)入數(shù)據(jù);COM_PowerDown由COM_Init創(chuàng)建時(shí)生產(chǎn)的句柄,系統(tǒng)掛起前調(diào)用這個(gè)函數(shù);COM_PowerUp由COM_Init創(chuàng)建時(shí)生產(chǎn)的句柄,系統(tǒng)重新啟動(dòng)前調(diào)用這個(gè)函數(shù)。
四、總結(jié)
在FPGA上實(shí)現(xiàn)UART IP核,占用700個(gè)宏單元,共1萬(wàn)5千門(mén)系統(tǒng)設(shè)計(jì),通過(guò)接口模塊化設(shè)計(jì)的UART核來(lái)實(shí)現(xiàn)嵌入式微處理器動(dòng)態(tài)擴(kuò)展多串口電路的方法,有利于通過(guò)電路的最小更改來(lái)實(shí)現(xiàn)多串口的擴(kuò)展,同時(shí)也減小開(kāi)發(fā)周期和成本,該設(shè)計(jì)方法也可以作為其他電路設(shè)計(jì)的參考。
參考文獻(xiàn):
[1]邰銘、于洪濤,Windows CE.Net內(nèi)核定制及應(yīng)用開(kāi)發(fā),電子工業(yè)出版社,2004.
[2]董長(zhǎng)富、郭超平、宋渝,基于FPGA的多串口模塊的設(shè)計(jì)和實(shí)現(xiàn),設(shè)計(jì)參考,2006,Vol.8 No.11.
[3]姜寧、范多旺,基于FPGA/CPLD的通用異步通信接口UART的設(shè)計(jì),信息系統(tǒng)與信息化,2006年第1期.
作者簡(jiǎn)介:
方明,男,碩士,主研方向:嵌入式系統(tǒng)開(kāi)發(fā),集成電路設(shè)計(jì);林建中,男,高級(jí)工程師,主研方向:計(jì)算機(jī)系統(tǒng)開(kāi)發(fā),集成電路設(shè)計(jì)。