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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > C51單片機(jī)模擬I2C總線驅(qū)動(dòng)程序設(shè)計(jì)(1)

          C51單片機(jī)模擬I2C總線驅(qū)動(dòng)程序設(shè)計(jì)(1)

          作者: 時(shí)間:2016-11-26 來源:網(wǎng)絡(luò) 收藏
          /********************************** I2C 總線驅(qū)動(dòng) ******************************
          模塊名:I2C 總線驅(qū)動(dòng) 型號(hào):I2C
          功能描述:
          此模塊包括發(fā)送數(shù)據(jù)及接收數(shù)據(jù),應(yīng)答位發(fā)送,并提供了幾個(gè)直接面對(duì)器件的操作函數(shù),能
          很方便的與用戶程序進(jìn)行連接并擴(kuò)展。需要注意的是,函數(shù)是采用延時(shí)方法產(chǎn)生 SCL 脈沖,
          對(duì)高晶振頻率要做一定的修改?。≡趯?E2PROM 的時(shí)候一定要延時(shí)?。?!
          說明:
          1us機(jī)器周期,晶振頻率要小于12MHz
          返回1:則操作成功,返回0:則操作失敗。
          sla為器件從地址,suba為器件子地址。
          *******************************************************************************
          #i nclude "AT89X52.h"
          #i nclude
          #define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();} //定義空指令
          sbit SDA = P1^3; //模擬 I2C 數(shù)據(jù)傳輸位
          sbit SCL = P1^2; //模擬 I2C 時(shí)鐘控制位
          bit bdata I2C_Ack; //應(yīng)答標(biāo)志位
          /************************************ I2C_Start *******************************
          函數(shù)名:void I2C_Start()
          入口:
          出口:
          功能描述:啟動(dòng) I2C 總線,即發(fā)送 I2C 初始條件
          解釋: 在 I2C 總線協(xié)議中規(guī)定的起始位格式是:在 SCL 高電平期間,SDA 發(fā)生從高到低的電平
          跳變.它與其它數(shù)據(jù)格式的區(qū)別在于,協(xié)議中規(guī)定有效的數(shù)據(jù)必須在 SCL 的高電平期間保持
          不變,只有在 SCL 的低電平期間才能發(fā)生跳變.所以這一有別與其它格式的數(shù)據(jù)才能做為起
          始位.
          調(diào)用函數(shù):
          全局變量
          *******************************************************************************
          void I2C_Start()
          {
          SDA = 1; //發(fā)送起始條件的數(shù)據(jù)信號(hào)
          _Nop();
          SCL = 1;
          SomeNOP(); //起始條件建立時(shí)間大于 4.7us,延時(shí)
          SDA = 0; //發(fā)送起始信號(hào)
          SomeNOP(); //起始條件建立時(shí)間大于 4us,延時(shí)
          SCL = 0; //鉗住 I2C 總線準(zhǔn)備發(fā)送或接收數(shù)據(jù)
          //解釋:I2C 總線在空閑狀態(tài)下都是被上拉為高電平的,所以當(dāng)它們處于低電平時(shí)就表示忙的狀態(tài).
          _nop_();
          _nop_();
          }
          /************************************ I2C_Stop ********************************
          函數(shù)名:void I2C_Stop()
          入口:
          出口:
          功能描述:結(jié)束 I2C 總線,即發(fā)送 I2C 結(jié)束條件
          解釋:同起始條件的格式類似,結(jié)束條件的格式是在 SCL 高電平期間,SDA 由低電平向高電平
          跳變.
          調(diào)用函數(shù):
          全局變量:
          *******************************************************************************
          void I2C_Stop()
          {
          SDA = 0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)
          _Nop();
          SCL = 1; //發(fā)送結(jié)束條件的時(shí)鐘信號(hào)
          SomeNOP();//結(jié)束條件建立時(shí)間大于 4us,延時(shí)
          SDA = 1; //發(fā)送 I2C 總線結(jié)束信號(hào)
          SomeNOP();
          }
          /************************************ I2C_CheckAck ****************************
          函數(shù)名:bit I2C_CheckAck(void)
          入口:
          出口:0(無應(yīng)答),1(有應(yīng)答)
          功能描述:
          檢驗(yàn) I2C 總線應(yīng)答信號(hào),有應(yīng)答則返回 1,否則返回 0,超時(shí)值取 255.
          解釋:I2C 總線協(xié)議中規(guī)定傳輸?shù)拿總€(gè)字節(jié)之后必須跟一個(gè)應(yīng)答位,所以從器件在接收到每
          個(gè)字節(jié)之后必須反饋一個(gè)應(yīng)答信號(hào)給主控制器,而主控制器就需要檢測(cè)從器件回傳的應(yīng)答信
          號(hào),根據(jù)其信息做出相應(yīng)的處理.另外,主從之別是相對(duì)的,接收數(shù)據(jù)的即為從,發(fā)送數(shù)據(jù)的及
          為主.
          再看看應(yīng)答信號(hào)的格式:在由發(fā)送器產(chǎn)生的時(shí)鐘響應(yīng)周期里,發(fā)送器先釋放 SDA(置高),然后
          由接受器將 SDA 拉低,并在這個(gè)時(shí)鐘脈沖周期的高電平期間保持穩(wěn)定的低電平.即表示從器
          件做出了應(yīng)答.
          調(diào)用函數(shù):void I2C_Stop()
          全局變量:
          *******************************************************************************
          bit I2C_CheckAck(void)
          {
          uchar errtime = 255; // 因故障接收方無 Ack,超時(shí)值為 255
          SDA = 1; //發(fā)送器先釋放 SDA
          SomeNOP();
          SCL = 1;
          SomeNOP(); //時(shí)鐘電平周期大于 4 us
          while(SDA) //判斷 SDA 是否被拉低
          {
          errtime--;
          if(errtime==0)
          {
          I2C_Stop();
          return(0);
          }
          }
          SCL = 0;
          _nop_();
          return(1);
          }
          /************************************ I2C_SendB *******************************
          函數(shù)名:void I2C_SendB(uchar c)
          入口:uchar 型數(shù)據(jù)
          出口:
          功能描述:
          字節(jié)數(shù)據(jù)傳送函數(shù),將數(shù)據(jù) c 發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,
          并對(duì)
          此狀態(tài)位進(jìn)行操作
          注意:在傳送數(shù)據(jù)時(shí),數(shù)據(jù)(SDA)的改變只能發(fā)生在SCL的低電平期間,在SCL的高電平期間保
          持不變
          調(diào)用函數(shù):bit I2C_CheckAck()
          全局變量:I2C_Ack
          *******************************************************************************
          void I2C_SendB(uchar c)
          {
          uchar BitCnt;
          for (BitCnt=0; BitCnt<8; BitCnt++) //要傳送的數(shù)據(jù)長度為 8 位
          {
          if((c<
          {
          SDA = 1;
          }
          else
          {
          SDA = 0;
          }
          _nop_();
          _nop_();
          SCL = 1; //置時(shí)鐘線為高通知被控器開始接收數(shù)據(jù)位
          SomeNOP(); //保證時(shí)鐘高電平周期大于 4us
          SCL = 0;
          }
          _nop_();
          _nop_();
          I2C_Ack = I2C_CheckAck();//檢驗(yàn)應(yīng)答信號(hào),作為發(fā)送方,所以要檢測(cè)接收器反饋的應(yīng)答信號(hào).
          _nop_();
          _nop_();
          }




          評(pí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); })();