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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于LPC1758平臺上I2C EEPROM 調(diào)試總結(jié)

          關(guān)于LPC1758平臺上I2C EEPROM 調(diào)試總結(jié)

          作者: 時(shí)間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          硬件平臺:PLC1758

          軟件平臺 uCOS-II

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

          開發(fā)環(huán)境: IAR EWARM

          源碼如下

          #define BSP_I2C2_PINS (DEF_BIT_10|DEF_BIT_11)

          static void BSP_I2C2_Init(CPU_INT32U fi2c)
          {
          //獲取外設(shè)時(shí)鐘
          CPU_INT32U Fpclk = BSP_PM_PerClkFreqGet(BSP_PM_PER_NBR_I2C2);
          //使能該功率模塊
          BSP_PM_PerClkEn(BSP_PM_PER_NBR_I2C2);
          //配置脈沖捕捉管腳
          BSP_GPIO_Cfg(BSP_GPIO_PORT0_FAST,//P0.10引腳
          BSP_I2C2_PINS,//設(shè)置成脈沖捕捉
          BSP_GPIO_OPT_FNCT_3);//引腳輸入使能

          //設(shè)置占空比
          if(fi2c>400000)
          fi2c = 400000;
          I2C2SCLH = (Fpclk+1/fi2c ) / 2;//高電平占空比寄存器
          I2C2SCLL = (Fpclk/fi2c) / 2; //低電平占空比寄存器
          //配置成I2C主模式
          I2C2CONCLR = 0x2C; //STA|SI|AA|STO;
          I2C2CONSET = 0x40; //I2EN=1,使能主I2C

          //設(shè)置中斷源
          BSP_IntVectSet((CPU_INT08U)BSP_INT_SRC_NBR_I2C2,(CPU_FNCT_VOID)I2C2_IRQ_ISR_handler );
          BSP_IntPrioSet((CPU_INT08U)BSP_INT_SRC_NBR_I2C2,0x01);
          //使能中斷
          BSP_IntEn(BSP_INT_SRC_NBR_I2C2);
          //I2C2中斷通道號為28

          }

          問題 :一個(gè)字節(jié)的變量寫入與讀出的的結(jié)果不一致,源碼如下


          INT8U I2C_WriteNByte(INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
          {
          if (num > 0) // 如果讀取的個(gè)數(shù)為0,則返回錯(cuò)誤
          { // 設(shè)置參數(shù)
          if (suba_type == 1)
          { // 子地址為單字節(jié)
          I2C_sla = sla; // 讀器件的從地址
          I2C_suba = suba; // 器件子地址
          I2C_suba_num = 1; // 器件子地址為1字節(jié)
          }
          else if (suba_type == 2)
          { // 子地址為2字節(jié)
          I2C_sla = sla; // 讀器件的從地址
          I2C_suba = suba; // 器件子地址
          I2C_suba_num = 2; // 器件子地址為2字節(jié)
          }
          else if (suba_type == 3)
          { // 子地址結(jié)構(gòu)為8+X
          I2C_sla = sla + ((suba >> 7 )& 0x0e);// 讀器件的從地址
          I2C_suba = suba & 0x0ff; // 器件子地址
          I2C_suba_num = 1; // 器件子地址為8+X
          }

          I2C_buf = s; // 數(shù)據(jù)
          I2C_num = num; // 數(shù)據(jù)個(gè)數(shù)
          I2C_suba_en = 2; // 有子地址,寫操作
          I2C_end = 0;

          // 清除STA,SI,AA標(biāo)志位
          I2C2CONCLR = (1 << 2)| // AA
          (1 << 3)| // SI
          (1 << 5); // STA

          // 置位STA,啟動(dòng)I2C總線
          I2C2CONSET = (1 << 5)| // STA
          (1 << 6); // I2CEN

          // 等待I2C操作完成
          return( Wait_I2c_End(1000));

          }
          return (FALSE);
          }


          INT8U I2C_ReadNByte (INT8U sla, INT32U suba_type, INT32U suba, INT8U *s, INT32U num)
          {

          if (num > 0) // 判斷num個(gè)數(shù)的合法性
          { // 參數(shù)設(shè)置
          if (suba_type == 1)
          { // 子地址為單字節(jié)
          I2C_sla = sla + 1; // 讀器件的從地址,R=1
          I2C_suba = suba; // 器件子地址
          I2C_suba_num = 1; // 器件子地址為1字節(jié)
          }
          else if (suba_type == 2)
          { // 子地址為2字節(jié)
          I2C_sla = sla + 1; // 讀器件的從地址,R=1
          I2C_suba = suba; // 器件子地址
          I2C_suba_num = 2; // 器件子地址為2字節(jié)
          }
          else if (suba_type == 3)
          { // 子地址結(jié)構(gòu)為8+X
          I2C_sla = sla + ((suba >> 7 )& 0x0e) + 1; // 讀器件的從地址,R=1
          I2C_suba = suba & 0x0ff; // 器件子地址
          I2C_suba_num = 1; // 器件子地址為8+x
          }
          I2C_buf = s; // 數(shù)據(jù)接收緩沖區(qū)指針
          I2C_num = num; // 要讀取的個(gè)數(shù)
          I2C_suba_en = 1; // 有子地址讀
          I2C_end = 0;

          // 清除STA,SI,AA標(biāo)志位
          I2C2CONCLR = (1 << 2)| // AA
          (1 << 3)| // SI
          (1 << 5); // STA

          // 置位STA,啟動(dòng)I2C總線
          I2C2CONSET = (1 << 5)| // STA
          (1 << 6); // I2CEN

          return( Wait_I2c_End(1000)); // 等待I2C操作完成


          }
          return (FALSE);

          }



          void I2C2_IRQ_ISR_handler(void)
          {



          switch (I2C2STAT & 0xF8)//0~6位是狀態(tài)位
          { // 根據(jù)狀態(tài)碼進(jìn)行相應(yīng)的處理
          case 0x08: // 已發(fā)送起始條件,主發(fā)送和主接收都有,裝入SLA+W或者SLA+R
          if(I2C_suba_en == 1)// SLA+R // 指定子地址讀
          {
          I2C2DAT = I2C_sla & 0xFE; // 先寫入地址
          }
          else // SLA+W
          {
          I2C2DAT = I2C_sla; // 否則直接發(fā)送從機(jī)地址
          }
          // 清零SI位
          I2C2CONCLR = (1 << 3)| // SI
          (1 << 5); // STA
          break;

          case 0x10: // 已發(fā)送重復(fù)起始條件 // 主發(fā)送和主接收都有
          // 裝入SLA+W或者SLA+R
          I2C2DAT = I2C_sla; // 重起總線后,重發(fā)從地址
          I2C2CONCLR = 0x28; // 清零SI,STA
          break;

          case 0x18:
          case 0x28: // 已發(fā)送I2DAT中的數(shù)據(jù),已接收ACK
          if (I2C_suba_en == 0)
          {
          if (I2C_num > 0)
          {
          I2C2DAT = *I2C_buf++;
          I2C2CONCLR = 0x28; // 清零SI,STA
          I2C_num--;
          }
          else // 沒有數(shù)據(jù)發(fā)送了
          { // 停止總線
          I2C2CONSET = (1 << 4); // STO
          I2C2CONCLR = 0x28; // 清零SI,STA
          I2C_end = 1; // 總線已經(jīng)停止
          }
          }

          else if(I2C_suba_en == 1) // 若是指定地址讀,則重新啟動(dòng)總線
          {
          if (I2C_suba_num == 2)
          {
          I2C2DAT = ((I2C_suba >> 8) & 0xff);
          I2C2CONCLR = 0x28; // 清零SI,STA
          I2C_suba_num--;
          break;
          }

          else if(I2C_suba_num == 1) //器件子地址為1字節(jié)
          {
          I2C2DAT = (I2C_suba & 0xff);
          I2C2CONCLR = 0x28; // 清零SI,STA
          I2C_suba_num--;
          break;
          }

          else if (I2C_suba_num == 0)
          {
          I2C2CONCLR = 0x08;
          I2C2CONSET = 0x20;
          I2C_suba_en = 0; // 子地址己處理
          break;
          }
          }
          else if (I2C_suba_en == 2) // 指定子地址寫,子地址尚未指定
          { // 則發(fā)送子地址
          if (I2C_suba_num > 0)
          {


          if (I2C_suba_num == 2)
          {
          I2C2DAT = ((I2C_suba >> 8) & 0xff);
          I2C2CONCLR = 0x28;
          I2C_suba_num--;
          break;
          }
          else if (I2C_suba_num == 1) //器件子地址為1字節(jié)
          {
          I2C2DAT = (I2C_suba & 0xff);
          I2C2CONCLR = 0x28;
          I2C_suba_num--;
          I2C_suba_en = 0;
          break;
          }
          }
          }
          break;

          case 0x40: // 已發(fā)送SLA+R,已接收ACK
          if (I2C_num <= 1) // 如果是最后一個(gè)字節(jié)
          {
          I2C2CONCLR = 1 << 2; // 下次發(fā)送非應(yīng)答信號
          }
          else
          {
          I2C2CONSET = 1 << 2; // 下次發(fā)送應(yīng)答信號
          }
          I2C2CONCLR = 0x28; // 清零SI,STA
          break;

          case 0x20: // 已發(fā)送SLA+W,已接收非應(yīng)答
          case 0x30: // 已發(fā)送I2DAT中的數(shù)據(jù),已接收非應(yīng)答
          case 0x38: // 在SLA+R/W或數(shù)據(jù)字節(jié)中丟失仲裁

          case 0x48: // 已發(fā)送SLA+R,已接收非應(yīng)答
          I2C2CONCLR = 0x28;
          I2C_end = 0xFF;
          break;

          case 0x50: // 已接收數(shù)據(jù)字節(jié),已返回ACK
          *I2C_buf++ = I2C2DAT;
          I2C_num--;
          if (I2C_num == 1) // 接收最后一個(gè)字節(jié)
          {
          I2C2CONCLR = 0x2C; // STA,SI,AA = 0
          }
          else
          {
          I2C2CONSET = 0x04; // AA=1
          I2C2CONCLR = 0x28;
          }
          break;

          case 0x58: // 已接收數(shù)據(jù)字節(jié),已返回非應(yīng)答
          *I2C_buf++ = I2C2DAT; // 讀取最后一字節(jié)數(shù)據(jù)
          I2C2CONSET = 0x10; // 結(jié)束總線
          I2C2CONCLR = 0x28;
          I2C_end = 1;
          break;

          default:
          break;
          }
          }

          原因:指定suba_type參數(shù)不正確,如果器件的地址位寬是一字節(jié),那么指定為1,如果地址位寬是兩字節(jié),那么指定為2。另外在讀寫操作時(shí)指定Wait_I2c_End(INT32 Dly)函數(shù)中的Dly值太小也不能操作成功,可以適當(dāng)放大些。



          評論


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