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

          新聞中心

          51單片機(jī) I2C AT24C02

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

          原理圖如下:

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



          代碼如下:

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

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



          關(guān)鍵詞: 51單片機(jī)I2CAT24C0

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