久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

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

通信的橋梁-IIC總線

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:224370 發(fā)表于 2020-4-7 11:30 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
網(wǎng)上轉(zhuǎn)載的IIC總線筆記,歡迎大家共師兄習(xí)

人與人之間能進(jìn)行交流是因?yàn)橛姓Z(yǔ)言這個(gè)工具。電子芯片之間的交流也需要一個(gè)工具,IIC總線就是這個(gè)工具,通過IIC總線,芯片之間能進(jìn)行信息交流。但是,交流并不是那么簡(jiǎn)單的,交流的雙方必須有共同語(yǔ)言,就像我們和外國(guó)人交流的時(shí)候就要用外語(yǔ),而不能用國(guó)語(yǔ),否則無法交流。芯片通過IIC總線進(jìn)行交流。

    什么是IIC總線?
    IIC總線由一條SDA數(shù)據(jù)線和一條SCL時(shí)鐘線組成,在這兩條線上可以掛載多個(gè)IIC設(shè)備,每個(gè)IIC設(shè)備都有自己的地址,這些地址由硬件的出廠固定地址位和可編程地址位組成,只有在兩條線上傳輸?shù)闹凳荌IC設(shè)備的地址時(shí),這個(gè)IIC設(shè)備才會(huì)作出響應(yīng)。就像師傅上課提問學(xué)生一樣,只有學(xué)生被叫到自己的名字才會(huì)站起來回答問題。
    IIC作為電子芯片之間的交流語(yǔ)言,它也有一些語(yǔ)法------IIC通訊協(xié)議。
   當(dāng)SCL時(shí)鐘線為高電平的時(shí)候,如果SDA線由高電平跳到低電平,說明師傅準(zhǔn)備提問學(xué)生了,即IIC主機(jī)準(zhǔn)備尋找從機(jī)。
    這個(gè)過程轉(zhuǎn)換為C語(yǔ)言就是
void IIC_Start(void)
{
SDA_OUT();     //sda線設(shè)置為輸出模式
IIC_SDA=1;   
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;  // SDA由高跳到低
delay_us(4);
IIC_SCL=0;//鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}  
    我們把這個(gè)過程稱為IIC的起始信號(hào)。
    注意:上面的delay延時(shí)函數(shù)不是固定的,要根據(jù)硬件設(shè)備的固定時(shí)序來設(shè)置。就像有些學(xué)生反應(yīng)比較快,有些學(xué)生反應(yīng)比較慢,師傅不能要求每個(gè)學(xué)生反應(yīng)時(shí)間都一樣。所以主機(jī)呼叫從機(jī)要根據(jù)從機(jī)的反應(yīng)速度來設(shè)定等待時(shí)間。這個(gè)延時(shí)十分重要!延時(shí)長(zhǎng)一點(diǎn)和短一點(diǎn)都無法得到正確的數(shù)據(jù)。

    做事要有始有終,師傅提問完學(xué)生當(dāng)然要請(qǐng)學(xué)生坐下啦,IIC用完從機(jī),當(dāng)然也要把從機(jī)釋放了。
    這個(gè)過程就是主機(jī)發(fā)出一個(gè)終止信號(hào):SCL為高時(shí),SDA由低電平跳到高電平
    void IIC_Stop(void)
{
SDA_OUT();//sda線輸出
IIC_SCL=0;
IIC_SDA=0;//SDA由低跳到高
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//發(fā)送I2C總線結(jié)束信號(hào)
delay_us(4);  
}
    終止信號(hào)完了之后,IIC處于閑置狀態(tài),主機(jī)可以呼叫其他設(shè)備了,(提問完一個(gè)學(xué)生,師傅又可以去提問另一個(gè)學(xué)生了!)
                                 
    俗話說:一個(gè)巴掌拍不響。師傅叫學(xué)生起來回答問題,如果學(xué)生不樂意當(dāng)然也就不鳥師傅了。當(dāng)主機(jī)呼叫從機(jī)時(shí),從機(jī)可以應(yīng)答也可以不應(yīng)答。即當(dāng)SCL為高電平的時(shí)候,SDA為低電平表明從機(jī)應(yīng)答,否則表明從機(jī)不應(yīng)答。
void IIC_Ack(void)
{
IIC_SCL=0;      //首先拉低SCL,防止產(chǎn)生起始或結(jié)束信號(hào)
SDA_OUT();
IIC_SDA=0;      //低電平代表應(yīng)答
delay_us(4);
IIC_SCL=1;
delay_us(4);
IIC_SCL=0;
}
      Ack即從機(jī)應(yīng)答。
    void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;  //高電平代表不應(yīng)答
delay_us(4);
IIC_SCL=1;
delay_us(4);
IIC_SCL=0;
  }
    NAck即是No Ack ,從機(jī)不應(yīng)答。


等待應(yīng)答也是一個(gè)過程:
    u8IIC_Wait_Ack(void)
    {
        u8ucErrTime=0;
        SDA_IN();     //SDA設(shè)置為輸入模式  
        IIC_SDA=1;
        delay_us(4);      
        IIC_SCL=1;
        delay_us(4);     
        while(READ_SDA)             //SDA為高即未應(yīng)答
        {
            ucErrTime++;
            if(ucErrTime>250)           //等待一段時(shí)間還沒應(yīng)答則發(fā)送停止信號(hào)
            {
                IIC_Stop();
                return1;
            }
        }
        IIC_SCL=0;//時(shí)鐘線輸出0      
        return0;                     
    }




  有了上面的基本信號(hào),主從機(jī)可以進(jìn)行交流了。
    voidIIC_Send_Byte(u8 txd)  //發(fā)送一個(gè)字節(jié)的數(shù)據(jù)            
    {                     
        u8t;   
        SDA_OUT();         
        IIC_SCL=0;//拉低時(shí)鐘線開始數(shù)據(jù)傳輸
        for(t=0;t<8;t++)
        {            
            
            if(txd&0x80) // 因?yàn)橄劝l(fā)的是最高位
                IIC_SDA=1;      //如果剛剛的位是1則證明SDA為高,所以置1
            else
                IIC_SDA=0;          //你懂的
            txd <<=1;              //為讀下一位作準(zhǔn)備
            delay_us(4);  
            IIC_SCL=1;          //時(shí)鐘線高的時(shí)候,數(shù)據(jù)保持穩(wěn)定,保證正確讀取
            delay_us(4);
            IIC_SCL=0;          //時(shí)鐘線拉低,允許讀下一位
            delay_us(4);
        }   
        }      
              為什么要先把SCL設(shè)置為低電平?其實(shí)上面已經(jīng)有提示,因?yàn)樵赟CL為高電平的時(shí)候,SDA的變化代表著起始或者終止信號(hào),所以在SCL為低的時(shí)候,才允許SDA變化(這些變化代表數(shù)據(jù))。

    另外因?yàn)橐粋(gè)字節(jié)(8位)的數(shù)據(jù)是按照一位一位來傳送的,協(xié)議規(guī)定先傳送最高位,所以txd與上0x80,判斷最高位什么電平,然后txd自身左移一位,即第6位變第7位...以此類推,循環(huán)8次,則0~7號(hào)位上的數(shù)據(jù)完成了傳送。

        師傅可以提問學(xué)生,學(xué)生也可以提問師傅。同樣,主機(jī)可以向從機(jī)發(fā)數(shù)據(jù),從機(jī)也可以向主機(jī)發(fā)數(shù)據(jù)(或主機(jī)讀取從機(jī)數(shù)據(jù))
u8 IIC_Read_Byte()          //因?yàn)榻邮諒淖罡呶婚_始,所以下面進(jìn)行左移操作的。
       {
              u8i,receive=0;
              SDA_IN();                //SDA設(shè)置為輸入
              for(i= 0;i < 8;i++ )                            //一個(gè)字節(jié)需要一位一位地讀出來,所以要循環(huán)8次
              {
                     IIC_SCL= 0;
                     delay_us(4);
                     IIC_SCL= 1;
                     receive<<= 1;      //左移一位
                     if(READ_SDA)   //當(dāng)SDA是1的時(shí)候讀入1否則直接補(bǔ)零
                            receive|= 0x01;  
                     delay_us(1);
              }                                   
                     IIC_Ack();//發(fā)送ACK   ,表示讀完數(shù)據(jù)且應(yīng)答了
              returnreceive;
       }
    這里的READ_SDA是SDA線的引腳狀態(tài)號(hào)。


以上就是IIC的基本“語(yǔ)法”了。
再來一個(gè)實(shí)際應(yīng)用:
/************************************************/
/*                   向從機(jī)寫數(shù)據(jù)                    */
/************************************************/
//“1”代表主機(jī)讀取數(shù)據(jù),“0”代表主機(jī)發(fā)送數(shù)據(jù)
void Single_Write(u8 SlaveAddress,u8 REG_Address,u8REG_Data)
{
       IIC_Start();                                //開始信號(hào)
       IIC_Send_Byte(SlaveAddress);   //發(fā)送設(shè)備地址+寫信號(hào)
       IIC_Wait_Ack();                         //等待應(yīng)答
       IIC_Send_Byte(REG_Address);             //發(fā)送設(shè)備寄存器地址
       IIC_Wait_Ack();                         //等待應(yīng)答
       IIC_Send_Byte(REG_Data);            //寫數(shù)據(jù)
       IIC_Wait_Ack();                         //等待應(yīng)答
       IIC_Stop();                                       //停止信號(hào)
       delay_ms(5);
}
/************************************************/
/*                   讀取從機(jī)的數(shù)據(jù)   */
/************************************************/
u8 Single_Read(u8 SlaveAddress,u8 REG_Address)
{
       u8 REG_Data;
       IIC_Start();                                //開始信號(hào)
       IIC_Send_Byte(SlaveAddress);   //發(fā)送設(shè)備地址+寫信號(hào)
       IIC_Wait_Ack();                         //等待應(yīng)答
       IIC_Send_Byte(REG_Address);   //發(fā)送設(shè)備寄存器地址
       IIC_Wait_Ack();                         //等待應(yīng)答
       IIC_Start();                                //再次開始信號(hào)
       IIC_Send_Byte(SlaveAddress+ 1);    //發(fā)送設(shè)備地址+讀信號(hào)
       IIC_Wait_Ack();                         //等待應(yīng)答
       REG_Data =IIC_Read_Byte();        //獲取數(shù)據(jù)
       IIC_NAck();                                      //不再應(yīng)答
       IIC_Stop();                                       //停止信號(hào)
       delay_ms(5);        
       returnREG_Data;                           
}




注意:在同一IIC總線上可以掛載的同一IIC設(shè)備最大數(shù)量是2^(可編程位數(shù)),如果可編程位數(shù)是3,那么可以掛載這種IIC設(shè)備的最大數(shù)量就是8個(gè)。

IIC總線筆記.pdf

1.89 MB, 下載次數(shù): 8, 下載積分: 黑幣 -5

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

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产性生活一级片 | 精品视频一区二区三区 | 成人精品鲁一区一区二区 | 成人免费观看网站 | 成人午夜精品一区二区三区 | 91xxx在线观看 | 日韩成人高清在线 | 99精品一区| 欧美激情国产日韩精品一区18 | 亚洲成人精品在线 | 国产欧美精品一区二区色综合朱莉 | 午夜欧美| 亚洲精品一区二区 | 午夜三级网站 | 久久久亚洲| 亚洲国产一区二区三区 | 成人国产精品免费观看 | 久久久亚洲成人 | 久久久www成人免费无遮挡大片 | 国产精品免费在线 | 亚欧精品一区 | 午夜亚洲| 亚洲高清视频一区二区 | 国产欧美日韩精品一区 | 在线色网| 可以在线看的黄色网址 | 精品视频一区在线 | 国产欧美一区二区三区另类精品 | 欧美日韩久 | 国产精品亚洲片在线播放 | 黄视频在线网站 | 国产一级片精品 | 久久久不卡网国产精品一区 | 国产电影一区二区在线观看 | 国产精品日日做人人爱 | 欧美日韩不卡合集视频 | 免费看的黄网站 | 久久久青草婷婷精品综合日韩 | 成年人精品视频 | 国产欧美精品一区二区三区 | 亚洲一区 中文字幕 |