欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

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

QQ登錄

只需一步,快速開始

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

這個(gè)單片機(jī)IIC通訊程序的疑問

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:847776 發(fā)表于 2020-12-27 22:43 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
如下疑問 :
關(guān)于程序中這個(gè)讀字節(jié)的子函數(shù) uchar read_byte() ,讀取EEPROM內(nèi)數(shù)據(jù)時(shí),用了 “ k=(k<<1)|sda; ”,然后循環(huán)8次,這里是如何得到一個(gè)字節(jié)數(shù)據(jù)的,沒弄明白。

我理解是k左移之后(不管k初值是什么),低位補(bǔ)0,而sda要么是0000 0000,要么是0000 0001,是固定的,所以進(jìn)行按位或之后的k要么是0000 0000,要么是0000 0001,這個(gè)也是固定的,不管循環(huán)多少次,每次得到的k都是0000 0000,或者是0000 0001,怎么就讀取到內(nèi)部的0x55這個(gè)數(shù)據(jù)了呢? 而且實(shí)際運(yùn)行用P1點(diǎn)亮LED也是正確的。
感謝指點(diǎn)!

以下是單片機(jī)代碼(注釋是自己寫的,有錯(cuò)誤的地方還請(qǐng)不吝指正):

#include <reg52.h>
#include <intrins.h>
sbit scl=P2^1;
sbit sda=P2^0;
typedef unsigned char uchar;
typedef unsigned int uint;
void delayms(uchar z)
{
     int x,y;
     for(x=z;x>0;x--)
       for(y=110;y>0;y--);
}
void delayus()
{
     _nop_();_nop_();_nop_();_nop_();_nop_();
}
void start()        //開始信號(hào)
{
     sda=1;
     scl=1;
     delayus();     //根據(jù)時(shí)序圖,scl和sda都為1的時(shí)候要保持4.7us以上。
     sda=0;         //在scl為高電平的狀態(tài)下,sda產(chǎn)生下降沿
     delayus();     //根據(jù)時(shí)序圖,數(shù)據(jù)拉低后保持4us以上。
     scl=0;         //根據(jù)時(shí)序圖,將scl拉低,后面開始字節(jié)傳輸。
     delayus();
}
void stop()         //停止信號(hào)
{   
     sda=0;
     scl=1;
     delayus();     //根據(jù)時(shí)序圖,scl和sda分別為1、0的時(shí)候要保持4us以上。
     sda=1;         //在scl為高電平的狀態(tài)下,sda產(chǎn)生上升沿
     delayus();     //根據(jù)時(shí)序圖,數(shù)據(jù)拉高后保持4.7us以上。
     sda=0;         //根據(jù)時(shí)序圖,將sda拉低。
     delayus();
}
void respons()      //應(yīng)答信號(hào)
{
     uchar i;
     sda=1;         //不管之前sda是什么狀態(tài),先釋放sda
     delayus();
     scl=1;         //將scl拉高,用于sda響應(yīng)。
     delayus();
     while((sda==1)&&(i<250)) i++;
     scl=0;
     delayus();     
}

void write_byte(uchar date)    //寫字節(jié),可以用來寫 器件地址 或 內(nèi)存地址 或 數(shù)據(jù)。
{
     uchar i,temp;
     temp=date;
     scl=0;
     for(i=0;i<8;i++)          //總共8位(器件地址是7位+1位讀寫位,內(nèi)存地址是8位),所以需要循環(huán)8次。
     {
       temp=temp<<1;           //將器件地址進(jìn)行左移,左移之后會(huì)溢出,因?yàn)镮IC是從MSB開始寫,所以要左移。
       sda=CY;                 //每當(dāng)有數(shù)據(jù)溢出1,CY都會(huì)置1,溢出0,會(huì)置0,賦給sda,就得到了本次移出來的地址數(shù)據(jù)
       delayus();     
       scl=1;
       delayus();              //延時(shí),給從機(jī)時(shí)間讀取sda信號(hào)。
       scl=0;                  //傳輸完一位后就將SCL拉低,下一次循環(huán)時(shí)sda才允許發(fā)生變化。
     }
       scl=0;
       delayus();
       sda=1;
       delayus();

}

uchar read_byte()              //字節(jié)讀取
{
     uchar j,k;
     scl=0;   
     delayus();
     sda=1;
     delayus();
     for(j=0;j<8;j++)
     {
          scl=1;
          delayus();
          k=(k<<1)|sda;        //k的初值不管是什么,左移之后LSB都是0
          scl=0;
          delayus();
     }
     return k;                 
}
void init()
{
     sda=1;
     scl=1;
     delayus();
}

void main()                    // 主程序思路為先往24C02中寫0x55,然后再讀出來并且賦值給P1
{
     init();
     start();
     write_byte(0xa0);        //尋址,并且下一步為寫。
     respons();               //從機(jī)響應(yīng),疑問:respons函數(shù)中,沒有響應(yīng)時(shí)超時(shí)后也會(huì)繼續(xù),那主機(jī)往哪里寫?
     write_byte(22);          //寫存儲(chǔ)地址,指定后面要往存儲(chǔ)器的第22個(gè)地址去寫數(shù)據(jù)。24c02總共256個(gè)字節(jié)地址,所以0~255都可以。
     respons();  
     write_byte(0x55);        //往存儲(chǔ)器的第22個(gè)地址中寫入數(shù)據(jù)0x55
     respons();
     stop();

     delayms(100);           //進(jìn)入24C02的寫周期,需>10ms

/*下面一段參考24c02的隨機(jī)讀時(shí)序來寫,將上面剛剛寫進(jìn)第22個(gè)地址的數(shù)據(jù)讀出來賦值給P1*/
     start();
     write_byte(0xa0);      //尋址,并且下一步為寫
     respons();             //從機(jī)響應(yīng)
     write_byte(22);        //指定要訪問的地址為22
     respons();
     start();               //由寫變?yōu)樽x,所以要重新開始一下   
     write_byte(0xa1);      //尋址,并且下一步為讀
     respons();
     P1=read_byte();
     stop();
     while(1);              //主程序?qū)憽⒆x完之后,將讀到的數(shù)據(jù)給P1,然后讓程序停在這里。

}





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

使用道具 舉報(bào)

沙發(fā)
ID:213173 發(fā)表于 2020-12-28 08:27 | 只看該作者
k的初值為 0000 0000 ,k=(k<<1)|sda; ,邏輯運(yùn)算符“|”是按位或。移位后最低位補(bǔ)0,每“|”1次最低位被賦值0或1,0000 000x,循環(huán)8次后k=xxxx xxxx,就得到一個(gè)字節(jié)數(shù)據(jù)。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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