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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 51單片機 I2C AT24C02

          51單片機 I2C AT24C02

          作者: 時間:2016-11-25 來源:網絡 收藏
          I2C協(xié)議在項目開發(fā)中使用很常見,很多存儲芯片使用I2C接口。由于51單片機沒有I2C接口,這里使用IO口模擬I2C通訊協(xié)議,來完成I2C芯片驅動。使用的I2C芯片為AT24C02

          原理圖如下:

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



          代碼如下:

          //程序功能:計時器每一秒向AT24C02保持數據,同時數碼管顯示,重啟之后讀取出數據接著計時,100S循環(huán)
          //程序問題:無法寫入
          #include
          #define uint unsigned int
          #define uchar unsigned char
          //變量定義
          uint timer_flag; //用于判斷定時器T0方式一是否計滿1s
          uchar shiwei,gewei; //數碼管顯示的十位與個位
          uint number;
          uchar time_date; //當前時間數據
          //控制端口聲明
          sbit duanxuan=P2^6; //數碼管段選端
          sbit weixuan=P2^7; //數碼管位選端
          sbit AT24C02_SDA=P2^0; //AT24C02串行數據輸入輸出端口
          sbit AT24C02_SCLK=P2^1; //時鐘信號端口
          //數碼管顯示數字段碼定義
          uchar code table[]={
          0x3f,0x06,0x5b,0x4f,
          0x66,0x6d,0x7d,0x07,
          0x7f,0x6f,0x77,0x7c,
          0x39,0x5e,0x79,0x71};
          //相關函數聲明
          void delay_minute(); //延時us級函數聲明
          void delay_xs(uint); //延時s級函數聲明
          void timer_init(); //定時器T0方式一初始化函數聲明
          void AT24C02_init(); //I^2C通訊總線初始化函數聲明
          void star(); //I^2C通訊啟動函數聲明
          void stop(); //I^2C通訊停止函數聲明
          void response(); //應答函數聲明
          void write_in_byte(uchar); //寫入一個字節(jié)函數聲明
          uchar read_out_byte(); //讀出一個字節(jié)函數聲明,函數放回到讀出的值
          //注意寫入一個字節(jié)與寫入數據的區(qū)別,前者是后者的一個子過程,讀取同
          void saveing(uchar,uchar); //向AT24C02保存數據函數聲明
          uchar load(uchar); //從AT24C02載入掉電之前的數據,函數放回到讀出的值
          void quwei(uchar); //顯示數字取出各位與十位
          void display(uchar); //數碼管顯示函數聲明
          //主函數
          void main()
          {
          AT24C02_init(); //AT24C02初始化
          time_date=load(3); //開機首先載入AT24C02中的數據,這里讀取的是第三位址的數據
          if(time_date>100) //防止上一次保存的數據是100,這里計時是100循環(huán)的
          {
          time_date=1;
          }
          timer_init(); //計時器T0方式一初始化
          while(1)
          {
          display(time_date); //顯示時間
          if(timer_flag==1) //如果計滿一秒,就保存時間數據
          {
          timer_flag=0;
          saveing(3,time_date); //保存時間數據
          }
          }
          }
          //延時us級函數主體
          void delay_minute()
          {;;}
          //延時s級函數主體
          void delay_xs(uint s)
          {
          uint i,j;
          for(i=s;i>0;i--)
          {
          for(j=110;j>0;j--)
          {
          }
          }
          }
          //定時器T0方式一初始化函數主體
          void timer_init()
          {
          //方式選擇
          TMOD=0x01;
          //預裝初值
          TH0=(65536-46080)/256;
          TL0=(65536-46080)%6;
          //開中斷
          EA=1;
          ET0=1;
          //啟動定時器
          TR0=1;
          }
          //I^2C通訊總線初始化函數主體
          void AT24C02_init() //兩線均寫1 AT24C02數據有效規(guī)則,sclk為高電平且sda數據穩(wěn)定,當sda發(fā)生有效數據變化時,sclk必須要是0
          {
          AT24C02_SDA=1;
          delay_minute();
          AT24C02_SCLK=1;
          delay_minute();
          }
          //I^2C通訊啟動函數主體
          void star() //啟動規(guī)則:SCLK-1,SDA下降沿
          {
          AT24C02_SDA=1; //一定要SDA首先為1,再是SCLK為1,否則會出現(xiàn)一個停止信號
          delay_minute();
          AT24C02_SCLK=1;
          delay_minute();
          AT24C02_SDA=0;
          delay_minute();
          }
          //I^2C通訊停止函數主體
          void stop() //停止規(guī)則:SCLK-1,SDA上升沿
          {
          AT24C02_SDA=0; //一定要SDA首先為0,再是SCLK為1,否則會出現(xiàn)一個啟動信號
          delay_minute();
          AT24C02_SCLK=1;
          delay_minute();
          AT24C02_SDA=1;
          delay_minute();
          }
          //應答函數主體
          void response() //應答規(guī)則:SCLK-1,等待從機把SDA拉低
          {
          uint i;
          AT24C02_SCLK=1;
          delay_minute();
          while(AT24C02_SDA==1&&i<255)//等待從機把SDA拉低,且超過一定時間沒有應答,默認已經應答
          {
          i++;
          }
          AT24C02_SCLK=0; //應答之后,SCLK-0.防止數據誤操作,因為SCLK-1,數據就是有效地
          delay_minute();
          }
          //寫入一個字節(jié)函數主體
          void write_in_byte(uchar date)
          {
          uint i,buffer; //i用于循環(huán)發(fā)送每一位,buffer緩沖數據
          buffer=date;
          for(i=0;i<8;i++)
          {
          buffer=buffer<<1; //buffer左旋,高位就放入CY
          AT24C02_SCLK=0; //有效發(fā)送規(guī)則:sclk-0變化數據,sclk-1數據穩(wěn)定后有效
          delay_minute();
          AT24C02_SDA=CY;
          delay_minute();
          AT24C02_SCLK=1;
          delay_minute();
          }
          AT24C02_SCLK=0; //不發(fā)送,一定是SCLK-0,SDA-1
          delay_minute();
          AT24C02_SDA=1;
          delay_minute();
          }
          //讀出一個字節(jié)函數主體
          uchar read_out_byte() //讀出規(guī)則:啟動-控制字片選+寫(為了寫入要讀取的地址)-應答-寫入存儲地址-應答-讀取數據-應答-停止
          {
          uchar i,buffer_writting;
          //--------------------------------------------------
          //不能少的
          AT24C02_SCLK=0; //方便SDA數據發(fā)生有效變化
          delay_minute();
          AT24C02_SDA=1;
          delay_minute();
          //--------------------------------------------------
          for(i=0;i<8;i++)
          {
          AT24C02_SCLK=1;
          delay_minute();
          buffer_writting=(buffer_writting<<1)|AT24C02_SDA;//buffer_writting左旋之后與AT24C02_SDA的數據線與
          delay_minute();
          AT24C02_SCLK=0;
          delay_minute();

          }
          return buffer_writting;
          }
          //向AT24C02保存數據函數主體
          void saveing(uchar address,uchar time_date0) //寫入字節(jié)規(guī)則:啟動-控制字片選+寫-應答-寫入存儲地址-應答-寫入數據-應答-停止
          {
          star(); //啟動信號
          write_in_byte(0xa0);
          response();
          write_in_byte(address);
          response();
          write_in_byte(time_date0);
          response();
          stop();
          }
          //從AT24C02載入掉電之前的數據函數主體
          uchar load(uchar address) //讀出規(guī)則:啟動-控制字片選+寫(為了寫入要讀取的地址)-應答-寫入存儲地址-應答-讀取數據-應答-停止
          {
          uchar time_date_former;
          star();
          write_in_byte(0xa0);
          response();
          write_in_byte(address);
          response();
          time_date_former=read_out_byte();
          stop();
          return time_date_former;
          }
          //顯示數字取出各位與十位函數主體
          void quwei(uchar quwei_date)
          {
          shiwei=quwei_date/10;
          gewei=quwei_date;
          }
          //數碼管顯示函數函數主體
          void display(uchar display_date)
          {
          quwei(display_date);
          //顯示第一個數碼管
          duanxuan=1;
          P0=table[shiwei];
          duanxuan=0;
          P0=0xff;
          weixuan=1;
          P0=0xfe;
          weixuan=0;
          delay_xs(2);
          //顯示第二的數碼管
          duanxuan=1;
          P0=table[gewei];
          duanxuan=0;
          P0=0xff;
          weixuan=1;
          P0=0xfd;
          weixuan=0;
          delay_xs(2);
          }
          //T0定時器方式一中斷服務程序
          void T0_timer_no1() interrupt 1
          {
          //預裝初值
          TH0=(65536-46080)/256;
          TL0=(65536-46080)%6;
          number++;
          if(number==20) //20次計滿就是1s
          {
          number=0;
          time_date++; //時間累加
          timer_flag=1; //計滿一次就保存數據
          if(time_date==100) //100s循環(huán)計時
          {
          time_date=0;
          }
          }
          }
          以上,結束。



          關鍵詞: 51單片機I2CAT24C0

          評論


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