新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 用51單片機定時器中斷設計電子鐘

        用51單片機定時器中斷設計電子鐘

        作者: 時間:2016-11-28 來源:網絡 收藏
        把前天設計的時鐘的功能補全了一些,貼上來,

        本文引用地址:http://www.104case.com/article/201611/322835.htm

        #include
        #define uchar unsigned char
        sbit rd=P2^6;
        sbit wr=P2^5;
        sbit lcde=P2^7;
        sbit k1=P1^0;
        sbit k2=P1^1;
        sbit k4=P1^3;
        sbit k8=P1^7;
        uchar code table1[]="2011-11-05";
        uchar code table2[]="00:00:00";
        uchar code table3[][3]={{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};//定義了二維數組存放星期
        uchar t,s1num;
        char shi,fen,miao,week,nian;
        uchar yue=1,ri=1;
        void delay(uchar z)//延遲zms函數
        {
        uchar x,y;
        for(x=z;x>0;x--)
        for(y=110;y>0;y--);

        }

        void write_com(uchar com)//液晶寫指令操作
        {
        rd=0;
        wr=0;
        delay(5);
        lcde=1;
        P0=com;
        lcde=0;
        }

        void write_date(uchar date)//液晶寫數據操作
        {
        rd=1;
        wr=0;
        delay(5);
        lcde=1;
        P0=date;
        lcde=0;
        }

        void write_sfm(uchar add,uchar date)//更新時分秒
        {
        uchar shi,ge;
        shi=date/10;
        ge=date;
        write_com(0x80+0x40+add);
        write_date(0x30+shi);
        write_date(0x30+ge);
        }

        void write_week(uchar i)//更新星期
        {
        uchar j;
        write_com(0x80+0x0b);
        for(j=0;j<3;j++)
        {
        write_date(table3[i][j]);

        }
        }


        void write_riqi(uchar add,uchar riqi)//更新年月日
        {
        uchar shi,ge;
        shi=riqi/10;
        ge=riqi;
        write_com(0x80+0x00+add);
        write_date(0x30+shi);
        write_date(0x30+ge);
        }

        void init()//初始化函數
        {
        uchar i,j;


        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);

        write_com(0x80+0x00);
        for(i=0;i<10;i++)
        write_date(table1[i]);

        write_com(0x80+0x00+0x0b);
        for(j=0;j<3;j++)
        write_date(table3[week][j]);

        write_com(0x80+0x46);
        for(i=0;i<8;i++)
        write_date(table2[i]);

        TMOD=0x01;//定時器0工作方式1
        TH0=(65536-50000)/256;//設定定時器初值
        TL0=(65536-50000)%6;//12M晶振時50ms數為50000
        EA=1;
        ET0=1;
        TR0=1;
        }

        void keyscan()//鍵盤掃描函數
        {
        if(k1==0)//按下k1鍵確定調時分秒
        {
        delay(5);
        if(k1==0)
        {
        s1num++;
        while(!k1)
        ;
        delay(5);
        while(!k1);
        if(s1num==1)
        {
        TR0=0;//暫停計時器
        write_com(0x80+0x4d);//光標在秒的位置閃爍
        write_com(0x0f);
        }

        if(s1num==2)//光標在分的位置
        {
        TR0=0;
        write_com(0x80+0x4a);
        write_com(0x0f);
        }

        if(s1num==3)//光標在小時的位置
        {
        TR0=0;
        write_com(0x80+0x47);
        write_com(0x0f);
        }
        if(s1num==4)//光標在星期的位置
        {
        TR0=0;
        write_com(0x80+0x0d);
        write_com(0x0f);
        }
        if(s1num==5)//光標在日的位置
        {
        TR0=0;
        write_com(0x80+0x09);
        write_com(0x0f);
        }
        if(s1num==6)//光標在月的位置
        {
        TR0=0;
        write_com(0x80+0x06);
        write_com(0x0f);
        }
        if(s1num==7)//光標在年的位置
        {
        TR0=0;
        write_com(0x80+0x03);
        write_com(0x0f);
        }
        if(s1num==8)//按下第8下時接著走時
        {
        s1num=0;
        write_com(0x0c);
        TR0=1;
        }

        }
        }
        if(s1num!=0)
        {
        if(s1num==1)
        {
        if(k2==0)//按k2鍵秒加1
        {
        delay(5);
        if(k2==0)
        {
        while(!k2);
        delay(5);
        while(!k2);

        miao++;
        if(miao==60)
        miao=0;

        write_sfm(0x0c,miao);
        write_com(0x80+0x4d);
        }
        }
        }


        if(s1num==2)
        {
        if(k2==0)//分加1
        {
        delay(5);
        if(k2==0)
        {
        while(!k2);
        delay(5);
        while(!k2);
        fen++;
        if(fen==60)
        fen=0;

        write_sfm(0x09,fen);
        write_com(0x80+0x4a);
        }
        }
        }

        if(s1num==3)
        {
        if(k2==0)//時加1
        {
        delay(5);
        if(k2==0)
        {

        while(!k2);
        delay(5);
        while(!k2);
        shi++;
        if(shi==24)
        shi=0;

        write_sfm(0x06,shi);
        write_com(0x80+0x47);
        }
        }
        }

        if(s1num==4)
        {
        if(k2==0)//星期加1
        {
        delay(5);
        if(k2==0)
        {

        while(!k2);
        delay(5);
        while(!k2);
        week++;
        if(week==7)
        week=0;

        write_week(week);
        write_com(0x80+0x0d);
        }
        }
        }

        if(s1num==5)
        {
        if(k2==0)//日加1
        {
        delay(5);
        if(k2==0)
        {

        while(!k2);
        delay(5);
        while(!k2);
        ri++;
        if(ri==31)
        ri=1;

        write_riqi(0x08,ri);
        write_com(0x80+0x09);
        }
        }
        }


        if(s1num==6)
        {
        if(k2==0)//月加1
        {
        delay(5);
        if(k2==0)
        {

        while(!k2);
        delay(5);
        while(!k2);
        yue++;
        if(yue==12)
        yue=1;

        write_riqi(0x05,yue);
        write_com(0x80+0x06);
        }
        }
        }

        if(s1num==7)
        {
        if(k2==0)//年加1
        {
        delay(5);
        if(k2==0)
        {

        while(!k2);
        delay(5);
        while(!k2);
        nian++;
        if(nian==100)
        nian=0;
        write_riqi(0x02,nian);
        write_com(0x80+0x03);
        }
        }
        }

        if(k4==0)//判斷k4是否被按下
        {
        delay(5);
        if(k4==0)
        {
        while(!k4);
        delay(5);
        while(!k4);
        if(s1num==1)
        {
        miao--;//秒減1
        if(miao==-1)
        miao=59;
        write_sfm(0x0c,miao);
        write_com(0x80+0x4d);
        }
        if(s1num==2)
        {
        fen--;//分減1
        if(fen==-1)
        fen=59;
        write_sfm(0x09,fen);
        write_com(0x80+0x4a);
        }
        if(s1num==3)
        {
        shi--;//時減1
        if(shi==-1)
        shi=23;
        write_sfm(0x06,shi);
        write_com(0x80+0x47);
        }
        if(s1num==4)
        {
        week--;//星期減1
        if(week==-1)
        week=6;
        write_week(week);
        write_com(0x80+0x0d);
        }
        if(s1num==5)
        {
        ri--;//日減1
        if(ri==0)
        ri=30;
        write_riqi(0x08,ri);
        write_com(0x80+0x09);
        }
        if(s1num==6)
        {
        yue--;//月減1
        if(yue==0)
        yue=12;
        write_riqi(0x05,yue);
        write_com(0x80+0x06);
        }
        if(s1num==7)
        {
        nian--;//年減1
        if(nian==-1)
        nian=99;
        write_riqi(0x02,nian);
        write_com(0x80+0x03);
        }
        }
        }
        }
        if(k8==0)// 按下k8退出調時
        {
        delay(5);
        if(k8==0)
        {
        while(!k8);
        delay(5);
        while(!k8);
        s1num=0;
        write_com(0x0c);
        TR0=1;
        }
        }
        }

        void main()
        {
        init();
        while(1)
        {
        keyscan();
        }
        }

        void timer0() interrupt 1//中斷服務程序
        {

        TH0=(65536-50000)/256;//設定定時器初值
        TL0=(65536-50000)%6;//12M晶振時50ms數為50000
        t++;
        if(t==20)//定時器中斷20次為1秒
        {
        t=0;
        miao++;
        if(miao==60)
        {
        miao=0;
        fen++;
        if(fen==60)
        {
        fen=0;
        shi++;
        if(shi==24)
        {
        shi=0;
        ri++;
        week++;
        if(week==7)
        week=0;
        write_week(week);//刷新星期
        if(ri==31)
        {
        ri=1;
        yue++;
        if(yue==13)
        {
        yue=1;
        nian++;
        if(nian==100)
        nian=0;
        write_riqi(0x02,nian);//刷新年
        }

        write_riqi(0x05,yue);//刷新月
        }
        write_riqi(0x08,ri);//刷新日
        }
        write_sfm(0x06,shi);//刷新時
        }
        write_sfm(0x09,fen);//刷新分
        }
        write_sfm(0x0c,miao);//刷新秒
        }
        }


        // 還可以加上整點報時和斷電記憶的功能,還可以加上24小時和12小時制轉換功能,還可以加上秒表功能,原理都是一樣的,但由于51單片機內存有限,只有
        //4k,所以沒加
        //由于單片機晶振不是嚴格的12MHz,所以要想時鐘精確的話還要進行中斷時間的調整//其中年只能改變后兩位,即從2000到2099年,其實也可實現全調,原理是一樣的,但沒這個必要



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 灵川县| 化德县| 黄石市| 屏东市| 喀喇| 宜黄县| 荔波县| 贺兰县| 上饶县| 东乌| 喀喇| 玉溪市| 轮台县| 泾阳县| 德阳市| 平乐县| 大田县| 准格尔旗| 平定县| 剑河县| 老河口市| 阿拉善盟| 屏东县| 长岛县| 根河市| 泸西县| 偃师市| 杂多县| 虞城县| 萨迦县| 兴化市| 宾川县| 岢岚县| 宁海县| 临泽县| 哈巴河县| 义乌市| 赤壁市| 大姚县| 沿河| 万荣县|