IIC總線原理及其在51單片機中的簡單應用
1. IIC總線基本概念
1.1總線概述
IIC總線是PHLIPS公司推出的一種串行總線,是具備多主機系統(tǒng)所需的包括總線裁決和高低速器件同步功能的高性能串行總線。
1.2總線結構
IIC總線是由數據線SDA和時鐘線SCL構成的串行總線,可發(fā)送和接收數據。在CPU與被控IC之間、IC與IC之間可以進行雙向傳送,最高傳送速率100kbps。各種被控制電路均并聯在這兩條總線上。
2. IIC總線協(xié)議
2.1數據傳輸中的主/從機
在多主機系統(tǒng)中,可能同時有幾個主機企圖啟動總線傳送數據。為了避免混亂, IIC總線要通過總線仲裁,以決定由哪一臺主機控制總線。連在每一個總線上的電路和模塊都有一個唯一地址,它們彼此之間只有簡單的Master/Slaver關系。
主機:控制時鐘線,產生啟動信號、時鐘信號、停止信號。控制線上的發(fā)送和接收節(jié)奏。
從機:按SCL線上的時鐘接收SDA線上的數據或發(fā)送數據到SDA線上。
2.2協(xié)議概述
IIC總線僅占用系統(tǒng)的兩個I/O口,一條作為串行數據線SDA,一條作為串行時鐘線SCL,線上外加上拉電阻,在不傳數據時SCL、 SDA總保持高電平。IIC總線通過上拉電阻接電源正極。當總線空閑時,兩根線均為高電平。連到總線上的任一器件輸出的低電平,都將使總線的信號變低,即各器件的SDA及SCL都是線“與”關系。CPU發(fā)出的控制信號分為地址碼和控制量兩部分,地址碼用來選址,即接通需要控制的電路,確定控制的種類;控制量決定該調整的類別(如對比度、亮度等)及需要調整的量。這樣,各控制電路雖然掛在同一條總線上,卻彼此獨立,互不相關。
2.3時序圖
完整的數據傳輸過程時序圖:
2.4信號類型
(1)開始信號:SCL為高電平時,SDA由高電平向低電平跳變,開始傳送數據。
(2)結束信號:SCL為高電平時,SDA由低電平向高電平跳變,結束傳送數據。
(3)應答信號:接收數據的IC在接收到8bit數據后,向發(fā)送數據的IC發(fā)出特定的低電平脈沖,表示已收到數據。CPU向受控單元發(fā)出一個信號后,等待受控單元發(fā)出一個應答信號,CPU接收到應答信號后,根據實際情況判斷是否繼續(xù)傳遞信號。若未收到應答信號,由判斷為受控單元出現故障。
(4)總線空閑:SCL和SDA都保持高電平的狀態(tài)
(5)總線忙:在數據傳送開始以后,SCL為高電平的時候,SDA的數據必須保持穩(wěn)定,只有當SCL為低電平的時候才允許SDA上的數據改變.
這些信號中,起始信號是必需的,結束信號和應答信號,都可以不要。IIC總線有兩根信號線,一根為SDA(數據線),一根為SCL(時鐘線)。任何時候時鐘信號都是由主控器件產生。
3. IIC總線數據傳輸格式
3.1字節(jié)傳送與應答:
每一個字節(jié)必須保證是8位長度。數據傳送時,先傳送最高位(MSB),每一個被傳送的字節(jié)后面都必須跟隨一位應答位(即一幀共有9位)。
3.2數據幀格式
IIC總線上傳送的數據信號是廣義的,既包括地址信號,又包括真正的數據信號。(注:下圖中有陰影部分表示數據由主機向從機傳送,無陰影部分則表示數據由從機向主機傳送。A表示應答, A非 表示非應答(高電平)。S表示起始信號,P表示終止信號。)
A. 主機向從機發(fā)送數據,數據傳送方向在整個傳送過程中不變
B. 主機在第一個字節(jié)后,立即從從機讀數據
C. 傳送過程中,當需改變傳送方向時,起始信號和從機地址都被重復產生一次,但兩次讀/寫方向位正好反相。
4. IIC總線多主機競爭的仲裁
總線上可能掛接有多個器件,有時會發(fā)生兩個或多個主器件同時想占用總線的情況,這種情況叫做總線競爭。IIC總線具有多主控能力,可以對發(fā)生在SDA線上的總線競爭進行仲裁,其仲裁原則是這樣的:當多個主器件同時想占用總線時,如果某個主器件發(fā)送高電平,而另一個主器件發(fā)送低電平,則發(fā)送電平與此時SDA總線電平不符的那個器件將自動關閉其輸出級?偩競爭的仲裁是在兩個層次上進行的。首先是地址位的比較,如果主器件尋址同一個從器件,則進入數據位的比較,從而確保了競爭仲裁的可靠性。由于是利用IIC總線上的信息進行仲裁,因此不會造成信息的丟失。
為何識別到“0”將丟失仲裁呢?因為對于OD門,只能驅動到低電平,釋放總線只能通過不驅動總線釋放,停止驅動即產生“1”,但是發(fā)現總線還是“0”,這說明還有主機在跟自己競爭總線使用權,自己線驅動到“1”,確檢測到“0”,那代表自己已經失去了仲裁。
• 主機只能在總線空閑時啟動傳送。兩個或多個主機可能在起始條件的最小持續(xù)時間tHD;STA 內產生一個起始條件,結果在總線上產生一個規(guī)定的起始條件。
• 當SCL 線是高電平時,仲裁在SDA 線發(fā)生;這樣,在其他主機發(fā)送低電平時,發(fā)送高電平的主機將斷開它的數據輸出級,因為總線上的電平與它自己的電平不相同。然后,進一步獲得其的判定條件:
• 仲裁可以持續(xù)多位。首先是比較地址位。如果每個主機都試圖尋址同一的器件,仲裁會繼續(xù)比較數據位(假設主機是發(fā)送器),或者比較響應位(假設主機是接收器)。
• IIC總線的地址和數據信息由贏得仲裁的主機決定,在仲裁過程中不會丟失信息。丟失仲裁的主機可以產生時鐘脈沖直到丟失仲裁的該字節(jié)末尾。
• 在串行傳輸過程中時,一旦有重復的起始條件或停止條件發(fā)送到IIC 總線的時侯,仲裁過程仍在進行。如果可能產生這樣的情況,有關的主機必須在幀格式相同位置發(fā)送這個重復起始條件或停止條件。
• 此外,如果主機也結合了從機功能,而且在尋址階段丟失仲裁,它很可能就是贏得仲裁的主機在尋址的器件。那么,丟失仲裁的主機必須立即切換到它的從機模式。
• IIC總線的控制只由地址或主機碼以及競爭主機發(fā)送的數據決定,沒有中央主機,總線也沒有任何定制的優(yōu)先權。
5.時鐘信號的同步
在 IIC總線上傳送信息時的時鐘同步信號是由掛接在SCL線上的所有器件的邏輯“與”完成的。SCL線上由高電平到低電平的跳變將會影響到這些器件,一旦某個器件的時鐘信號下跳為低電平,將使SCL線一直保持低電平,使SCL線上的所有器件開始低電平期。此時,低電平周期短的器件的時鐘由低至高的跳變并不能影響SCL線的狀態(tài),于是這些器件將進入高電平等待的狀態(tài)。當所有器件的時鐘信號都上跳為高電平時,低電平期結束,SCL線被釋放返回高電平,即所有的器件都同時開始它們的高電平期。其后,第一個結束高電平期的器件又將SCL線拉成低電平。這樣就在SCL線上產生一個同步時鐘。可見,時鐘低電平時間由時鐘低電平期最長的器件確定,而時鐘高電平時間由時鐘高電平期最短的器件確定。
6.總線功能特點及應用
6.1 IIC總線功能特點
IIC總線最主要的優(yōu)點是其簡單性和有效性。由于接口直接在組件之上,因此IIC總線占用的空間非常小,減少了電路板的空間和芯片管腳的數量,降低了互聯成本。總線的長度可高達25英尺,并且能夠以10Kbps的最大傳輸速率支持40個組件。
IIC總線的另一個優(yōu)點是,它支持多主控,其中任何能夠進行發(fā)送和接收的設備都可以成為主總線。一個主控能夠控制信號的傳輸和時鐘頻率。當然,在任何時間點上只能有一個主控。
6.2總線應用
目前有很多半導體集成電路上都集成了IIC接口。帶有IIC接口的單片機有:CYGNAL的 C8051F0XX系列,三星的S3C24XX系列,PHILIPSP87LPC7XX系列,MICROCHIP的PIC16C6XX系列等。很多外圍器件如存儲器、監(jiān)控芯片等也提供I²C接口。
7.利用51單片機模擬IIC總線協(xié)議
7.1所需器件
AT89C51單片機、24C02存儲器、6kΩ電阻兩個、導線若干
7.2接線方式
利用AT89C51的IO口模擬實現IIC總線協(xié)議進行與24C02存儲器的通信,其電路圖如下:
7.3程序代碼
下面是使用AT89C51的IO口模擬實現IIC總線協(xié)議進行通信的程序:
#include
#include
#define uc unsigned char
sbit SDA=P1^0;
sbit SCL=P1^1;
bit NackFlag;
void delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void DelayX1ms(uc count)
{
uc i,j;
for(i=0;i
for(j=0;j<120;j++)
;
}
void start() //啟動
{
SDA=1;
delay();
SCL=1;
delay();
SDA=0;
delay();
SCL=0;
}
void stop() //停止
{
SDA=0;
delay();
SCL=1;
delay();
SDA=1;
delay();
SCL=0;
}
void ChkAck() //應答
{
SDA=1;
SCL=1;
NackFlag=0;
if(SDA==1)
NackFlag=1;
SCL=0;
}
void send8bit(uc num)
{
uc i=8;
uc temp;
temp=num;
for(i=8;i>0;i--)
{
SDA=temp&0x80;
SCL=1;
delay();
SCL=0;
temp=temp<<1;
}
}
void sendbyte(uc num,uc addr)
{
start();
send8bit(0xa0);
ChkAck();
send8bit(num);
ChkAck();
stop();
DelayX1ms(10);
}
void main(void)
{
uc i;
for (i=0;i<0xff;i++)
{
sendbyte(i,i);
DelayX1ms(5);
}
while(1);
}

編輯:admin 最后修改時間:2018-05-18