《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 可編程邏輯 > 業(yè)界動(dòng)態(tài) > 用Verilog HDL實(shí)現(xiàn)I2C總線功能

用Verilog HDL實(shí)現(xiàn)I2C總線功能

2008-09-11
作者:路永坤

??? 摘? 要: 簡(jiǎn)述了I2C總線的特點(diǎn);介紹了開(kāi)發(fā)FPGA時(shí)I2C總線模塊的設(shè)計(jì)思路;給出并解釋了用Verilog HDL實(shí)現(xiàn)部分I2C總線功能的程序,以及I2C總線主從模式下的仿真時(shí)序圖。

??? 關(guān)鍵詞: I2C總線? FPGA? Verilog HDL? 時(shí)序

?

??? 開(kāi)發(fā)FPGA時(shí),利用EDA工具設(shè)計(jì)芯片實(shí)現(xiàn)系統(tǒng)功能已經(jīng)成為支撐電子設(shè)計(jì)的通用平臺(tái),并逐步向支持系統(tǒng)級(jí)的設(shè)計(jì)方向發(fā)展。在軟件設(shè)計(jì)過(guò)程中,越來(lái)越強(qiáng)調(diào)模塊化設(shè)計(jì)。I2C總線是Philips公司推出的雙向兩線串行通訊標(biāo)準(zhǔn),具有接口線少?通訊效率高等特點(diǎn)。把I2C總線設(shè)計(jì)成相應(yīng)的模塊,有利于相關(guān)FPGA的開(kāi)發(fā)。目前有一些介紹相關(guān)開(kāi)發(fā)的資料[1],但都是利用VHDL語(yǔ)言或AHDL語(yǔ)言實(shí)現(xiàn)的。本文給出利用Verilog HDL語(yǔ)言設(shè)計(jì)的I2C總線模塊。

1 I2C總線概述

??? I2C總線系統(tǒng)由兩根總線即SCL(串行時(shí)鐘)線和SDA(串行數(shù)據(jù))線構(gòu)成。這種總線可以設(shè)計(jì)成很多種通訊配置,但本文只討論主從系統(tǒng)的應(yīng)用。主器件控制總線通訊,開(kāi)始/結(jié)束傳送?發(fā)送信息并產(chǎn)生I2C系統(tǒng)時(shí)鐘。在寫(xiě)操作過(guò)程中,從器件一旦被主控器件尋址,就執(zhí)行特定的相應(yīng)功能。在讀操作過(guò)程中,主控器件從從器件那里獲得數(shù)據(jù)。在整個(gè)主從傳送過(guò)程中,所有的事件都通過(guò)主控器件的SCL時(shí)鐘線達(dá)到同步。連到總線上的器件的接口形式必須是漏極開(kāi)路或集電極開(kāi)路輸出狀態(tài)。通過(guò)上拉電阻,使得兩根總線在空閑的狀態(tài)下都為高電平" title="高電平">高電平狀態(tài)。因此I2C總線上具有線與功能,即總線上的所有器件都達(dá)到高電平狀態(tài)時(shí),I2C總線才能達(dá)到高電平狀態(tài),從而使總線上的高速器件和慢速器件工作同步。

??? 在I2C協(xié)議中,從器件地址是一個(gè)唯一的7位地址。接下來(lái)是一個(gè)讀寫(xiě)方向標(biāo)志位,讀狀態(tài)是高電平?寫(xiě)狀態(tài)是低電平。

2 I2C模塊的設(shè)計(jì)與實(shí)現(xiàn)

??? 根據(jù)I2C協(xié)議中傳輸過(guò)程的特點(diǎn),I2C模塊可以劃分為字節(jié)發(fā)送模塊" title="發(fā)送模塊">發(fā)送模塊、字節(jié)接收模塊" title="接收模塊">接收模塊、開(kāi)始條件模塊、停止條件" title="停止條件">停止條件模塊。其中,字節(jié)發(fā)送模塊、字節(jié)接收模塊和停止條件模塊為基本模塊。在開(kāi)始條件模塊中,因?yàn)樾枰l(fā)送從器件地址,所以要調(diào)用字節(jié)發(fā)送模塊。

??? 下面給出用Verilog HDL語(yǔ)言[3]實(shí)現(xiàn)字節(jié)發(fā)送模塊的關(guān)鍵程序。相關(guān)變量的聲明在此略去。程序在Max+PlusII環(huán)境下編譯?調(diào)試?仿真。

??? assign en_sdao=tempen_sdao; //設(shè)置SDA三態(tài)輸出使能

????assign send_byte_over=tempsend_byte_over;

??? assign NO_ACK=tempNO_ACK;

??? assign sdao=tempsda;

??? assign sclo=tempscl;

??? always@(posedge send_byte_clk)

??? begin

??? case(send_byte_zt)

??? sendbit1:

??? begin

??? if(send_byte_num==0)

??? begin

??? shiftdata[7:0]=indata[7:0];

??? end

??? shiftdata=shiftdata << 1;

??? tempsda=shiftdata[8];

????tempscl=1;? ??????????????? //置SCL為高電平

??? send_byte_zt= delay_1;

??? send_byte_num=send_byte_num+1;

??? end

??? delay_1: ????????????????????? //延時(shí)三個(gè)周期

??? begin

??? if(delay_counter>=2)

??? begin

??? send_byte_zt = sendbit2;

??? delay_counter=0;

??? end

??? else

??? begin

??? delay_counter=delay_counter+1;

??? send_byte_zt = send_byte_zt;

??? end

??? end

??? sendbit2:

??? begin

??? tempscl=0; ???????????????????????? //SCL置零

??? send_byte_zt = delay_2;

??? end

??? delay_2: ???????????????????????????? //延時(shí)三個(gè)周期

??? begin

??? if(delay_counter>=2)

??? begin

??? send_byte_zt = sendbit3;

??? delay_counter=0;

??? end

??? else

??? begin

??? delay_counter=delay_counter+1;

??? send_byte_zt = send_byte_zt;

??? end

??? end

??? sendbit3: ????????????? ??//判斷是否字節(jié)中所有位都發(fā)送完畢

??? begin

??? if(send_byte_num<=8)

??? begin

??? send_byte_zt=sendbit1;

??? end

??? else

??? begin

??? send_byte_zt=ForACK1;

??? send_byte_num=0;

??? end

??? end

??? ForACK1:

??? begin

??? tempsda=1; ???????????????? //釋放數(shù)據(jù)線,等待應(yīng)答信號(hào)

??? send_byte_zt=delay_ACK;

??? end

??? delay_ACK: ???????????????? //延時(shí)

??? begin

??? if(delay_counter>=3)

??? begin

??? send_byte_zt = ForACK2;

??? delay_counter=0;

??? end

??? else

??? begin

??? delay_counter=delay_counter+1;

??? send_byte_zt = send_byte_zt;

??? tempscl=1;

??? end

??? end

??? ForACK2:

??? begin

??? send_byte_zt=AckYESNO;

??? tempen_sdao=0; ????????? ???//輸出SDA使能信號(hào),控制sdao和sdai

??? end

??? AckYESNO:

??? begin

??? if(sdai) ????????????????????????????? //如果應(yīng)答信號(hào)sdai為1,NO_ACK置1

??? begin

??? tempNO_ACK=1; ?????????????? //設(shè)置未應(yīng)答標(biāo)志信號(hào)

??? end

??? tempscl=0; ???????????????????????? //終止應(yīng)答位

??? send_byte_zt=Finish_delay;

??? end

??? Finish_delay: ????????????????????? //延時(shí)

??? begin

??? if(delay_counter>=2)

??? begin

??? tempsend_byte_over=1;

??? send_byte_zt = FinishACK1;

??? delay_counter=0;

??? end

??? else

??? begin

??? delay_counter=delay_counter+1;

??? send_byte_zt = send_byte_zt;

??? end

??? end

??? FinishACK1:

??? begin

??? send_byte_zt=sendbit1;

??? send_byte_num=0;

??? end

??? default:

??? begin

??? send_byte_zt=sendbit1;

??? send_byte_num=0;

??? end

??? endcase

??? end

??? 程序中sdao、sclo為輸出信號(hào),sdai為應(yīng)答信號(hào),en_sdao是對(duì)sdao和sdai進(jìn)行切換的信號(hào)。I2C總線具有SDA和SCL兩根信號(hào)線,所以在整個(gè)模塊設(shè)計(jì)中,把sdao/sclo和sdai/scli作為兩組信號(hào)。當(dāng)需要向外部SDA信號(hào)線上輸出信息時(shí),sdao連到SDA信號(hào)線上;當(dāng)需要從外部SDA信號(hào)線上讀入信息時(shí),置sdao成高阻態(tài),sdai連到SDA信號(hào)線上。en_sdao信號(hào)作為這一過(guò)程的切換信號(hào)。在程序中定義了一些狀態(tài)信號(hào):NO_ACK、send_byte_over。其中,NO_ACK信號(hào)判斷從器件是否對(duì)發(fā)送的信號(hào)給予了應(yīng)答。send_byte_over信號(hào)判斷字節(jié)是否傳輸完畢。這些信號(hào)可以傳遞給上一層設(shè)計(jì)模塊,以控制程序的流程。為了使I2C總線能夠有效地通訊,必須考慮信號(hào)的建立和保持時(shí)間,所以程序中設(shè)置了相應(yīng)的延時(shí)部分。另外,在以clk為觸發(fā)信號(hào)的過(guò)程模塊中,定義send_byte_clk信號(hào)為時(shí)鐘信號(hào)的兩倍頻信號(hào),并加入字節(jié)發(fā)送模塊使能信號(hào)start_send_byte控制模塊工作,由于篇幅所限,略去該過(guò)程模塊。

??? 字節(jié)發(fā)送模塊的仿真測(cè)試結(jié)果" title="測(cè)試結(jié)果">測(cè)試結(jié)果如圖1所示。

?

?

??? 根據(jù)I2C總線標(biāo)準(zhǔn),利用Verilog HDL很容易實(shí)現(xiàn)字節(jié)接收模塊?開(kāi)始條件模塊?停止條件模塊這三個(gè)模塊。圖2是數(shù)據(jù)發(fā)送過(guò)程的仿真測(cè)試結(jié)果。從器件的7位地址為101011,向從器件發(fā)送的數(shù)據(jù)為00010111。aensclo和aensdao分別是sclo/scli和sdao/sdai的切換信號(hào)。

?

?

??? 圖3是數(shù)據(jù)接收過(guò)程的仿真測(cè)試結(jié)果。從器件的7位地址為0011001,從器件發(fā)送的數(shù)據(jù)為11111111。ensclo和ensdao分別是sclo/scli和sdao/sdai的切換信號(hào)。

?

?

??? 將圖2和圖3所模擬的I2C總線時(shí)序與I2C總線協(xié)議中相關(guān)要求進(jìn)行比較,滿足I2C總線的時(shí)序要求。

??? 對(duì)各個(gè)模塊進(jìn)行多層次處理,形成I2C總線模塊。

??? 以該I2C總線模塊為基礎(chǔ),編寫(xiě)FPGA與AT24C01A(ATMEL公司生產(chǎn)的E2PROM)的通訊程序。然后把相關(guān)程序下載到EPF10K10LC84-3中,與AT24C01A進(jìn)行實(shí)際通訊實(shí)驗(yàn),效果良好。

參考文獻(xiàn)

1 李明峰,李沁遙. I2C器件接口IP核的CPLD設(shè)計(jì).單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2002,12.

2 The I2C-Bus Specification,Version 2.1.January 2000. http://www.philips.com,

3 王金明,楊吉斌. 數(shù)字系統(tǒng)設(shè)計(jì)與Verilog HDL. 北京:電子工業(yè)出版社,2002

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。