向繼文
(吉首大學(xué)信息科學(xué)與工程學(xué)院,湖南 吉首 416000)
I2C總線是Philips公司推出的芯片間串行傳輸總線,以2根連線(SDA和SCL)即可實(shí)現(xiàn)完善的全雙工同步數(shù)據(jù)傳送,具有規(guī)范完整、結(jié)構(gòu)獨(dú)立和使用簡單等特點(diǎn)[1],最高傳輸速率可達(dá)400 kbps[2].I2C總線最初是為音頻和視頻設(shè)備開發(fā)的[3].如今,支持I2C技術(shù)的控制器和外圍器件的種類很多,I2C總線技術(shù)在各類電子產(chǎn)品、家用電器和通信設(shè)備中得到了廣泛應(yīng)用.然而,I2C總線器件與主控器件之間的線路連接雖然簡單,但是相應(yīng)的軟件卻較復(fù)雜,其控制程序調(diào)試有一定的難度.針對這個問題,筆者擬設(shè)計(jì)一款I(lǐng)2C器件的控制電路,主控制器采用單片機(jī),并利用Proteus軟件對所設(shè)計(jì)的I2C器件控制電路進(jìn)行仿真.
I2C總線只要求2條信號線,一條是串行數(shù)據(jù)線SDA,另一條是串行時(shí)鐘線SCL[4].2條信號線都是雙向的,各I2C器件的數(shù)據(jù)線均連接到SDA總線上,各I2C器件的時(shí)鐘線均連接到SCL總線上,2條信號線均需要通過上拉電阻連接正電源.I2C總線與單片機(jī)的硬件連接結(jié)構(gòu)如圖1所示.
圖1 I2C總線與單片機(jī)的硬件連接結(jié)構(gòu)
支持I2C總線標(biāo)準(zhǔn)的外圍器件較多,常見的有A/D及D/A轉(zhuǎn)換器、SRAM及E2PROM存儲器、日歷時(shí)鐘芯片、LED/LCD驅(qū)動芯片和數(shù)字音頻處理芯片等.每個連接到I2C總線上的器件都有唯一的地址[5],器件地址碼為B3,B2,B1,B0,引腳地址為A2,A1,A0,方向控制位為R/W。
地址碼中的器件地址用于區(qū)分器件的大類類型,4位器件地址碼可以支持16個大類器件地址,這個地址由器件廠商給定.引腳地址共3位,最多可以支持8個同一類型的器件,由用戶根據(jù)實(shí)際情況通過物理連接設(shè)定.理論上,連接到I2C總線上的器件最多為16種類型共128個器件,但實(shí)際上是不可能的.這是因?yàn)镮2C總線沒有那么強(qiáng)的驅(qū)動能力,且連接到總線上的器件太多,引腳分布電容也會較大,從而使得信號的質(zhì)量下降,通信的誤碼率增大.方向控制位用于設(shè)定主器件(如單片機(jī))和從器件(如I2C存儲器)的數(shù)據(jù)傳送方向,為1時(shí)設(shè)定為主器件讀從器件傳送來的數(shù)據(jù),為0時(shí)設(shè)定為主器件對從器件進(jìn)行寫操作.以圖2所示的I2C存儲器為例,設(shè)定各器件的地址.
圖2 I2C存儲器與單片機(jī)的連接
存儲器芯片采用Atmel公司生產(chǎn)的AT24C02芯片,每片存儲容量為256 B,固定的器件地址碼為1010,引腳地址A2,A1,A0通過硬件連接設(shè)定.根據(jù)電路連接圖(圖2),可以得到各芯片的地址(表1).
表1 AT24C02芯片的讀寫地址
在I2C總線協(xié)議中,數(shù)據(jù)的傳輸必須由主器件發(fā)送的起始信號開始,由主器件發(fā)送的停止信號結(jié)束.總線信號包括4種類型:
(1)起始信號.當(dāng)時(shí)鐘線SCL為高電平時(shí),數(shù)據(jù)線SDA產(chǎn)生從高電平到低電平的跳變,要求SDA在跳變前高電平維持時(shí)間大于4.7 μs,跳變后低電平時(shí)間大于4 μs.
(2)停止信號.當(dāng)時(shí)鐘線SCL為高電平時(shí),數(shù)據(jù)線SDA產(chǎn)生從低電平到高電平的跳變,要求SDA在跳變前低電平維持時(shí)間大于4 μs,跳變后高電平時(shí)間大于4.7 μs.
(3)應(yīng)答信號.I2C總線每傳送1 Byte的數(shù)據(jù)后,在時(shí)鐘線SCL為高電平時(shí),由接收方將數(shù)據(jù)線SDA拉成低電平,表示數(shù)據(jù)傳輸正確,要求SCL高電平維持時(shí)間大于4 μs.
(4)數(shù)據(jù)信號.在起始信號與停止信號之間傳送的是數(shù)據(jù)信息,包括從器件的地址信息.數(shù)據(jù)信息以操作時(shí)序?yàn)閱挝贿M(jìn)行傳送,字節(jié)數(shù)沒有限制,但每個字節(jié)必須為8 bit,先發(fā)送高位,后發(fā)送低位,每個字節(jié)后面必須接收1個應(yīng)答信號.
在傳輸數(shù)據(jù)信息時(shí),數(shù)據(jù)線只允許在時(shí)鐘線SCL為低電平時(shí)改變,因?yàn)闀r(shí)鐘線為高電平時(shí)數(shù)據(jù)線的改變已經(jīng)做了定義,不能用于傳送數(shù)據(jù)信息.
Proteus軟件是英國Lab Center Electronics公司推出的EDA工具軟件,不僅具備其他 EDA工具軟件的仿真功能,還具備極好的仿真單片機(jī)及外圍器件的功能.采用Proteus軟件進(jìn)行仿真測試,有利于降低系統(tǒng)開發(fā)的軟硬件成本[6-7].本系統(tǒng)Proteus仿真電路如圖3所示.
圖3 Proteus仿真電路
仿真電路包括時(shí)鐘電路、復(fù)位電路、液晶顯示電路、中斷觸發(fā)電路和I2C存儲器電路等.仿真時(shí),首先運(yùn)行主程序,液晶模塊LCD1602顯示初始信息,并在主程序中調(diào)用I2C寫信息子程序,分別給3片AT24C02芯片寫入不同的信息;當(dāng)要讀出存儲器中的信息時(shí),按下單片機(jī)P3.2引腳外接的按鍵觸發(fā)外部中斷0,由外部中斷子程序調(diào)用相關(guān)子程序,分別將3片AT24C02芯片中原來寫入的信息讀出,并通過液晶模塊LCD1602加以顯示.
控制程序采用單片機(jī)匯編語言編寫,該程序能夠非常方便地通過C語言改寫.主要子程序包括液晶模塊相關(guān)子程序、I2C總線啟動子程序、I2C總線停止子程序、檢測應(yīng)答子程序、字節(jié)寫入子程序、多字節(jié)寫入子程序和字節(jié)讀出子程序等,在此僅介紹與I2C總線操作主要相關(guān)的子程序.
(1)總線啟動子程序.該子程序按照I2C總線時(shí)序和電平寬度要求編寫,完成I2C總線的啟動.
I2C_START:SETB SDA ∥拉高數(shù)據(jù)線
NOP
SETB SCL ∥拉高時(shí)鐘線
NOP ∥5條NOP指令延時(shí)
…
CLR SDA ∥拉低數(shù)據(jù)線
NOP ∥5條NOP指令延時(shí)
…
CLR SCL ∥拉低時(shí)鐘線
NOP
RET
(2)總線停止子程序.該子程序按照I2C總線時(shí)序和電平寬度要求編寫,完成I2C總線的停止.
I2C_STOP:CLR SDA
NOP
SETB SCL
NOP ∥5條NOP指令延時(shí)
…
SETB SDA
NOP ∥5條NOP指令延時(shí)
…
RET
(3)字節(jié)寫通用子程序.該子程序完成向存儲器芯片寫入1 Byte數(shù)據(jù),需要寫入的字節(jié)在累加器A中.
WRBYTE:MOV R0,#08H
WLP:RLC A ∥先發(fā)送高位,再發(fā)送低位
JC WR1
SJMP WR0
WR1:SETB SDA ∥寫1
NOP
SETB SCL
NOP ∥5條NOP指令延時(shí)
…
CLR SCL
SJMP RETURN
WR0:CLR SDA ∥寫0
NOP
SETB SCL
NOP ∥5條NOP指令延時(shí)
…
CLR SCL
RETURN:DJNZ R0,WLP ∥判斷1 B是否發(fā)送完畢
RET
(4)字節(jié)讀通用子程序.該子程序?qū)崿F(xiàn)讀存儲器芯片向單片機(jī)發(fā)送1 Byte數(shù)據(jù),讀出的字節(jié)放在累加器A中.
RDBYTE:MOV R0,#08H
RLP:SETB SDA
NOP
SETB SCL ∥時(shí)鐘線拉高,準(zhǔn)備接收數(shù)據(jù)
NOP
NOP
MOV C,SDA ∥讀數(shù)據(jù)
NOP
NOP
RLC A ∥讀取的數(shù)據(jù)移位到累加器A中
NOP
CLR SCL
DJNZ R0,RLP ∥判斷1 B是否接受完畢
RET
(5)外部中斷0子程序.該子程序?qū)崿F(xiàn)依次讀出3片存儲器芯片的內(nèi)容,并發(fā)送給液晶顯示器顯示.
RD_I2CRAM_INT:ACALL INIT ∥調(diào)用液晶顯示模塊初始化子程序
MOV A,#10000000B ∥設(shè)置液晶顯示第1行起始地址
MOV R1,#00H ∥設(shè)置芯片內(nèi)部讀起始地址
MOV R2,#16 ∥設(shè)置讀取的字節(jié)數(shù)
MOV R3,#10100000B ∥傳送1#片器件地址,寫操作
MOV R4,#10100001B ∥傳送1#片器件地址,讀操作
ACALL RD_I2CRAM ∥調(diào)用讀子程序,并顯示
MOV A,#11000000B ∥設(shè)置液晶顯示第2行起始地址
MOV R1,#0
MOV R2,#8
MOV R3,#10100010B ∥傳送2#片器件地址,寫操作
MOV R4,#10100011B ∥傳送2#片器件地址,讀操作
ACALL RD_I2CRAM
MOV A,#11001000B ∥設(shè)置3#片內(nèi)容顯示的起始地址
MOV R1,#0
MOV R2,#8
MOV R3,#10100100B ∥傳送3#片器件地址,寫操作
MOV R4,#10100101B ∥傳送3#片器件地址,讀操作
ACALL RD_I2CRAM
RETI
程序運(yùn)行時(shí),先顯示初始信息“HELLO HOW ARE YOU”(圖4),并調(diào)用寫信息子程序,對3個存儲器分別寫入不同的字符信息;當(dāng)按下P3.2引腳外接的按鍵觸發(fā)外部中斷0以后,由外部中斷程序調(diào)用相關(guān)子程序依次讀出3片存儲器芯片的內(nèi)容,并在液晶顯示器上顯示出來.仿真測試結(jié)果如圖5所示,由圖可見結(jié)果正確.
圖4 初始信息截圖
圖5 3片存儲器芯片的信息截圖
研究了I2C總線的硬件連接和數(shù)據(jù)傳輸協(xié)議,設(shè)計(jì)了一款有3個I2C存儲器的仿真電路,并利用Proteus軟件進(jìn)行了仿真測試.程序采用單片機(jī)匯編語言編寫,能滿足操作時(shí)序中高低電平對時(shí)間的要求,也能非常方便地改寫為C語言程序.采用通用子程序的方式完成程序的編寫,有利于移植到不同類型的I2C器件的程序開發(fā)中.根據(jù)系統(tǒng)功能的不同需求,在實(shí)際應(yīng)用中,可以改用12864之類的LCD顯示模塊,以便顯示更多的信息,還可以連接更多類型的I2C器件,實(shí)現(xiàn)更多的操作需求.