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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 51單片機讀寫AT24C02源代碼(詳細注釋)

          51單片機讀寫AT24C02源代碼(詳細注釋)

          作者: 時間:2016-12-02 來源:網(wǎng)絡 收藏
          在P1口上接八個led燈,結果就顯示在這八個燈上面。AT24C02的接線方式見程序的頂部的定義。以下是源代碼:

          #include //包含頭文件
          typedef unsigned char uchar;
          typedef unsigned int uint;
          #define write_c02 0xa0
          #define read_c02 0xa1
          sbit sda = P2^0;
          sbit scl = P2^1;
          void delay()
          { //delay:5us
          ;;
          }
          //i2c:init
          void i2c_init()
          {
          sda = 1;
          delay();
          scl = 1;
          delay();
          }
          //delayms:
          void delayms(uint xms)
          {
          uchar x, y;
          for(x = xms; x > 0; x--)
          for(y = 110; y > 0; y--);
          }
          //start:
          void start() //啟動i2c
          {
          sda = 1;
          scl = 1;
          delay();//延時必須大于4.7us,此約為五微秒
          sda = 0; //在scl為高電平時,sda一個下降沿為啟動信號
          delay();
          }
          //stop:
          void stop() //停止i2c
          {
          sda = 0;
          scl = 1;
          delay();
          sda = 1; //在scl為高電平時,sdasda一個上升沿為停止信號
          delay();
          }
          //ack:
          void ack() //應答信號0
          {
          uchar i = 0; //等待變量
          scl = 1;//在scl為高電平期間等待應答
          delay();
          while((sda == 1) && i < 250)//若為應答0即退出,從機向主機發(fā)送應答信號
          i++;//等待一段時間
          scl = 0; //應答之后將scl拉低
          delay();
          }
          //nack:
          void nack() //非應答
          {
          scl = 1;//在scl為高電平期間,由主機向從機發(fā)送一個1,非應答信號
          delay();
          sda = 1;
          scl = 0; //應答之后將scl拉低
          delay();
          }
          //send byte:
          void send_byte(uchar date)//寫一個字節(jié)
          {
          uchar i, temp;
          temp = date; //存入要寫入的數(shù)據(jù),即要發(fā)送到sda上的數(shù)據(jù)
          for(i = 0; i < 8; i++)
          { //發(fā)送8位
          temp <<= 1; //to CY 將數(shù)據(jù)的最高位移入到PSW中的CY位中
          scl = 0;//只有在scl為低電平時,才允許sda上的數(shù)據(jù)變化
          delay();
          sda = CY; //將CY里的數(shù)據(jù)發(fā)送到sda數(shù)據(jù)線上
          delay(); //可以延時
          scl = 1; //在scl為高電平時,不允許sda上的數(shù)據(jù)變化,使數(shù)據(jù)穩(wěn)定
          delay();
          scl = 0;//允許sda數(shù)據(jù)線的數(shù)據(jù)變化,等待下一個數(shù)據(jù)的傳輸
          delay();
          }
          //wait ack:發(fā)送完一個字節(jié)數(shù)據(jù)后要主機要等待從機的應答,第九位
          scl = 0;//允許sda變化
          delay();
          sda = 1;//wait:ack,sda拉高等待應答,當sda=0時,表示從機的應答
          delay();
          }
          //read: byte
          uchar read_byte() //讀一個字節(jié)數(shù)據(jù)
          {
          uchar i, j, k;
          scl = 0; //讀之前先允許sda變化
          delay(); //等待數(shù)據(jù)
          for(i = 0; i < 8; i++)
          {
          scl = 1; //不允許sda變化
          delay(); //使sda數(shù)據(jù)穩(wěn)定后開始讀數(shù)據(jù)
          j = sda; //讀出sda上的數(shù)據(jù)
          k = (k << 1)| j; //將數(shù)據(jù)通過|運算存入k中
          scl = 0;//允許sda變化等待下一位數(shù)據(jù)的到來
          delay();
          }
          //delay();//可不用延時
          return k;//返回讀出的數(shù)據(jù)
          }
          //write:at24c02 在at24c02中的指定地址寫入數(shù)據(jù)
          void write_at24c02(uchar address, uchar date)
          {
          start(); //啟動i2c
          send_byte(write_c02);//寫入期間地址和寫操作
          ack(); //從機應答0
          send_byte(address); //寫入寫數(shù)據(jù)的單元地址
          ack(); //ack0
          send_byte(date); //在指定地址中寫入數(shù)據(jù)
          ack(); //從機應答0
          stop(); //停止i2c
          }
          //read: at24c02 在at24c02的指定地址中讀出寫入的數(shù)據(jù)
          uchar read_at24c02(address)
          {
          uchar dat;//用來存儲讀出的數(shù)據(jù)
          start(); //啟動i2c
          send_byte(write_c02); //寫入at24c02器件地址和寫操作
          ack(); //從機應答0
          send_byte(address); //寫入要讀取AT24C02的數(shù)據(jù)的單元地址
          ack(); //從機應答0
          start(); //再次啟動i2c
          send_byte(read_c02); //寫入AT24C02器件地址和讀操作
          ack();//從機應答‘0’
          dat = read_byte();//讀出指定地址中的數(shù)據(jù)
          nack(); //主機發(fā)出非應答‘1’
          stop(); //停止i2c
          return dat; //返回讀出的數(shù)據(jù)
          }
          //main:
          void main()
          {
          uchar i;
          i2c_init();
          start();
          while(1)
          {
          for(i = 0x00; i < 0xff; i++)
          {
          write_at24c02(10, i);
          delayms(10);//需等待十毫秒
          P1 = read_at24c02(10);//1010 1010
          delayms(2000);
          }
          }
          }


          評論


          技術專區(qū)

          關閉
          看屁屁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); })();