1. 程式人生 > >複習IIC協議---以AT24C02為例

複習IIC協議---以AT24C02為例

1.總綱--複習IIC(inter integrated circuit)協議以及自己順便讀一下資料手冊。

/*************************************************************************************/

1.1IIC協議的總結

1.2AT24C02的資料手冊的閱讀

1.3AT24C02關鍵部分的摘抄,以及IIC協議的引入及使用

1.4關鍵程式碼的編寫,以及AT24C02的上層協議。

/*************************************************************************************/

1.1IIC協議

1.1.1、首先IIC協議分為物理層(四線結構)和協議層(主機,從機,時鐘極性,時鐘相位)。在多主機的系統中,如果有多個主機

只要求兩條匯流排線路,一條是序列資料線SDA,一條是序列時鐘線SCL, (IIC是半雙工而不是全雙工)

兩根線經過上拉電阻上拉之VCC,所以匯流排在空閒的狀態下都是高電平。

 

注意:IIC協議:在SCL的高電平週期內,SDA線上的資料必須保持穩定(因為在SCL為高電平時,SDA如果有跳變就會被認為起始訊號或者終止訊號),資料線SDA僅可以在時鐘SCL為低電平時改變。這一點可以參考時序圖看出。

1.1.2、起始訊號:SCL為高時 SDA是由高電平向低電平變化。

                          

1.1.3、終止訊號:SCL為高時 SDA為由低電平向高電平變化。

1.1.4、應答訊號:每當主機向從機發送8bit資料時第九個時鐘週期,從機需要給出一個低電平表示應答,

1.1.4、傳送定址訊號。

資料幀格式:
有應答與非應答,
分為地址資訊 和 資料資訊,地址8bit--- 7位表示從機地址 第8位表示讀還是寫。
資料則按照資料手冊的時序圖來編寫。
具體編寫程式碼時:
要注意是從高位到低位,還是從低位到高位傳輸資料。一樣採用移位位與/位或的方式。

 

1.2AT24C02的資料手冊的閱讀

概括性知識:首先閱讀一外設晶片的資料手冊時,要大致這個晶片的作用是什麼?然後要知道這款晶片對外的介面是什麼?

(是標準的協議比如SPI、IIC或其他標準協議又或者是該晶片的自定義的時序圖通訊協議比如ds18B20單匯流排協議、LCD的驅動都是自定義的協議)。然後就是熟讀該晶片的資料手冊熟悉他的結構及暫存器,這樣才能更瞭解該晶片的使用功能。

在這裡先get一下重點:一般晶片的資料手冊中比較重要(也是相通的地方)的地方:一般開頭都是:概括,特性,封裝

然後最重要的是 interface,然後就是按照他的上層協議得到相應的資料。

那麼接下來介紹如何讀24c02晶片的資料手冊。

按照我們上邊的分析來看,這是一個記憶體(flash)晶片,說白了就是儲存資料,如何將資料寫入儲存,在需要的時候將資料讀出使用。先把準一個大方向。

首先是特性,然後就是封裝,引腳介紹, 當然我們通過其引腳判斷 SDA、SCL、VCC、GND.我們就知道該晶片是通過IIC匯流排協議來通訊的,具體我們可以先寫IIC底層時序。(這次之前先要初始化GPIO,主要是SDA、SCL這兩個引腳)這裡把屬於IIC的底層時序,寫到這裡(為了和AT24C02的上層時序寫在一起)

啟動、終止、應答、寫一個位元組、讀一個位元組,

1.2.1啟動程式碼&&終止程式碼

在初始化gpio引腳後,將SCL和SDA拉高。讓匯流排處於空閒狀態。

 1 void IIC_Start()                     
 2 {
 3 SCL=1;
 4 SDA=1;
 5 Delay();
 6 SDA=0;
 7 Delay();
 8 SCL= 0;    //這裡將SCL線拉低,鉗住SCL,已經準備好傳送或接受資料。也就是說每次Start訊號後,SCL是被拉低的。
 9 }
10 void IIC_End()                     
11 {
12 SCL=0;
13 SDA=0;
14 Delay();
15 SCL=1;
16 Delay();
17 SDA=1;
18 Delay();
19 }

起始訊號產生後匯流排處於被佔用的狀態,在終止訊號產生後匯流排處於空閒狀態。然後起始訊號的終止訊號都是由主機發出的。

1.2.2、IIC匯流排的資料傳輸

IIC資料傳輸:這裡說的資料起始也包括地址資料和真正傳輸的資料,

 

 然後傳送一個位元組的資料。

void Send_Byte(char data)
{
  char a=0;
  SCL=0; //先將SCL時鐘線拉低  
  //MSB (the Most Significant Bit) 高位在前
 for(a=0;a<8;a++)
 {
          SDA=(data&0x80)>>7
          data=data<<1;
          Delay();
          SCL=1;
          Delay();
          SCL=0;
          Delay();       //具體延時時間資料手冊中的時序圖中具體有寫。
 }

}

 應答訊號:即就是在等待從機是否將SDA拉低。但是如果沒有等到該訊號的到來,我們軟體的設計需要足夠靈活,不能死等下去導致系統宕機,如果沒有看門狗就會真正的掛掉的,所以設定一個變數我們只需要等待一定的時間認定這次資料不對,接著再讀。

 


// 返回1的話 成功應答 返回0 沒有應答。
u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); // 將SDA 資料線設定為輸入 SDA=1;delay_us(1); SCL=1;delay_us(1); while(READ_SDA) //判斷 SDA資料線是否為低,也就是是否應答。 { ucErrTime++; if(ucErrTime>250) // 軟體設定超時時間 { IIC_Stop();
            ,return 1;
        }
    }
    SCL=0;       
    return 0;  
} 

 

 

 

讀出一個位元組的資料:根據IIC底層時序圖。

char IIC_read_Byte()
{
char receive=0,a=0; SCL=0; //將SCL拉低,,在讀資料之前,需要將io設定為輸入模式
for(a=0;a<8;a++) { receive<<1; SCL=0; Delay(); SCL=1; Delay(); if(SDA) receive|=0X01; }
// 要新增應答訊號,也就是說在第九個時鐘週期,SDA是否為低電平。
// 具體看協議中是否規定了要求應答訊號。如果有那麼就要加上,如果無則不需要應答訊號。

return
receive;
}

資料手冊中的介面協議(也就是基於IIC底層的上層的協議)

往AT24C02中的寫入一個位元組:(當然還有頁寫這裡就以位元組寫為例)

 

 

 

往24c02中讀出一個位元組(當然還有頁讀這裡以當前地址讀為例):

 從器件的地址 :

在起始訊號後必須發一個從機的地址(7bit(地址資訊)+1bit(R/W)( 寫低電平有效 )) 

E:\STM32\自己的總結回顧\各種匯流排知識彙總\iic-------資料夾中的iic、spi匯流排的ppt;

從AT24c02中一個地址中寫入一個位元組

//這是基於AT24C02資料手冊也就是上邊的資料幀格式(具體程式碼)

 

void Wirte_Byte(unsigned char addr,char date)      //我們預設該記憶體晶片的只有 256 Byte
{

IIC_Start(); // 起始訊號 該函式結束時 SCL=0;
Send_Byte(0XA0);    // 傳送從機地址,該函式剛開始時,SCL=0; 產生8個時鐘週期後, SCL=0了。
IIC_Wait_Ack();    // ack的時候,首先將SDA設定成輸入模式,SCL=1(第九個時鐘週期的高電平),接下來等SDA是否為低電平,不管SDA是否
//為低電平,最後等待一定時間後,SCL最終就會拉低,(第九個時鐘週期結束)。
Send_Byte(addr);
IIC_Wait_Ack();
Send_Byte(date);
IIC_Wait_Ack();    // 與上邊次開始兩行是一樣的。最後 SCL=0;
TTC_End();          // 在SCL線為高時,SDA線產生下降沿。
}