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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > I^2C總線EEPROM編程心得

          I^2C總線EEPROM編程心得

          作者: 時間:2016-11-28 來源:網(wǎng)絡(luò) 收藏
          相比起學(xué)校教材所用的8031+鎖存器+存儲芯片的組合搭建(不過貌似這種組合只有教科書才用),8952+AT24CXX的組合已經(jīng)完全夠用而且可以很明確地將AT24CXX功能定位在掉電數(shù)據(jù)存儲。
          自己在進(jìn)行電子鐘的編程中,將AT24C02作為了鬧鐘定時保存的存儲,因?yàn)椴僮鞣奖?,很適合作為程序附加功能的拓展,比如電子密碼儲存部件等等。對于沒接觸過的人來說,唯一頭痛的就是I^2C總線的軟件模擬編程,雖然只有SCL和SDA兩條通訊線以及高低電平,上下沿幾種狀態(tài)加以組合,但是單調(diào)得難以理解,尤其延時應(yīng)該是多少,應(yīng)答怎么實(shí)現(xiàn)這些問題都很困擾。I^2C總線是AT24CXX硬件自帶,而常見8952不自帶的,所以進(jìn)行交互通訊時,需要在8952上運(yùn)行軟件模擬。相關(guān)的原理解釋網(wǎng)上很多,這里建立在理解了原理的基礎(chǔ)上,進(jìn)行程序分析:在保證程序能正常工作的前提下,進(jìn)行了延時最短處理

          //24C02的初始化
          void c02_init()
          {
          scl=1;
          sda=1;
          }
          //開啟I^C總線
          void start()
          {
          sda=1;
          nop();
          scl=1;
          nop();
          sda=0;
          nop();
          scl=0;
          nop();
          }
          //停止I^2C總線
          void stop()
          {
          sda=0;
          nop();
          scl=1;
          nop();
          sda=1;
          nop();
          }

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

          //前面總線開關(guān)操作和初始化好理解,看著說明書的原理波形就能夠?qū)懗?/p>

          //發(fā)送8位數(shù)據(jù)

          //之前還真不知道數(shù)據(jù)是這樣一位位賦值傳遞的
          void s_byte(uchar s_dat)
          {
          uchar i;
          for(i=0;i<8;i++)
          {
          s_dat<<=1;//最高位再左移就會寫入到 CY
          scl=0;
          nop();
          sda=CY;//如此類推將每次左移讀CY值,直到讀完8位
          scl=1;//SCL=1,保留數(shù)據(jù)。SCL=0,改變數(shù)據(jù)。
          nop();
          }
          scl=0;
          nop();
          sda=1;
          nop();
          }

          //讀取8位數(shù)據(jù)
          uchar r_byte()
          {
          uchar i,k=0;
          for(i=0;i<8;i++)
          {
          scl=1;
          nop();
          k<<=1;
          if(sda)
          {
          k++;
          }
          scl=0;
          nop();
          }
          return k;
          }

          //從件應(yīng)答
          void ack()
          {
          uchar i;
          scl=1;
          nop();

          scl=0;
          //參考了很多程序還是這個好理解,有應(yīng)答時SDA==0跳出,沒有應(yīng)答等待i累加完畢也退出。

          //但是應(yīng)答這樣用貌似沒有什么意義。在無應(yīng)答時,是不是該轉(zhuǎn)入其他操作?

          while((sda==1)&&i<(200))i++;
          scl=0;
          nop();
          }

          //寫入函數(shù)

          void c02_write(uchar w_add,uchar w_dat)
          {
          start();
          s_byte(0xa0);
          ack();
          s_byte(w_add);
          ack();
          s_byte(w_dat);
          ack();
          stop();
          delay(5);
          }

          //讀取函數(shù),這個是任意地址的讀取函數(shù)。包含了當(dāng)前地址讀取的操作
          uchar c02_read(uchar r_add)
          {
          start();
          //這里要注意,向從件寫入一個地址(r_add),讓接收器件自己比對是否相同.故先送一個寫入驅(qū)動(0xa0)

          s_byte(0xa0);
          ack();
          s_byte(r_add);
          ack();

          //進(jìn)行讀寫入驅(qū)動前,都要重新開啟總線 start();
          start();

          //確定了地址之后,才進(jìn)行真正的寫入操作。
          s_byte(0xa1);
          ack();
          return r_byte();
          stop();
          delay(10);
          }

          其中應(yīng)答很多人說可有可無,假如EEPROM是作為實(shí)現(xiàn)單一功能的主要元件,比如密碼鎖的存儲器,必須做到功能的盡善盡美,我覺得是要的。假如像我一樣作為電子鐘許多附加程序的其中一個,為了節(jié)省運(yùn)算時間,無奈地不應(yīng)答也能接受吧?吧?吧?不知道哩……

          最后使用write(w_add,w_dat);和read(r_add);就可以方便調(diào)用了。記得在這兩個函數(shù)使用前先調(diào)用初始化函數(shù)。



          關(guān)鍵詞: I^2C總線EEPROM編程心

          評論


          相關(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); })();