<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51單片機(jī) 普通IO口模擬IIC(I2C)接口通訊的程序代碼

          51單片機(jī) 普通IO口模擬IIC(I2C)接口通訊的程序代碼

          作者: 時間:2018-08-06 來源:網(wǎng)絡(luò) 收藏

          I2C總線是Philips公司提出的一種集成電路IC器件之間相連接的總線協(xié)議,其目的是使電子系統(tǒng)(不只 限于單片機(jī)系統(tǒng))各個IC器件之間的連線變得容易。因為使用傳統(tǒng)的并行總線在IC器件之間連接,往往會使得IC之間連線較多,顯得非常復(fù)雜。而I2C總線 則使IC器件之間只需SDA、SCL兩條連線就可以傳送數(shù)據(jù),因而十分方便。由于I2C在印刷體中不容易書寫(需要上標(biāo)),所以實際書寫時,還常見到 IIC、I2C等書寫方法,本文采用IIC的寫法,敬請注意。關(guān)于IIC總線的知識,請參閱相關(guān)書籍,此處不再做進(jìn)一步介紹。

          本文引用地址:http://www.ex-cimer.com/article/201808/385451.htm

          下面我們用一個使用IIC總線連接器件的例子來簡單說明IIC總線的仿真。

          例.EEPROM24C02是采用IIC接口的一種常用2Kbit(256×8bit)的存儲器。編寫程序使用AT89C51的IO口模擬實現(xiàn)IIC總線協(xié)議進(jìn)行通信,并向24C02存儲器內(nèi)從字節(jié)0到字節(jié)FF寫入數(shù)字0到FF。

          51系列單片機(jī)本身沒有IIC接口,但一些本身具有IIC接口的單片機(jī)往往是高端產(chǎn)品,一方面價格不菲,另一方面我們的系統(tǒng)也沒有必要使用之。通常我們就使用軟件通過51系列單片機(jī)的IO口來模擬實現(xiàn)IIC總線通信。

          本例事實上比較簡單,但需要對IIC總線時序有較好的理解。源文件如下圖所示(采用C51語言編寫):




          在Keil中編輯好源文件以后,接下來就可以建立工程文件并生成相應(yīng)的源代碼了,然后我們來繪制電路圖。

          此例的電路圖極其簡單。只需兩個IC,即AT89C51和24C02C,和兩個上拉電阻,而且上拉電阻還可以省略。至于連接,就更為簡單了。最后得到繪制好的電路圖如下圖所示:


          繪制好電路圖,我們就可以將前面剛剛生成的程序源代碼裝入單片機(jī)了,裝入以后,下面我們就可以來進(jìn)行仿真了。

          首先點(diǎn)擊仿真按鈕,系統(tǒng)沒有什么反映,只有高低電平變化的顏色。我們要想查看結(jié)果,還要用前文中仿真擴(kuò)展 RAM存儲器的方法,先點(diǎn)擊暫停,然后點(diǎn)擊“Debug”菜單下的“I2C Memory Internal Memory – U2”子菜單來打開U2即EEPROM存儲器24C02C的內(nèi)容窗口“I2C Memory Internal Memory – U2”,然后我們就看到了其中的內(nèi)容,也就是我們仿真程序的結(jié)果。如下圖所示:


          從圖中我們能清楚地看到我們的仿真結(jié)果,程序完全正確地執(zhí)行了我們的命令。

          當(dāng)然,如果你過早地點(diǎn)擊了暫停按鈕,那么你得到的結(jié)果可能和上圖略有不同,那可能是因為程序尚未執(zhí)行完畢。此時你可以繼續(xù)點(diǎn)擊運(yùn)行按鈕,或者點(diǎn)擊單步按鈕來仔細(xì)查看程序執(zhí)行過程中24C02C存儲器內(nèi)容的改變情況。

          完整代碼如下:

          /*----------------------------------------------------------------

          Acess the eeprom--24c04

          ----------------------------------------------------------------*/

          #include

          #ifndef INT8U

          #define INT8U unsigned char

          #endif

          #ifndef INT8S

          #define INT8S signed char

          #endif

          #ifndef INT16U

          #define INT16U unsigned int

          #endif

          #define I2C_DELAY; _nop_();_nop_();_nop_();_nop_();_nop_(); // >=4.7uS

          //----------------------------------------------------------------

          // delay 100us

          //----------------------------------------------------------------

          void mDelay(INT8U k)

          {

          INT16U i ;

          for(; k>0; k--)

          {

          for(i=0; i93; i++)

          ;

          }

          }

          //----------------------------------------------------------------

          //OK

          //----------------------------------------------------------------

          void I2C_Start(void)

          {

          SDA = 1;

          I2C_DELAY;

          SCL = 1;

          I2C_DELAY;

          SDA = 0;

          I2C_DELAY;

          I2C_DELAY;

          }

          //----------------------------------------------------------------

          //OK

          //----------------------------------------------------------------

          void I2C_Stop(void)

          {

          SDA = 0 ;

          I2C_DELAY;

          SCL = 1 ;

          I2C_DELAY;

          SDA = 1 ;

          I2C_DELAY;

          I2C_DELAY;

          }

          //----------------------------------------------------------------

          //

          //----------------------------------------------------------------

          void sendAck(void)

          {

          SCL = 0;

          I2C_DELAY;

          SDA = 0;

          I2C_DELAY;

          SCL = 1;

          I2C_DELAY;

          }

          //----------------------------------------------------------------

          //

          //----------------------------------------------------------------

          void sendNoAck(void)

          {

          SCL = 0;

          I2C_DELAY;

          SDA = 1;

          I2C_DELAY;

          SCL = 1;

          I2C_DELAY;

          }

          //----------------------------------------------------------------

          // 0 = noACK; 1 = ACK ;

          //----------------------------------------------------------------

          bit checkAck()

          {

          bit tempbit;

          /*發(fā)送完一個字節(jié)后檢驗設(shè)備的應(yīng)答信號*/

          SDA = 1;

          I2C_DELAY;

          SCL = 0;

          I2C_DELAY;

          tempbit = SDA;

          SCL = 1;

          I2C_DELAY;

          if(tempbit==1)

          {

          return 0; //noACK

          }

          else

          {

          return 1; //ACK

          }

          }

          //----------------------------------------------------------------

          //OK

          // a positive clock edge clock a bit into the ROM

          //----------------------------------------------------------------

          void writeByte(INT8U datum)

          {

          INT8U bitCnt = 0 ;

          for(bitCnt=0; bitCnt8; bitCnt++)

          {

          SCL = 0 ;

          I2C_DELAY;

          if ((datum0x80) == 0x80) //if the MSb is 1

          SDA = 1 ;

          else

          SDA = 0 ;

          I2C_DELAY;

          SCL = 1 ;

          I2C_DELAY;

          datum=1 ;

          }

          }

          //----------------------------------------------------------------

          //OK

          //----------------------------------------------------------------

          INT8U readByte(void)

          {

          bit tempbit = 1 ;

          INT8U temp = 0 ;

          INT8U bitCnt ;

          SDA = 1 ; // release the bus,ready to receive byte??????????????

          I2C_DELAY;

          for(bitCnt=0; bitCnt8; bitCnt++)

          {

          SCL = 0; //?????????????????????????huan???????????????

          I2C_DELAY;

          tempbit = SDA ;

          if (tempbit)

          temp |= 0x01 ;

          else

          temp = 0xfe ;

          SCL = 1 ;

          I2C_DELAY;

          if(bitCnt7)

          temp = 1 ;

          }

          return(temp) ;

          }

          /*~~~~~~~~~~~~~~~~~~~~~~~ API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

          /*-----------------------------------------------------------------

          write some bytes to sequential address

          -----------------------------------------------------------------*/

          void writeToROM(INT8U datum[], INT8U address, INT8U num)

          {

          bit tempbit ;

          INT8U i ;

          INT8U *datum_P ;

          datum_P = datum ;

          I2C_Start() ;

          writeByte(0xa0) ;

          tempbit = checkAck();

          writeByte(address) ;

          tempbit = checkAck();

          for(i=0; i

          {

          writeByte(*(datum_P+i)) ;

          if(!checkAck())

          {

          I2C_Stop() ;

          mDelay(100) ;

          }

          }

          I2C_Stop() ;

          }

          /*-----------------------------------------------------------------

          read some bytes from ROM`s sequential address

          -----------------------------------------------------------------*/

          void readFromROM(INT8U datum[], INT8U address, INT8U num)

          {

          bit tempbit ;

          INT8U i ;

          INT8U *datum_P ;

          datum_P = datum;

          I2C_Start() ;

          writeByte(0xa0) ;

          tempbit = checkAck();

          writeByte(address) ;

          tempbit = checkAck();

          I2C_Start() ;

          writeByte(0xa1) ;

          tempbit = checkAck();

          for(i=0; i

          {

          *(datum_P+i) = readByte() ;

          if(i!=num-1)

          {

          sendAck() ;

          }

          else

          {

          sendNoAck() ;

          }

          }

          I2C_Stop() ;

          }

          /*-----------------------------------------------------------------

          wirte one byte to ROM --random write

          -----------------------------------------------------------------*/

          void writeOneByte(INT8U addr, INT8U datum)

          {

          bit tempbit ;

          /*write a byte to mem*/

          I2C_Start();

          writeByte(0xa0);

          tempbit = checkAck();

          writeByte(addr); /*address*/

          tempbit = checkAck();

          writeByte(datum); /*the data*/

          tempbit = checkAck();

          I2C_Stop();

          mDelay(100) ;

          }

          /*-----------------------------------------------------------------

          read one byte from rom --random read

          -----------------------------------------------------------------*/

          INT8U readOneByte(INT8U addr)

          {

          bit tempbit = 1;

          INT8U mydata;

          /*read a byte from mem*/

          I2C_Start();

          writeByte(0xa0);

          tempbit = checkAck();

          writeByte(addr); /*address*/

          tempbit = checkAck();

          I2C_Start();

          writeByte(0xa1);

          tempbit = checkAck();

          mydata = readByte();

          tempbit = checkAck();

          return (mydata) ;

          I2C_Stop();

          }

          『本文轉(zhuǎn)載自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系刪除』



          關(guān)鍵詞: 51單片機(jī) I/O口 程序代碼

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();