1 引言 隨著(zhù)單片機控制系統的不斷擴大以及控制功能不斷增多,有限的單個(gè)單片機通用I/O口已不能滿(mǎn)足同一系統中控制多個(gè)受控對象需要,隨著(zhù)FC總線(xiàn)研究的深入,用I2C總線(xiàn)擴展單片機I/O口的方法在全自動(dòng)、半自動(dòng)儀器的開(kāi)發(fā)領(lǐng)域得到了廣泛應用,本文介紹了一個(gè)測試系統通過(guò)FC總線(xiàn)擴展I/O口實(shí)現了系統的多個(gè)功能。給出了系統的硬件連接以及Atmega128與三個(gè)Atmega168之間的軟件通信流程圖。 2 系統的硬件結構 圖1是作者所研究的測試系統的整體框圖,本系統中主要芯片PHILIPS公司的LPC2292,在此系統中鍵盤(pán)上其中三個(gè)按鈕分別控制三個(gè)電機,系統的主要功能是LPC2292將掃描到的鍵盤(pán)信息發(fā)給Atmega128單片機,Atmega128單片機通過(guò)I2C總線(xiàn)尋址Atmega168,并向被尋址的Atmega168發(fā)送電機控制命令,最后,電機根據Atmega168控制策略正常運行。電機啟動(dòng)同時(shí),數據采集模塊也開(kāi)始正常運行,數據采集模塊把采到數據送到LPC2292的A/D轉換接口,然后將ADC輸出的數據發(fā)送到LCD。系統中的撥碼開(kāi)關(guān)用于設置相應的Atmega168單片機的地址,當單片機Atmega128接收到LPC2292發(fā)來(lái)的控制命令時(shí),通過(guò)I2C總線(xiàn)尋址Atmega168,當某個(gè)Atmega168的地址與Atmega128廣播地址相同時(shí),它就開(kāi)始根據Atmega128發(fā)送的命令控制電機開(kāi)始工作。 ![]() 圖1基于I2C總線(xiàn)的I/O擴展框圖 3 I2C總線(xiàn) I2C總線(xiàn)是PHILIPS公司推出的芯片間串行數據傳輸總線(xiàn),軟、硬件協(xié)議十分巧妙,2根線(xiàn)(SDA,SCL)HP可實(shí)現完善的全雙工同步數據傳送,能夠十分方便地構成單主系統或多主系統和外同器件擴展系統。不過(guò),多主系統(即系統中有多個(gè)I2C總線(xiàn)接口的單片機)會(huì )出現多主競爭的復雜狀態(tài)。I2C器件是把I2C的協(xié)議植入器件的I/O接口,使用時(shí)器件直接掛到I2C總線(xiàn)上,這一特點(diǎn)給用戶(hù)在設計應用系統時(shí)帶來(lái)了極大的方便。I2C器件無(wú)須片選信號,是否選中是由主器件發(fā)出的I2C從地址決定的。 所有掛到I2C總線(xiàn)的外圍器件,各自都有一個(gè)唯一確定的地址。任何時(shí)刻總線(xiàn)上只有一個(gè)主控器件對總線(xiàn)實(shí)行控制權,分時(shí)實(shí)現點(diǎn)對點(diǎn)的數據傳送。I2C總線(xiàn)上所有外闈器件都有規范的器件地址,器件地址由7位組成,它和1位方向位(R/W)構成了I2C總線(xiàn)器件的尋址字節SLA,格式如下: ![]() 器件地址(A6,A5,A4,A3)是I2C總線(xiàn)外圍接口器件同有的地址編碼(4位或5位),器件出廠(chǎng)時(shí)已固化好。引腳地址(A2,A1,A0)和器件在電路中的實(shí)際接法有關(guān)(地址線(xiàn)、電源或地),形成地址數據。數據方向位(R/W)規定了總線(xiàn)上的主節點(diǎn)對從節點(diǎn)的數據傳送方向,當(R/W)位置1時(shí)接收,當(R/W)為0時(shí)發(fā)送。圖1中的撥碼開(kāi)關(guān)設置了從單片機Atmega168的地址,也就是從機地址的低三位(A2,AI,A0),當某個(gè)撥碼開(kāi)關(guān)的某個(gè)開(kāi)關(guān)閉合時(shí),相應的地址位為零,否則相應位為1,因此可以通過(guò)撥碼開(kāi)關(guān)上開(kāi)關(guān)的狀態(tài)來(lái)設定從單片機Atmega168的地址,比如某個(gè)撥碼開(kāi)關(guān)與A0、A2位對應的開(kāi)關(guān)閉合,與Al對應的開(kāi)關(guān)斷開(kāi),那么這個(gè)單片機地址的低三位為010。 4 I2C通信的流程圖 根據I2C總線(xiàn)的傳輸協(xié)議規范和硬件連接,作者給出了如圖2和圖3基本程序流程圖和部分程序。開(kāi)發(fā)語(yǔ)言為c語(yǔ)言,與匯編語(yǔ)言相比,可以提高軟件的執行速度。 4.1 主機發(fā)送/從機接收I2C子程序流程圖 圖2和圖3給出了主機發(fā)送,從機接收I2C子程序流程圖,通過(guò)I2C總線(xiàn)發(fā)送/接收數據時(shí),I2C總線(xiàn)的控制寄存器的中斷位必須先置位,為了避免因為某種原因不能使控制寄存器的中斷位置位而導致程序進(jìn)入死循環(huán),作者在I2C總線(xiàn)通信程序發(fā)送/接收數據前編寫(xiě)了中斷循環(huán)等待和錯誤處理程序,大大提高了程序的可靠性,具體程序如下: while(!(TWCR & (1< 應用I2C總線(xiàn)發(fā)送數據時(shí),作者采用了狀態(tài)位查詢(xún)方法,并且給出了錯誤標志置位、錯誤跳出程序,下面的程序是發(fā)送從機地址的部分程序: switch(TWSR & 0XF8) { case Oxl8: flag=0; break; case 0x20:flag=1; break; case 0x38:flag=l; break; default:return 0: } if(flag) continue; ![]() 圖2 I2C主機發(fā)送程序框圖 程序中的flag=0表示從機地址發(fā)送成功,flag=1表示從機地址發(fā)送失敗,當TWSR寄存器中的狀態(tài)碼為0x18時(shí),表明從機地址已發(fā)送,并且接收到ACK,同時(shí)錯誤標志“flag”置0,下一步通過(guò)心發(fā)送數據,當TWSR寄存器中的狀態(tài)碼為0x20時(shí),表明從機地址已發(fā)送,但是接收到NO ACK,同時(shí)錯誤標志”flag”置1,下一步執行“if(flag)continue;”語(yǔ)句,結束本次循環(huán),當TWSR寄存器中的狀態(tài)碼為0x38時(shí),表明從機地址仲裁失敗,同時(shí)錯誤標志“flag”置1,下一步執行“if(flag)continue;"語(yǔ)句,結束本次循環(huán)?偩(xiàn)將釋放,并進(jìn)入未尋址從機模式,總線(xiàn)空閑后將發(fā)送“start”。程序中“if(flag)continue;”語(yǔ)句使得當數據發(fā)送失敗時(shí),結束本次循環(huán),返回到開(kāi)始等待發(fā)送命令,這樣避免了由于偶爾數據發(fā)送失敗造成整個(gè)程序無(wú)法運行,甚至整個(gè)設備無(wú)法運行,因而,用“if(flag)continue;”語(yǔ)句結束錯誤傳輸?商岣逫2C通信的質(zhì)量,同時(shí)也提高了使用I2C總線(xiàn)通信的設備的效率。 ![]() 圖3 從機接收流程圖 4.2 編程中的注意事項 a)在主機或從機初始化時(shí),一定要設定數據傳輸方向; b)由于每次發(fā)送/接收數據時(shí)TWCR寄存器的中斷標志位必須置位,因此程序中要有等待TWCR寄存器中斷位置位程序,同時(shí),為了避免由于某種原因導致中斷位不能置位造成等待程序進(jìn)入死循環(huán),在等待中斷位置位程序中要有等待超時(shí)返回程序。 c)I2C總線(xiàn)的使用,除了基本的啟動(dòng)、結束、應答、非應答子程序外,還應有應答位檢查、發(fā)送和接收單字節、發(fā)送和接收多字節等子程序。 5 結論 作者在程序流程的每個(gè)關(guān)鍵部分都設置了錯誤查詢(xún)和錯誤處理,使得I2C程序能夠從錯誤中自動(dòng)恢復,避免了由于I2C通信導致的錯誤而使得系統無(wú)法正常工作,文中還給出了部分發(fā)送子程序和編程注意事項。對于圖2和圖3的I2C通信流程,作者已在多個(gè)科研項目中進(jìn)行了編程使用。實(shí)踐證明,按上述流程編寫(xiě)I2C通信程序,主從單片機之間的通信非?煽。 本文作者創(chuàng )新點(diǎn):程序流程的每個(gè)關(guān)鍵部分都設置了錯誤查詢(xún)和錯誤處理,使心通信能夠從錯誤中自動(dòng)恢復,提高了使用I2C通信的可靠性,并且給出了避免死循環(huán)的錯誤處理程序。 作者:賈朱紅,張曉冬 來(lái)源:《微計算機信息》(嵌入式與SOC)2009年第3-2期 |