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

          新聞中心

          ARM入門筆記(9)

          作者: 時(shí)間:2016-12-02 來源:網(wǎng)絡(luò) 收藏
          I2C接口實(shí)驗(yàn)

          注:在AT91SAM7Sxx系列中,I2C稱作TWI。

          一.實(shí)驗(yàn)?zāi)康?br />
          能夠正確讀寫I2C接口芯片存儲(chǔ)器(24C02),即寫入24C02的數(shù)據(jù)與讀出來的數(shù)據(jù)相同。

          二.實(shí)驗(yàn)程序和參數(shù)設(shè)置

          1>連接器選項(xiàng)設(shè)置和啟動(dòng)代碼與上一個(gè)實(shí)驗(yàn)相同
          2> I2C驅(qū)動(dòng)程序

          ATMEL官方網(wǎng)站上有這方便的參考程序。主要由I2C接口的初始化、I2C的讀和寫三部分組成。

          #i nclude "board.h"
          #i nclude "twi.h"
          void InitTwi(void)
          { AT91F_TWI_CfgPIO(); //配置TWI的TWD和TWCK管腳 AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA,(unsigned int)AT91C_PA3_TWD);
          AT91F_TWI_CfgPMC (); //使能TWI外圍時(shí)鐘
          AT91F_TWI_Configure (AT91C_BASE_TWI);//將TWI設(shè)置成主模式
          AT91F_SetTwiClock(AT91C_BASE_TWI); //計(jì)算、設(shè)置時(shí)鐘發(fā)生寄存器
          }
          //*----------------------------------------------------------------------------
          //* fn AT91F_SetTwiClock
          //*計(jì)算、設(shè)置TWI時(shí)鐘發(fā)生寄存器
          //*----------------------------------------------------------------------------
          void AT91F_SetTwiClock(const AT91PS_TWI pTwi)
          { int sclock;
          sclock = (10*MCK /AT91C_TWI_CLOCK);
          sclock = (MCK /AT91C_TWI_CLOCK);
          if (sclock % 10 >= 5)
          sclock = (sclock /10) - 5;
          else
          sclock = (sclock /10)- 6;
          sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
          pTwi->TWI_CWGR = 0x00010000 | sclock | (sclock
          }
          //*----------------------------------------------------------------------------
          //* fn AT91F_TWI_Write
          //* rief Send n bytes to a slave device
          //*----------------------------------------------------------------------------
          int AT91F_TWI_Write(const AT91PS_TWI pTwi ,int address, char *data2send, int size)
          { unsigned int status;
          pTwi->TWI_MMR=(AT91C_EEPROM_I2C_ADDRESS| AT91C_TWI_IADRSZ_1_BYTE ) & ~AT91C_TWI_MREAD;
          pTwi->TWI_IADR = address; // Set TWI Internal Address Register
          status = pTwi->TWI_SR;
          pTwi->TWI_THR = *(data2send++);
          pTwi->TWI_CR = AT91C_TWI_START;
          while (size-- >1){// Wait THR Holding register to be empty
          while (!(pTwi->TWI_SR & AT91C_TWI_TXRDY));
          pTwi->TWI_THR = *(data2send++);// Send first byte
          }
          pTwi->TWI_CR = AT91C_TWI_STOP;
          status = pTwi->TWI_SR;
          while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); // Wait transfer is finished
          return AT91C_EEPROM_WRITE_OK;
          }
          //*----------------------------------------------------------------------------
          //* fn AT91F_TWI_Read
          //* rief Read n bytes from a slave device
          //*----------------------------------------------------------------------------
          int AT91F_TWI_Read(const AT91PS_TWI pTwi , int address, char *data2rec, int size)
          { unsigned int status;
          pTwi->TWI_MMR=(AT91C_EEPROM_I2C_ADDRESS|AT91C_TWI_IADRSZ_1_BYTE) | AT91C_TWI_MREAD; // Set the TWI Master Mode Register
          pTwi->TWI_IADR = address; // Set TWI Internal Address Register
          pTwi->TWI_CR = AT91C_TWI_START; // Start transfer
          status = pTwi->TWI_SR;
          while (size-- >1){ // Wait RHR Holding register is full
          while (!(pTwi->TWI_SR & AT91C_TWI_RXRDY));
          *(data2rec++) = pTwi->TWI_RHR; // Read byte
          }
          pTwi->TWI_CR = AT91C_TWI_STOP;
          status = pTwi->TWI_SR;
          while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); // Wait transfer is finished
          *data2rec = pTwi->TWI_RHR; // Read last byte
          return AT91C_EEPROM_READ_OK;
          }

          3> 主函數(shù)

          在主函數(shù)中,首先調(diào)用了TWI的初始化函數(shù),然后進(jìn)入了超級(jí)大循環(huán)。在每次寫和讀時(shí),都對它們的數(shù)據(jù)緩沖區(qū)進(jìn)行初始化,以查看讀、寫的正確性。

          #i nclude "board.h"
          #i nclude "twi.h"
          int main ( void )
          { int loop,index=0;
          char Wri_data[16], Red_data[16];//定義寫和讀緩沖區(qū)
          InitTwi(); //TWI初始化
          while (1)
          { for (loop = 0; loop 初始化寫和讀緩沖區(qū)的內(nèi)容
          data1[loop] = loop + index;
          data2[loop] = 0;
          }
          index += 1;
          AT91F_TWI_Write(AT91C_BASE_TWI, 0x0, Wri_data, EEP_RW_CHK_CNT);//寫
          AT91F_TWI_Read(AT91C_BASE_TWI, 0x0, Red_data, EEP_RW_CHK_CNT);//讀
          }//用單步調(diào)試,可比較Wri_data[16]和 Red_data[16]的內(nèi)容來判斷讀寫是否正確。
          }

          三.出現(xiàn)的問題與解決方法

          1> 無論寫入任何數(shù)據(jù),讀出來都是同樣的數(shù),表明數(shù)據(jù)沒有寫入(在調(diào)試時(shí)對其寫操作,器件沒有產(chǎn)生應(yīng)答)。

          原因是24C02的寫保護(hù)管腳沒有接地,內(nèi)部的數(shù)據(jù)被寫保護(hù)了。注意:有些廠家的EEROM的該管腳處于懸空時(shí)為不保護(hù)狀態(tài),而有些廠家的EEROM會(huì)處于保護(hù)狀態(tài),因此在用之前一定要仔細(xì)閱讀廠家的數(shù)據(jù)手冊,或不要將該腳懸空。

          2> 對24WC02寫的數(shù)據(jù)和讀的數(shù)據(jù)不一樣。

          原因是I2C的時(shí)鐘太快。在本實(shí)驗(yàn)程序中,可以減少twi.h中的AT91C_TWI_CLOCK常量的數(shù)值。或者直接在程序中修改TWI時(shí)鐘波形發(fā)生寄存器TWI_CWGR。

          3> 當(dāng)寫入16字節(jié)數(shù)據(jù),再讀出16字節(jié)數(shù)據(jù)時(shí),最后一個(gè)字節(jié)總為0。

          原因是TWI Master Mode Register的IADRSZ(器件內(nèi)部地址長度)設(shè)成了兩個(gè)字節(jié)(Two-byte),要將改成一個(gè)字節(jié)(One-byte)。


          關(guān)鍵詞: ARM入門筆記I2

          評論


          技術(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); })();