I2C總線控制器的VHDL設(shè)計(jì)及實(shí)現(xiàn)
摘 要:本文用VHDL設(shè)計(jì)了一個(gè)簡潔而實(shí)用的I2C總線控制器,介紹了詳細(xì)的設(shè)計(jì)思路和在FPGA中的實(shí)現(xiàn),并給出了在嵌入式系統(tǒng)設(shè)計(jì)中的使用方法。
關(guān)鍵詞:I2C總線;VHDL;FPGA
引言
I2C總線以其接口簡單、使用靈活等突出優(yōu)點(diǎn)在數(shù)字系統(tǒng)中獲得了廣泛的應(yīng)用。尤其在嵌入式系統(tǒng)中,I2C總線被普遍用來連接CPU/MCU和外圍器件。I2C總線規(guī)范經(jīng)過十幾年的實(shí)踐,發(fā)展了多層標(biāo)準(zhǔn)。從傳輸速率上劃分,有標(biāo)準(zhǔn)模式(100Kbit/s),快速模式(400Kbit/s),高速模式(3.4Mbit/s);從尋址范圍上劃分有7位地址模式和10位地址模式。本文使用VHDL語言設(shè)計(jì)的控制器模塊采用標(biāo)準(zhǔn)速率、7位地址的模式,主要應(yīng)用在嵌入式系統(tǒng)中,給CPU/MCU提供一個(gè)操作I2C器件的簡易平臺(tái),以彌補(bǔ)某些CPU/MCU功能的不足。
功能定義
I2C總線的接口非常簡單,只需一根數(shù)據(jù)線(SDA)和一根時(shí)鐘線(SCL)。I2C器件可以工作于主件(Master)模式和從件(Slaver)模式,但I(xiàn)2C總線上同時(shí)只能有一個(gè)主件和多個(gè)從件,每次傳輸規(guī)定由主件發(fā)起,通過從件地址(Slaver Address)訪問從件。設(shè)計(jì)時(shí)本著簡單實(shí)用的原則,限定本模塊只工作于Master模式。
端口定義
entity I2C_CTRL is
port(
-- 系統(tǒng)信號(hào)
nReset: in STD_LOGIC;-- 系統(tǒng)復(fù)位信號(hào)端
CLK: in STD_LOGIC; -- FPGA內(nèi)部系統(tǒng)時(shí)鐘端
-- 控制信號(hào)
ADRS: in STD_LOGIC_ VECTOR(4 downto 2); -- 地址線,3位(8個(gè)32位地址)
Din: in STD_LOGIC_ VECTOR(7 downto 0); -- 數(shù)據(jù)輸入線,8位
Dout: out STD_LOGIC_ VECTOR(7 downto 0); -- 數(shù)據(jù)輸出線,8位
nCS: in STD_LOGIC; --片選使能端
nWR: in STD_LOGIC; --寫使能端
-- I2C總線信號(hào)
SDA: inout STD_LOGIC; --串行數(shù)據(jù)輸入輸出端,輸出有三態(tài)
SCL: out STD_LOGIC --時(shí)鐘輸出端,三態(tài)輸出
);
end I2C_CTRL;
寄存器定義
本模塊的寄存器定義參照Motorola公司ColdFire系列MCU MCF5307的I2C控制器,共定義了3個(gè)寄存器,長度均為8位,采用32位編址,如表1所示。
時(shí)序狀態(tài)機(jī)
本模塊根據(jù)I2C總線規(guī)范的時(shí)序標(biāo)準(zhǔn)(見圖1),劃分一個(gè)傳輸周期為8個(gè)狀態(tài),狀態(tài)轉(zhuǎn)換如圖2所示。
進(jìn)程設(shè)計(jì)
本模塊全部采用同步時(shí)序設(shè)計(jì)。VHDL時(shí)序仿真見圖3,限于篇幅,不提供VHDL原程序。下面只對(duì)每個(gè)進(jìn)程的關(guān)鍵點(diǎn)進(jìn)行說明。
時(shí)鐘進(jìn)程
本模塊設(shè)定FPGA分配給I2C模塊的系統(tǒng)時(shí)鐘(CLK)為20MHz,而標(biāo)準(zhǔn)模式的I2C總線操作速率(SCL的速率)為100KHz,需要對(duì)系統(tǒng)時(shí)鐘進(jìn)行分頻?;赩HDL的同步設(shè)計(jì)需要,本地時(shí)鐘頻率必須為SCL速率的整數(shù)倍,本模塊取兩倍值,因此本地時(shí)鐘頻率設(shè)為200KHz。定義6bit定時(shí)器timer,對(duì)系統(tǒng)時(shí)鐘的上升沿進(jìn)行計(jì)數(shù)。
系統(tǒng)復(fù)位時(shí)timer清零。當(dāng)CLK上升沿時(shí),timer值減1。當(dāng)timer=0時(shí)賦值100,對(duì)20MHz的系統(tǒng)輸入時(shí)鐘進(jìn)行100分頻產(chǎn)生200KHz的本地時(shí)鐘。
為滿足對(duì)總線的運(yùn)行狀態(tài)進(jìn)行進(jìn)一步的細(xì)分,使用一個(gè)5bit的step信號(hào)對(duì)運(yùn)行進(jìn)度進(jìn)行計(jì)數(shù),每個(gè)本地時(shí)鐘到達(dá)時(shí),step加1。
CPU讀寄存器進(jìn)程
系統(tǒng)復(fù)位時(shí)Dout端口清零。在片選信號(hào)nCS有效的情況下,當(dāng)CLK上升沿時(shí),對(duì)地址總線ADRS譯碼,把指定地址的寄存器內(nèi)容送到Dout端口。
CPU寫寄存器進(jìn)程
系統(tǒng)復(fù)位時(shí),初始化I2CR和I2DO。在片選信號(hào)nCS和nWR同時(shí)有效的情況下,當(dāng)CLK上升沿時(shí),讀取Din端口的信號(hào),存入被ADRS譯碼選中的寄存器。
狀態(tài)標(biāo)志改寫進(jìn)程
系統(tǒng)復(fù)位時(shí),初始化狀態(tài)標(biāo)志。運(yùn)行時(shí)根據(jù)狀態(tài)機(jī)和step的值改寫狀態(tài)標(biāo)志。其中I2SR[IIF]因?yàn)橥瑫r(shí)可以由CPU改寫,安排另外一個(gè)獨(dú)立的進(jìn)程。
狀態(tài)機(jī)賦值進(jìn)程和狀態(tài)機(jī)轉(zhuǎn)換進(jìn)程
系統(tǒng)復(fù)位時(shí),狀態(tài)為IDEL。當(dāng)檢測(cè)到MSTA=1時(shí),進(jìn)入START狀態(tài),保持4個(gè)本地時(shí)鐘周期,進(jìn)入READY狀態(tài),根據(jù)MTX的值,進(jìn)入SENDING或RECEVING狀態(tài),等待ICF=1時(shí),表明傳輸結(jié)束,進(jìn)入WAITING狀態(tài)。根據(jù)IIF或者M(jìn)STA是否被清除,決定繼續(xù)下一個(gè)傳輸或者退到STOP狀態(tài)。STOP狀態(tài)保持3個(gè)本地時(shí)鐘周期,返回IDEL狀態(tài)。
SCL線進(jìn)程和SDA線進(jìn)程
系統(tǒng)復(fù)位時(shí)SCL線輸出高阻,運(yùn)行時(shí)按照狀態(tài)機(jī)和step的值改寫SCL線。當(dāng)進(jìn)入傳輸狀態(tài)(SENDING或RECEIVING)時(shí),step[0]=0輸出高阻,step[0]=1輸出低電平。
系統(tǒng)復(fù)位時(shí)SDA線輸出高阻,運(yùn)行時(shí)按照狀態(tài)機(jī)和step的值讀寫SDA線。
在FPGA中的實(shí)現(xiàn)
本I2C控制器模塊全部采用可綜合的VHDL語言設(shè)計(jì),通過Mentor公司的Leonardo Spectrum工具綜合,并在Altera公司的Cyclone FPGA中實(shí)現(xiàn)布線。
Leonardo Spectrum 2003b65綜合的結(jié)果是:
Device Utilization for EP1C6Q240C
Resource Used Avail Utilization
IOs 25 181 13.81%
LCs 171 5980 2.86%
Memory Bits 0 92160 0.00%
Clock Frequency Report
Clock : Frequency
CLK : 211.8 MHz
此處作為一個(gè)單獨(dú)的模塊進(jìn)行綜合,因此上述結(jié)果I/O口占用率包括了地址、數(shù)據(jù)總線和時(shí)鐘線等,實(shí)際使用時(shí)作為一個(gè)子模塊,這些信號(hào)線都在FPGA內(nèi)部。
模塊的使用說明
本模塊適合應(yīng)用在嵌入式系統(tǒng)中,作為CPU/MCU連接I2C器件的一個(gè)橋接器,使得CPU可以像操作普通存儲(chǔ)器一樣控制I2C器件。下面補(bǔ)充說明CPU/MCU操作本模塊的使用方法。
1) 每發(fā)起一次傳輸都必須先對(duì)I2C器件進(jìn)行尋址。不管是要從I2C器件里接收還是發(fā)送數(shù)據(jù),都必須先設(shè)置I2CR[MTX]以標(biāo)明是一個(gè)發(fā)送任務(wù),并在I2DR中填入要尋址的I2C器件的Slaver地址,再發(fā)送“開始傳輸”指令。只有在傳輸完地址之后,再按需要改寫I2CR[MTX]位來實(shí)現(xiàn)接收或者發(fā)送。如果發(fā)送地址之前就試圖讀寫I2C總線將得不到預(yù)期的結(jié)果。
2) 在一次傳輸完成之后,將置位中斷標(biāo)記I2SR[IIF]。中斷標(biāo)記必須由軟件清除,在標(biāo)記被清除之后,控制器將自動(dòng)讀取I2CR,進(jìn)行下一輪傳輸。如果要改變傳輸方式,應(yīng)該在清除中斷標(biāo)記I2SR[IIF]之前改寫I2CR寄存器。
3) 對(duì)reSTART指令的執(zhí)行與I2C總線協(xié)議規(guī)范不盡相同。只有在傳輸指令沒有被結(jié)束(即在發(fā)送reSTART指令之后沒有發(fā)送過STOP指令)的狀態(tài)下設(shè)置I2CR[RSTA]才能產(chǎn)生一個(gè)reSTART指令,否則無效。而且每次需要reSTART操作時(shí),必須再次重復(fù)設(shè)置I2CR[RSTA]才能生效。這樣解釋reSTART指令的目的是,可以方便實(shí)現(xiàn)一些EEPROM器件的“選擇/任意讀數(shù)”模式。
結(jié)語
本文設(shè)計(jì)的I2C控制器非常適用于以“MCU+FPGA”為模式的嵌入式系統(tǒng)中。當(dāng)MCU不具有I2C控制功能,而使用I/O口模擬又占用較多資源時(shí),用FPGA實(shí)現(xiàn)對(duì)I2C器件的控制成為最理想的選擇。通常這種情況下,針對(duì)在I2C總線的地位來說,MCU只需擔(dān)當(dāng)主件(Master模式),I2C器件只充當(dāng)從件(Slaver模式),而且一般的器件都只工作于標(biāo)準(zhǔn)速率。因此,若采用FPGA廠商提供的標(biāo)準(zhǔn)I2C控制器IP,會(huì)造成資源浪費(fèi)。而自行設(shè)計(jì)一個(gè)控制器就顯得更為經(jīng)濟(jì)實(shí)用了?!?/P>
參考文獻(xiàn)
1 The I2C-Bus Specification, Version 2.1, Philips Semiconductors, 2000.1
2 MCF5307 ColdFire Integrated Microprocessor User誷 Manual, Rev 2.0, Motorola, Inc., 2000.8
評(píng)論