<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        基于24C08帶掉電記憶功能的兩路電子跑表

        作者:我行天下   來源:本站原創   點擊數:  更新時間:2014年03月30日   【字體:

        #include <reg51.h>
        #include <intrins.h>
        #define uchar unsigned char
        #define uint  unsigned int
        uchar tent,tent1,secbf,secbf1;sec,min,sec1,min1;
         
        bit write_secbf=0,write_secbf1=0;

        sbit scl_24=P2^6;
        sbit sda_24=P2^7;
        sbit en=P1^2;
        sbit rs=P1^0;
        sbit rw=P1^1;
        sbit gnd=P2^5;
        sbit puss=P2^3;
        sbit clear=P2^2;
        sbit puss1=P2^1;
        sbit start=P2^0;
         void delay(int i) 
        { uchar x,y;
        for (x=i;x>0;x--)
         for(y=110;y>0;y--); 
        }

        /**********1602子程序****************************/

        void write_com(uchar com)
        {
          rs=0;
          P0=com;
          delay(5);
          en=1;
          delay(5);
          en=0;
        }

        void write_dat(uchar dat)
        {
         rs=1;
         P0=dat;
         delay(5);
         en=1;
         delay(5);
         en=0;
         
        }


        void init_1602()
        {
        en=0;
        rw=0;
        write_com(0x38);
        write_com(0x0c);//如果輸入0X0F會是什么效果
        write_com(0x06);
        write_com(0x01);
        write_com(0x80);
        }


        /**************************延時子程序***********************/


        void usdelay()
        {
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_(); 
        }

        /***************以下開始為24CXX用子程序**********************/


        void star24() //開始信號
        {//時鐘線在高電平時,數據線由高變低即為開始信號 由高變低即為開始信號
        sda_24=1;
        usdelay();
        scl_24=1;
        usdelay();
        sda_24=0;//數據線由高變低即為開始信號
        usdelay();
        scl_24=0;
        }

        void stop24() //結束信號
        {//時鐘線在高電平時,數據線由低變高即為結束信號
        sda_24=0;
        usdelay();
        scl_24=1;
        usdelay();
        sda_24=1;
        usdelay();
        sda_24=0; //這句可有可無
        scl_24=0; //這句可有可無
        }

        void Ack24() 
        { uchar i;
        scl_24=1;
        usdelay(); 
            while((sda_24==1)&&(i<200))i++;
        scl_24=0;
            usdelay();
        }
        /*
        void NoAck24()  //不應答
        {
        sda_24=1; //時鐘線高電平時,數據線高,即為不應答
        usdelay();
            scl_24=1;
        usdelay();
        scl_24=0;
            usdelay();
        } */

        void init_24()
        {
        sda_24=1;
        usdelay();
        scl_24=1;
        usdelay();
        }


        void write_byte(uchar dat)
        {
        uchar i,temp;
        temp=dat;
        //scl_24=0;//低電平可以變數據,為高時是讀,且不能變
        for(i=0;i<8;i++)
          {
           temp=temp<<1;
           scl_24=0;
           usdelay();
         sda_24=CY;//CY是PSW寄存器中的CY位,再把CY賦給SDA,再由SCL控制發出去
         //sda_24=(bit)(temp&0x80);//用這句也可以換掉上一句(bit)是強制轉換命令,把數據轉成非0即1
           usdelay();
           scl_24=1;
           usdelay();
          }
          scl_24=0;
          usdelay();
          sda_24=1;//釋放總線
          usdelay();
        }

        uchar read_byte()
        {

        uchar i,k;
        scl_24=0; //這句可有可無
        usdelay(); //這句可有可無
        sda_24=1; //釋放總線
        usdelay();
        for(i=0;i<8;i++)
          {
           scl_24=1;
           usdelay();
           k=(k<<1)|sda_24;//判斷8次,移位7次
           scl_24=0;
           usdelay();
          
          }
        return k;
        }

        void write_add(uchar add,uchar dat)
        {
         star24();
         write_byte(0xa0);//呼叫器件,高四位為定了的1010,即A,低四位三個接了地,所以為000,最后一個0是寫標志
         Ack24();//寫了后要馬上應答
         write_byte(add);//寫要往哪個地址寫數據00-1023
         Ack24();//每寫一次要給一個應答位
          write_byte(dat);//把數據寫入
           Ack24();
          stop24();//給一個停止位,結束寫數據
        }


        uchar read_add(uchar add)
        {
         uchar dat;
         star24();
         write_byte(0xa0);//呼叫器件,高四位為定了的1010,即A,低四位三個接了地,所以為000,最后一個0是寫標志
         Ack24();//寫了后要馬上應答
         write_byte(add);//寫入要往哪個地址讀數據00-1023
         Ack24();//每寫一次要給一個應答位
         star24();
         write_byte(0xa1);//呼叫器件,高四位為定了的1010,即A,低四位三個接了地,所以為000,最后一個1是讀標志
         Ack24();//寫了后要馬上應答
         dat=read_byte();
         stop24();//給一個停止位,結束讀數據
         return dat;
        }

        void display_secbf(uchar dat)
        {
         
         write_com(0x80+13);
         write_dat(0x30+dat);
         

        }

        void display_secbf1(uchar dat)
        {
         
         write_com(0x80+0x40+13);
         write_dat(0x30+dat);
         
        }


        void display_sec(uchar add,uchar dat)
        {
         uchar a,b;
         a=dat/10;
         b=dat%10;
         write_com(0x80+add);
         write_dat(0x30+a);
         write_dat(0x30+b);
          write_dat('.');
        }

        void display_sec1(uchar add,uchar dat)
        {
         uchar a,b;
         a=dat/10;
         b=dat%10;
         write_com(0x80+0x40+add);
         write_dat(0x30+a);
         write_dat(0x30+b);
          write_dat('.');
        }

        void display_min(uchar add,uchar dat)
        {
         uchar a,b;
         a=dat/10;
         b=dat%10;
         write_com(0x80+add);
         write_dat(0x30+a);
         write_dat(0x30+b);
          write_dat(':');
        }

        void display_min1(uchar add,uchar dat)
        {
         uchar a,b;
         a=dat/10;
         b=dat%10;
         write_com(0x80+0x40+add);
         write_dat(0x30+a);
         write_dat(0x30+b);
          write_dat(':');

        void keyscan()

           if (start==0)
           {
            TR0=~TR0;
        TR1=~TR1;
           }
          if(puss==0)
            {
        delay(30);
        while(!puss);
        TR0=~TR0;
        }

          if(puss1==0)
            {
        delay(30);
        while(!puss1);
        TR1=~TR1;
        }


         if(clear==0)
            {

        delay(30);
        while(!clear);
        secbf=0;
        write_add(0,0);
        write_add(0,0);
        sec=0;
        write_add(1,0);
        write_add(1,0);
        min=0;
        write_add(2,0);
        write_add(2,0);
        display_secbf(secbf);
        display_sec(10,sec);
        display_min(7,min);
        TR0=0;

        secbf1=0;
        write_add(10,0);
         write_add(10,0);
        sec1=0;
        write_add(11,0);
        write_add(11,0);
        min1=0;
        write_add(12,0);
        write_add(12,0);

        display_secbf1(secbf);
        display_sec1(10,sec);
        display_min1(7,min);
        TR1=0;
        }
        }


        void N01()
        {
        display_secbf(secbf);
        display_sec(10,sec);
        display_min(7,min);
        if(secbf==10)
        {
        secbf=0;   //定時10秒,如果滿了,從0重新開始
        sec++; 
           if(sec==60)
            {
         sec=0;
         min++; 
         if(min==60)
         min=0; 
         write_add(2,min);
         }
        write_add(1,sec); 
        }
          if(write_secbf==1)
            {
         write_secbf=0;
         write_add(0,secbf);
         
        }
         
        }

         

        void N02()
        {
        display_secbf1(secbf1);
        display_sec1(10,sec1);
        display_min1(7,min1);
        if(secbf1==10)
        {
        secbf1=0;   //定時10秒,如果滿了,從0重新開始
        sec1++; 
           if(sec1==60)
            {
         sec1=0;
         min1++; 
         if(min1==60)
          min1=0;  
          write_add(12,min1);
         }
         
         write_add(11,sec1);
        }
          if(write_secbf1==1)
            {
         write_secbf1=0;
         write_add(10,secbf1); 
        }
         
        }


        void main()
        {
         gnd=0;
         init_1602();
         init_24();
         secbf=read_add(0);//從地址2中讀出以前保存的數據
         if(secbf==10)    secbf=0; //防止首次讀出錯誤數據
         sec=read_add(1);
         min=read_add(2);

         secbf1=read_add(10);//從地址2中讀出以前保存的數據
         if(secbf1==10)    secbf1=0; //防止首次讀出錯誤數據
         sec1=read_add(11);
         min1=read_add(12);


         TMOD=0x11;//定時器工作方式1
         ET0=1; // 開啟 定時器中斷使能
         EA=1; // 總中斷打開
         TH0=(65536-5000)/256;
         TL0=(65536-5000)%256;
         TR0=0;//計時開始

         ET1=1; // 開啟 定時器中斷使能
         
         TH1=(65536-5000)/256;
         TL1=(65536-5000)%256;
         TR1=0;//計時開始
         while(1)
           {
             keyscan();
            N01();
        N02();
           }

        }


        void t0()interrupt 1
        {
         TH0=(65536-5000)/256;
         TL0=(65536-5000)%256;
         tent++;//每中斷一次自加1,每次中斷約50MS
         if(tent==20)
            {
        tent=0;
        secbf++;
        write_secbf=1;//數據更新標志位,1/10秒寫一次24C08
        }
        }

        void t1()interrupt 3
        {
         TH1=(65536-5000)/256;
         TL1=(65536-5000)%256;
         tent1++;//每中斷一次自加1,每次中斷約50MS
         if(tent1==20)
            {
        tent1=0;
        secbf1++;
        write_secbf1=1;//數據更新標志位,1/10秒寫一次24C08
        }
        }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮