基于CPLD的系統(tǒng)中I2C總結(jié)的設(shè)計
對有些基于CPLD的系統(tǒng),要與帶有I2C總線接口的外圍器件連接,實現(xiàn)起來相對復雜一些。為實現(xiàn)系統(tǒng)中的I2C總線接口,可以另外引入單片機,也可以采用PCF8584或者PCA9564器件(PHILIPS公司推出的專用I2C總線擴展器)進行擴展,但這樣會增加系統(tǒng)成本,使系統(tǒng)冗余復雜。像ALTERA、XILINX等一些大公司有專用的基于CPLD器件的I2C總線IP核,但這些IP核的通用性不強,需要的外圍控制信號較多,占用系統(tǒng)很大的資源,因此直接采用這種IP核不可取。
鑒于此,依照I2C總線協(xié)議的時序要求,在基于CPLD的系統(tǒng)中開發(fā)了自己的I2C總線IP核。對于一些帶有I2C總線接口的外圍器件較少、對I2C總線功能要求較簡單的CPLD系統(tǒng),自主開發(fā)IP核顯得既經(jīng)濟又方便。
1 I2C總線的協(xié)議
I2C總線僅僅依靠兩根連線就實現(xiàn)了完善的全雙工同步數(shù)據(jù)傳送:一根為串行數(shù)據(jù)線(SDA),一根為串行時鐘線(SCL)。該總線協(xié)議有嚴格的時序要求??偩€工作時,由時鐘控制線SCL傳送時鐘脈沖,由串行數(shù)據(jù)線SDA傳送數(shù)據(jù)??偩€傳送的每幀數(shù)據(jù)均為一個字節(jié)(8 bit),但啟動I2C總線后,傳送的字節(jié)個數(shù)沒有限制,只要求每傳送一個字節(jié)后,對方回應一個應答位(Acknowledge Bit)。發(fā)送數(shù)據(jù)時首先發(fā)送數(shù)據(jù)的最高位(MSB)。
I2C總線協(xié)議規(guī)定,啟動總線后第一個字節(jié)的高7位是從器件的尋址地址,第8位為方向位("0"表示主器件對從器件的寫操作;"1"表示主器件對從器件的讀操作),其余的字節(jié)為操作的數(shù)據(jù)。總線每次傳送開始時有起始信號,結(jié)束時有停止信號。在總線傳送完一個或幾個字節(jié)后,可以使SCL線的電平變低,從而使傳送暫停。 圖1列出了I2C總線上典型信號的時序,圖2表示I2C總線上一次完整的數(shù)據(jù)傳送過程。

依據(jù)I2C總線的傳輸協(xié)議,總線工作時的具體時序如下:
起始信號(S):在時鐘SCL為高電平期間,數(shù)據(jù)線SDA出現(xiàn)由高電平向低電平的變化,用于啟動I2C總線,準備開始傳送數(shù)據(jù);
停止信號(P):在時鐘SCL為高電平期間,數(shù)據(jù)線SDA出現(xiàn)由低電平向高電平的變化,用于停止I2C總線上的數(shù)據(jù)傳送;
應答信號(A):I2C總線的第9個脈沖對應應答位,若SDA線上顯示低電平則為總線"應答"(A),若SDA線上顯示高電平則為"非應答"(/A);
數(shù)據(jù)位傳送: I2C總線起始信號或應答信號之后的第1~8個時鐘脈沖對應一個字節(jié)的8位數(shù)據(jù)傳送。在脈沖高電平期間,數(shù)據(jù)串行傳送;在脈沖低電平期間,數(shù)據(jù)準備,允許總線上數(shù)據(jù)電平變化。
2 應用實例
2.1 實例模型介紹
現(xiàn)舉某應用實例,要求對顯示器的視頻信號進行采集、處理和再顯示,整個系統(tǒng)采用CPLD器件進行控制。信號采集采用A/D公司的專用視頻采集芯片AD9883AD9883,該芯片在使用前需要依據(jù)實際的功能指標進行初始化。初始化過程依靠AD9883的SDA和SCL兩引腳進行。在系統(tǒng)中用CPLD器件?ALTERA公司的EPM3256AEPM3256A?實現(xiàn)初始化:按照I2C總線協(xié)議向AD9883的19個內(nèi)部寄存器(01H~13H)寫入19組固定的8位數(shù)據(jù);第14H寄存器為只讀型同步檢測寄存器,僅用于檢測幾個關(guān)鍵的數(shù)據(jù)設(shè)置。
可見該I2C總線模型如下:單主操作,只實現(xiàn)簡單的寫和讀操作(亦可只有寫操作,只是硬件調(diào)試的時候會麻煩些),寫地址連續(xù),沒有競爭和仲裁,是很簡單的I2C總線系統(tǒng)。由此設(shè)計了如圖3所示的IP核。其中,RESET為復位信號,CLK為系統(tǒng)時鐘。

為了軟件仿真方便,把雙向數(shù)據(jù)線SDA用分離的兩條線模擬:SDA為數(shù)據(jù)輸出,SDAACK為SDA的應答信號。軟件仿真成功后,只要把SDA設(shè)置為雙向,稍微修改一下程序就可以向CPLD器件下載,進行實際應用。
對AD9883內(nèi)部地址連續(xù)的寄存器進行初始化,I2C總線上傳輸?shù)臅r序信號依次為:開始信號(S);從器件地址和寫操作位(SLAW);內(nèi)部寄存器基地址(Base Address);寫入基地址的數(shù)據(jù)(Data0);寫入下一地址(Base Address+1)的數(shù)據(jù)(Data1);寫入地址(Base Address+2)的數(shù)據(jù)(Data2);……;寫入地址(Base Address+18)的數(shù)據(jù)(Data18);停止信號(P)。
針對AD9883,如果電路中的A0引腳(55#)接電源,則SLAW="10011001";Base Address="00000001",Data0~Data18是依據(jù)實際需要寫入的初始化數(shù)據(jù)。
2.2 IP核程序的編寫
整個程序用VHDL語言編制,SCL輸出時鐘的設(shè)計是基于CLK輸入時鐘的64分頻的。程序由三個狀態(tài)組成:開始(START)、轉(zhuǎn)換(SHIFT)和應答(ACK)。狀態(tài)定義如下:
type states is (start,shift,ack);??
signal my_states ?states;
?
下面給出部分進程的源代碼以供參考。
2.2.1開始信號的產(chǎn)生
PROCESS(clk)?
if clk'event and clk='1' then
TWCR<=DATAIN;?
SCL<='1';
else
TWCR<=(others=>'0');??
end if;?
if TWCR="10000000" then --比較寄存器TWCR的開始
值設(shè)置(由用戶決定)
STRB<='1';?
end if?;
if STRB='1' then --開始條件
INT<=INT+"000001";? --INT為時鐘脈沖計數(shù)
if INT<="011000" then --產(chǎn)生SDA的下降沿
SDA<='1';?
else
SDA<='0';?
end if;?
if INT>="011110" then --STRB歸0,保證只產(chǎn)生
一次開始信號
STRB <='0';?
INT<="00000?quot;;?
end if;?
end if;
?
等所有的初始化數(shù)據(jù)傳輸完畢后即產(chǎn)生停止信號,過程與上面相類似,在此省略。
2.2.2 數(shù)據(jù)轉(zhuǎn)換過程
數(shù)據(jù)轉(zhuǎn)換過程采用移位傳輸,傳輸8位之后即進入應答狀態(tài)。
when shift=>
if cnt="010000" then --cnt為clk脈沖計數(shù),由
實際的時鐘頻率決定cnt的值
COUNT<=COUNT+"0001";? --COUNT為數(shù)據(jù)移位個
數(shù)計數(shù)?MSR為移位寄存器
MSR<=MSR(6 downto 0)&txtag;?
txtag<='0';?
if COUNT="1000" then
my_states<=ack;?
TACK<='1';? --TACK為應答標志位
else
SDA<=MSR(7);??
my_states<=shift;?
TACK<='0';?
end if;?
end if;?
2.2.3 數(shù)據(jù)輸入
一般情況下,I2C總線傳輸?shù)臄?shù)據(jù)要由外部ROM或其它專門的數(shù)據(jù)存儲區(qū)來存儲,但在數(shù)據(jù)相對固定且數(shù)據(jù)量不是很大的情況下,可以將初始化的數(shù)據(jù)寫在程序中,這樣可減少頻繁的數(shù)據(jù)交換,簡化操作。AD9883的初始化數(shù)據(jù)就屬于這種情況,可以通過檢測應答信號來改變輸入的值。程序如下: PROCESS(clk)? --數(shù)據(jù)輸入
if clk'event and clk='1' then
CASE ackint IS --ackint為應答計數(shù),每應答
一次,輸入改變一次
when "00000"=> DATAIN<="10000000";?
when "00001"=> DATAIN<="01010010";?
when "00010"=> DATAIN<="11010000";?
……
when "10010"=> DATAIN<="00000000";?
when "10011"=> DATAIN<="00000000";?
when others=> DATAIN<="ZZZZZZZZ";?
END CASE;?
end if;?
2.3 仿真結(jié)果
把自主開發(fā)的IP核置于MAX+PLUS II 10.0開發(fā)環(huán)境下,選用EPM3128ATC100-10器件,經(jīng)過編譯、調(diào)試與仿真,證明該程序符合設(shè)計要求。圖4是模擬產(chǎn)生開始信號并傳輸兩組二進制數(shù)據(jù)"10011001"和"10101010"(十進制表示為153和170)的仿真波形。圖5是傳輸數(shù)據(jù)"10011001"后沒有應答時的仿真結(jié)果,此時總線處于暫停狀態(tài)。

仿真完成后,通過編程電纜將pof文件下載到實際電路的EPM3128ATC100-10EPM3128ATC100-10中,然后對AD9883AD9883進行初始化,結(jié)果工作正常,這進一步驗證了采用該自主開發(fā)的IP核完全可滿足I2C總線的時序要求,能實現(xiàn)I2C總線的功能。
參考文獻:
[1].AD9883datasheethttp://www.dzsc.com/datasheet/AD9883_251913.html.
[2].EPM3256Adatasheethttp://www.dzsc.com/datasheet/EPM3256A_301030.html.
[3].EPM3128ATC100-10datasheethttp://www.dzsc.com/datasheet/EPM3128ATC100-10_1096979.html.
來源:零八我的愛0次