摘 要: 簡(jiǎn)單介紹I2C總線(xiàn)協(xié)議,用Altera公司的FPGA(現(xiàn)場(chǎng)可編程門(mén)陣列)芯片設(shè)計(jì)I2C總線(xiàn)接口控制器,用于控制EEPROM(帶電可擦寫(xiě)可編程只讀存儲(chǔ)器)的讀寫(xiě)操作。
關(guān)鍵詞: I2C總線(xiàn);FPGA;EEPROM
0 引言
隨著電子技術(shù)快速發(fā)展,有許多的IC需要相互之間進(jìn)行通信。為此,Philips公司開(kāi)發(fā)了一種性能優(yōu)越的雙向兩線(xiàn)串行總線(xiàn)I2C(Inter-Integrated Circuit)總線(xiàn)。進(jìn)行FPGA設(shè)計(jì)時(shí)經(jīng)常需要與外圍提供I2C接口的芯片進(jìn)行通信,雖然市場(chǎng)上有專(zhuān)門(mén)的I2C總線(xiàn)接口芯片,但是大多性能指標(biāo)固定、功能單一、使用不方便。根據(jù)I2C總線(xiàn)協(xié)議和其電路的電氣特性,在Altera公司的EP4CE10F17C8N型號(hào)的FPGA芯片上可以方便地實(shí)現(xiàn)I2C總線(xiàn)接口,進(jìn)而實(shí)現(xiàn)EEPROM的讀寫(xiě)操作。
1 I2C總線(xiàn)原理概述
I2C總線(xiàn)有兩條串行總線(xiàn),一條是串行時(shí)鐘線(xiàn)(SCL),一條是串行數(shù)據(jù)線(xiàn)(SDA),連接到總線(xiàn)上的每個(gè)器件既可以作為發(fā)送器又可以作為接收器,且每個(gè)器件都有唯一的地址識(shí)別。主機(jī)主要負(fù)責(zé)產(chǎn)生時(shí)鐘、初始化發(fā)送和終止發(fā)送等操作。從機(jī)則是被主機(jī)尋址的器件。典型的連接在I2C總線(xiàn)上的器件有LCD、EEPROM等??偩€(xiàn)的啟動(dòng)信號(hào)條件是當(dāng)SCL為高電平時(shí),SDA由高變?yōu)榈?;停止條件是當(dāng)SCL為高電平時(shí),SDA電平由低變高。數(shù)據(jù)的變化只能發(fā)生在SCL為低電平期間[1]。
2 EEPROM讀寫(xiě)控制器模塊的設(shè)計(jì)與實(shí)現(xiàn)
在進(jìn)行數(shù)據(jù)傳輸時(shí),讀寫(xiě)控制器首先產(chǎn)生一個(gè)啟動(dòng)信號(hào)(當(dāng)SCL為高電平時(shí),SDA由高變?yōu)榈停又l(fā)送控制字(即I2C總線(xiàn)器件的特征編碼和3 bit EEPROM的芯片地址)以及寫(xiě)狀態(tài)R/W位為0到總線(xiàn)上。這里的總線(xiàn)器件特征碼為1010,而3 bit EEPROM的芯片地址為000。接著主控制器釋放總線(xiàn),等待EEPROM發(fā)出的應(yīng)答信號(hào),由于采用的EEPROM型號(hào)是24LC64,因此在控制器收到應(yīng)答后,將首先發(fā)送EEPROM高字節(jié)的存儲(chǔ)單元地址,當(dāng)控制器再次收到應(yīng)答后繼續(xù)發(fā)送EEPROM低字節(jié)的存儲(chǔ)單元地址,當(dāng)控制器再次收到應(yīng)答后,判斷是讀還是寫(xiě),如果是寫(xiě)操作,則控制器發(fā)送數(shù)據(jù)字節(jié),并把數(shù)據(jù)寫(xiě)入被尋址的存儲(chǔ)單元,EEPROM再次發(fā)送應(yīng)答信號(hào),讀寫(xiě)控制器收到應(yīng)答信號(hào)后,產(chǎn)生停止信號(hào)。如果之前判斷出是讀操作,則控制器會(huì)在收到應(yīng)答后產(chǎn)生一個(gè)重復(fù)起始條件,緊接著寫(xiě)入讀控制字10100001,這里的最后一位1表示讀操作,前面的1010000和之前說(shuō)的一樣,是器件特征編碼1010和3 bit EEPROM芯片地址000。當(dāng)控制器再次收到應(yīng)答后會(huì)產(chǎn)生一個(gè)釋放總線(xiàn)的動(dòng)作,把總線(xiàn)留給EEPROM,控制器負(fù)責(zé)接收EEPROM發(fā)出的數(shù)據(jù)。當(dāng)控制器接收完數(shù)據(jù)后會(huì)占用總線(xiàn),并發(fā)出一個(gè)非應(yīng)答信號(hào),表示數(shù)據(jù)收到,最后控制器再產(chǎn)生停止信號(hào),停止本次傳輸。模塊的主狀態(tài)機(jī)如圖1所示。
這里寫(xiě)入的地址是2 B的地址,且分兩次寫(xiě),因?yàn)榇薊EPROM的地址是16 bit的。
2.1 控制器的總線(xiàn)時(shí)鐘SCL產(chǎn)生
由于FPGA開(kāi)發(fā)板的時(shí)鐘是50 MHz,這里先將輸入的50 MHz時(shí)鐘進(jìn)行分頻產(chǎn)生400 kHz時(shí)鐘,利用400 kHz的時(shí)鐘去產(chǎn)生總線(xiàn)時(shí)鐘SCL。具體方法是:在400 kHz時(shí)鐘的下降沿對(duì)SCL進(jìn)行翻轉(zhuǎn)操作,這樣能很好地實(shí)現(xiàn)I2C總線(xiàn)時(shí)序要求。這里生成的SCL是200 kHz時(shí)鐘。其Verilog代碼如下:
always@(negedge clk_400k or negedge rst_n)
begin
if(!rst_n)
scl<=0;
else
scl<=~scl;
end
時(shí)序圖如圖2所示。
由圖2可知,在SCL為高電平時(shí),SDA由高變低會(huì)產(chǎn)生一個(gè)開(kāi)始信號(hào),而在SCL為高電平時(shí),SDA由低變高會(huì)產(chǎn)生一個(gè)停止信號(hào),而數(shù)據(jù)的改變只能在SCL為低電平期間發(fā)生,在SCL為高電平時(shí),數(shù)據(jù)要保持穩(wěn)定。數(shù)據(jù)采樣時(shí)使用400 kHz時(shí)鐘的上升沿采樣,并且是在SCL為高電平時(shí)才能采數(shù)據(jù),因?yàn)檫@時(shí)的數(shù)據(jù)穩(wěn)定。
2.2 I2C總線(xiàn)數(shù)據(jù)輸入輸出
電路的輸出采用三態(tài)數(shù)據(jù)通路設(shè)計(jì),如圖3所示。
其Verilog代碼如下:
assign sda=link_sda?sda_buf:1′bz;
由圖3可知,sda的I/O類(lèi)型為inout,當(dāng)開(kāi)關(guān)link_sda為1時(shí),讀寫(xiě)控制器上的數(shù)據(jù)可以發(fā)送到sda上,實(shí)現(xiàn)控制器占用總線(xiàn)進(jìn)行寫(xiě)操作,當(dāng)link_sda為0時(shí),輸出為高阻態(tài),而此時(shí)外部的sda上的數(shù)據(jù)可以讀進(jìn)來(lái),實(shí)現(xiàn)了控制器釋放總線(xiàn),將總線(xiàn)交由從機(jī)EEPROM,進(jìn)而可將EEPROM發(fā)出的數(shù)據(jù)讀進(jìn)來(lái)[2]。
數(shù)據(jù)的輸出涉及并串轉(zhuǎn)換,因?yàn)閿?shù)據(jù)寄存器中的數(shù)據(jù)是8 bit,而I2C總線(xiàn)上傳輸?shù)臄?shù)據(jù)sda為1 bit,其Verilog代碼如下:
if(count1<8)
begin
data<={data[6:0],data[7]};
sda_buf<=data[7];
count1<=count1+1;
state<=t2;
end
設(shè)計(jì)采用循環(huán)移位的方式將8 bit的并行data數(shù)據(jù)一位一位地移到sda_buf線(xiàn)上送出去。
相反,I2C總線(xiàn)數(shù)據(jù)的輸入涉及串轉(zhuǎn)并操作,Verilog代碼如下:
if(count1 <8)
begin
link_sda <= 0;//讀寫(xiě)控制器釋放總線(xiàn)
if(scl)
begin
data<={data[6:0],sda};//串轉(zhuǎn)并
count1<=count1+1;
state<=r2;
end
end
3 仿真驗(yàn)證
仿真平臺(tái)的搭建如圖4所示。
由圖4可知,電路的仿真驗(yàn)證模塊分為I2C接口控制器模塊、ROM模塊、地址發(fā)生器模塊、按鍵模塊、EEPROM模塊和數(shù)碼管顯示模塊。其中,按鍵模塊用于產(chǎn)生I2C接口控制器的讀寫(xiě)操作信號(hào);地址發(fā)生器模塊用于產(chǎn)生ROM和I2C接口控制器的地址信息;ROM模塊中事先存儲(chǔ)了一定量的數(shù)據(jù),并將這些數(shù)據(jù)發(fā)送給I2C接口控制器,用來(lái)寫(xiě)入EEPROM;I2C接口控制器負(fù)責(zé)EEPROM的讀寫(xiě)操作;數(shù)碼管顯示模塊負(fù)責(zé)將讀寫(xiě)控制器從EEPROM中讀出的數(shù)據(jù)顯示出來(lái),用來(lái)查看數(shù)據(jù)是否正確。
電路的仿真波形如圖5、圖6所示。
由圖5可知,在寫(xiě)EEPROM操作時(shí),讀寫(xiě)控制器在開(kāi)始信號(hào)后首先寫(xiě)入1 B的控制字10100000(前面的1010是器件特征碼,000表示EEPROM的芯片地址,最后一位0表示寫(xiě)操作),緊接著控制器釋放總線(xiàn),等待EEPROM給它的應(yīng)答。因?yàn)榉抡嬷皇悄M,并沒(méi)有接入EEPROM,所以應(yīng)答位呈現(xiàn)高阻態(tài)。在應(yīng)答的后面就是高字節(jié)的地址,等到再次收到應(yīng)答信號(hào)時(shí),控制器繼續(xù)發(fā)送低字節(jié)的地址位。這里的地址為0000_0000_0000_ 0000,共2 B,等再次收到應(yīng)答信號(hào)時(shí),控制器會(huì)發(fā)送單字節(jié)的數(shù)據(jù)0000_0001,將其寫(xiě)入相應(yīng)的存儲(chǔ)空間上。收到來(lái)自EEPROM的應(yīng)答后,控制器產(chǎn)生停止信號(hào),結(jié)束操作。圖6是控制器讀EEPROM操作,它與寫(xiě)操作不同的是在寫(xiě)入控制字和高低字節(jié)地址后,控制器會(huì)產(chǎn)生新的啟動(dòng)信號(hào),緊接著寫(xiě)入1010_0001,最后的1表示是讀操作,這時(shí)控制器會(huì)釋放總線(xiàn),等收到應(yīng)答后繼續(xù)釋放總線(xiàn),以讀取EEPROM中的數(shù)據(jù);1 B的數(shù)據(jù)收完后,控制器產(chǎn)生一個(gè)非應(yīng)答信號(hào)并緊接著產(chǎn)生停止信號(hào),表示讀數(shù)據(jù)任務(wù)結(jié)束。
4 結(jié)論
利用I2C總線(xiàn)協(xié)議設(shè)計(jì)出EEPROM讀寫(xiě)控制器,與專(zhuān)用的I2C接口芯片相比,有配置靈活、使用方便、可移植性強(qiáng)的特點(diǎn),除了滿(mǎn)足EEPROM的讀寫(xiě)操作,還可滿(mǎn)足其他I2C總線(xiàn)器件的讀寫(xiě)要求。電路仿真完成后,在FPGA上成功實(shí)現(xiàn)EEPROM的讀寫(xiě)操作,通信正常,滿(mǎn)足要求。
參考文獻(xiàn)
[1] Philips Semiconductors. The I2C-bus Specification Version 2.1[Z]. 2000.
[2] 夏宇聞.Verilog數(shù)字系統(tǒng)設(shè)計(jì)教程[M].北京:北京航空航天大學(xué)出版社,2013.