找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7720|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

I2C通信協(xié)議簡介

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:249758 發(fā)表于 2018-2-22 09:54 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
I2C通信協(xié)議簡介
摒棄復(fù)雜的情況,這里只對I2C做簡單的介紹。
一、I2C 總線的一些特征:
• 只要求兩條總線線路一條串行數(shù)據(jù)線SDA 一條串行時鐘線SCL
• 每個連接到總線的器件都可以通過唯一的地址和一直存在的簡單的主機從機關(guān)系軟件設(shè)定地址主機可以作為主機發(fā)送器或主機接收器
• 它是一個真正的多主機總線如果兩個或更多主機同時初始化數(shù)據(jù)傳輸可以通過沖突檢測和仲裁防止數(shù)據(jù)被破壞
• 串行的8 位雙向數(shù)據(jù)傳輸位速率在標(biāo)準(zhǔn)模式下可達100kbit/s 快速模式下可達400kbit/s 高速模式下可達3.4Mbit/s
• 片上的濾波器可以濾去總線數(shù)據(jù)線上的毛刺波保證數(shù)據(jù)完整
• 連接到相同總線的IC 數(shù)量只受到總線的最大電容400pF 限制
二、I2C總線在傳送數(shù)據(jù)過程中共有三種類型信號:開始信號、結(jié)束信號和應(yīng)答信號。
開始信號:SCL為高電平時,SDA由高電平向低電平跳變,開始傳送數(shù)據(jù)。
結(jié)束信號:SCL為高電平時,SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。
       應(yīng)答信號:接收數(shù)據(jù)的IC在接收到8bit數(shù)據(jù)后,向發(fā)送數(shù)據(jù)的IC發(fā)出特定的低電平脈沖,表示已收到數(shù)據(jù)
起始和結(jié)束:
bool I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; // SDA線為低電平則總線忙,退出
SDA_L;                      // 拉低SDA線(當(dāng)SCL為高電平時,SDA由高電平向低電平跳變表示開始信號)
I2C_delay();
if(SDA_read) return FALSE; // SDA線為高電平則總線出錯,退出
SDA_L;                     //數(shù)據(jù)為準(zhǔn)備好時,拉低SCL線
I2C_delay();
return TRUE;
}
    發(fā)出開始信號之后,設(shè)備在數(shù)據(jù)未準(zhǔn)備好時,拉低SCL線,這樣主設(shè)備可知從設(shè)備未發(fā)送數(shù)據(jù),從設(shè)備在數(shù)據(jù)準(zhǔn)備好,可以發(fā)送的時候,停止拉低SCL線,這時候才開始真正的數(shù)據(jù)傳輸
void I2C_Stop(void)
{
SCL_L;
I2C_delay();      
SDA_L;
I2C_delay();
SCL_H;            // SCL為高電平時,SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)
I2C_delay();
SDA_H;
I2C_delay();
}
   STOP在單主環(huán)境下非必要,但在多主環(huán)境就非常必要,主控總線的設(shè)備發(fā)送STOP后,通知總線其他設(shè)備總線已經(jīng)閑置.
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
    當(dāng)主機作為接收設(shè)備時,主機對最后一個字節(jié)不應(yīng)答,以向發(fā)送設(shè)備(從設(shè)備)標(biāo)識數(shù)據(jù)傳送結(jié)束。這是因為每次傳輸都應(yīng)得到應(yīng)答信號后再進行下一個字節(jié)傳送。如果此時接收機應(yīng)答了,那它就接收的不是最后一個字節(jié)了。如果是最后一個字節(jié),第9個時鐘周期發(fā)送的是非應(yīng)答信號(此時發(fā)送的不是應(yīng)答信號就是非應(yīng)答信號),最后發(fā)送停止信號。
  1)主發(fā)從收:主START->主發(fā)地址->從ACK->(主發(fā)數(shù)據(jù)->從ACK(循環(huán)))->主STOP或主 START啟動下一次傳輸
  這一過程中,主控SCL線,從只在ACK時控SDA線,其他時刻主控SDA線。  
  2)主收從發(fā):主START->從發(fā)地址->主ACK->(從發(fā)數(shù)據(jù)->主ACK(循環(huán)))->接受至最后一個字節(jié)時,主 NACK->主 STOP 或主START啟動下一次傳輸
      
并非每傳輸8位數(shù)據(jù)之后,都會有ACK信號,有以下3中例外
  •            當(dāng)從機不能響應(yīng)從機地址時(例如它正忙于其他事而無法響應(yīng)IIC總線的操作,或者這個地址沒有對應(yīng)的從機),在第9個SCL周期內(nèi)SDA線沒有拉低,即沒有ACK信號。這時,主機發(fā)出一個P信號終止傳輸或者重新發(fā)出一個S信號開始新的傳輸。
  •            如果從機接收器在傳輸過程中不能接收更多的數(shù)據(jù)時,它不會發(fā)出ACK信號。這樣,主機就可以意識到這點,從而發(fā)出一個P信號終止傳輸或者重新發(fā)出一個S信號開始新的傳輸。
  •            主機接收器在接收到最后一個字節(jié)后,也不會發(fā)出ACK信號。于是,從機發(fā)送器釋放SDA線,以允許主機發(fā)出P信號結(jié)束傳輸。
位傳輸:
主機向從機發(fā)送一字節(jié)數(shù)據(jù)
void I2C_SendByte(u8 SendByte) //數(shù)據(jù)從高位到低位
{
    u8 i=8;
    while(i--)
    {
        SCL_L;
        I2C_delay();
      if(SendByte&0x80)
        SDA_H;
      else
        SDA_L;  
        SendByte<<=1;
        I2C_delay();
  SCL_H;
        I2C_delay();
    }
    SCL_L;
}

三、7位尋址
    在起始條件S 后發(fā)送了一個從機地址,這個地址共有7 位,緊接著的第8 位是數(shù)據(jù)方向位R/W ,0表示發(fā)送寫、1表示請求數(shù)據(jù)讀:
    數(shù)據(jù)傳輸一般由主機產(chǎn)生的停止位P終止,但是如果主機仍希望在總線上通訊它可以產(chǎn)生重復(fù)起始條件Sr和尋址另一個從機,而不是首先產(chǎn)生一個停止條件。
完整的數(shù)據(jù)傳輸:




stm32如何建立與EEPROM的通訊
1、 配置I/O端口,確定并配置I2C的模式,使能GPIO和I2C時鐘。

2、 寫:
檢測SDA是否空閑;
->按I2C協(xié)議發(fā)出起始訊號;
->發(fā)出7位器件地址和寫模式;
->要寫入的存儲區(qū)首地址;
->用頁寫入方式或字節(jié)寫入方式寫入數(shù)據(jù);
3、 讀:
檢測SDA是否空閑;
->按I2C協(xié)議發(fā)出起始訊號;
->發(fā)出7位器件地址和寫模式(偽寫);
->發(fā)出要讀取的存儲區(qū)首地址;
->重發(fā)起始訊號;
->發(fā)出7位器件地址和讀模式;
->接收數(shù)據(jù);

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表