EDN首页   博客首页

日志档案

发表于 2008-10-3 12:43:31

3

标签: 单片机  

电子钟程序,希望各位高手指出不知之处

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P1^0;
sbit rw=P1^1;
sbit e=P1^2;
sbit s1=P3^2;//按键s1,s2,s3分别接到P3^2,P3^3,P3^0
sbit s2=P3^3;
sbit s3=P3^0;
sbit rd=P3^4;//初始化中置0
uchar num,t,shi,fen,miao,s1num,s2num,s3num;

uchar code table2[]="MonWedTueThuFriSatSun";//星期
uchar code table3[]={31,29,31,30,31,30,31,31,30,31,30,31};//闰年
uchar code table4[]={31,28,31,30,31,30,31,31,30,31,30,31};//平年
uint nian,yue,ri;

uchar t1;//
uchar code table[]="  2008-10-03 Fri";
uchar code table1[]="    00:00:00";
/********************************
        延时
********************************/
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=10;y>0;y--);
}
/********************************
        写指令
********************************/
void write_com(uchar com)
{
        rs=0;
        P0=com;
        delay(5);
        e=1;
        delay(5);
        e=0;        
}
/********************************
        写数据
********************************/
void write_data(uchar date)
{
        rs=1;
        P0=date;
        delay(5);
        e=1;
        delay(5);
        e=0;                
}
/********************************
中断,被初始化函数调用
********************************/
void zduan()
{
        TMOD=0x01;
        TH0=(65536-50000)/256;//装初值
        TL0=(65536-50000)%256;
        EA=1;//开总中断
        ET0=1;//开T0中断
        TR0=1;//启动计数器T0
}
/********************************
     初始化
********************************/
void init()
{
        nian=2008;//初始化年,月,日
        yue=10;
        ri=3;
        t1=12;//初始化星期,12是表示为星期五        
        rd=0;//按键s3一端接P3^4,设置为低电平,相当接地
        rw=0;
        write_com(0x38);//设置16*2显示,5*7点阵,8为数据接口
        write_com(0x0c);//开显示,不显示光标
        write_com(0x06);//当读或写一个字符后地址指针加一,且光标加一,整屏显示不移动
        write_com(0x01);//显示清屏
        write_com(0x80);
        for(num=0;num<16;num++)//写入初始显示的年,月,日,星期
                {
                        write_data(table[num]);
                        delay(5);
                }
        write_com(0x80+0x40);
        for(num=0;num<12;num++)//写入初始显示的时,分,秒
                {
                        write_data(table1[num]);
                        delay(5);
                }
         zduan();//调用初始化函数

}
/********************************
        写入年
********************************/
void write_nian(uint nian)
{
        uint qw,bw,sw,gw;
        qw=nian/1000;
        bw=nian%1000/100;
        sw=nian%1000%100/10;
        gw=nian%10;
        write_com(0x80+0x02);//指向对应地址
        write_data(0x30+qw);        
        write_data(0x30+bw);//延时?
        write_data(0x30+sw);
        write_data(0x30+gw);
}
/********************************
        写入日,月
********************************/

void write_ry(uint add,uint ry)
{
        uint sw,gw;
        sw=ry/10;
        gw=ry%10;
        write_com(0x80+add);//指向对应地址
        write_data(0x30+sw);
        write_data(0x30+gw);
}
/********************************
指定时分秒的地址,并把每个变化的时间送入对应地址
********************************/
void write_sfm(uchar add,uchar sfm)
{
        uchar shiw,gew;
        shiw=sfm/10;//把时/分/秒,拆成十位和各位分别送入对应地址
        gew=sfm%10;
        write_com(0x80+0x40+add);//指向对应地址
        write_data(0x30+shiw);        
        write_data(0x30+gew);
}
/********************************
键盘扫描,被主函数调用,调年月日
********************************/
void keyscan()
{
        if(s1==0)//按下s1键,不按下(s1=1)就跳去判断s2有没有被按下
        delay(5);//延时消抖
        if(s1==0)//再次确定s1有没有被按下
        {        s1num++;//每按一下s1键slnum就加1
                while(!s1);//s1为1时(既松开s1键),执行下一条语句
                TR0=0;//关闭计数器T0
                        if(s1num==1)//第一次按下s1键,停止计时                        
                        {
                                TR0=0;//关闭计数器T0
                                write_com(0x80+0x40+10);
                                write_com(0x0f);                
                        }
                                if(s1num==2)//第二次按下s1键
                                {
                                        write_com(0x80+0x40+7);        
                                }
                                        if(s1num==3)//第三次按下s1键
                                        {
                                                write_com(0x80+0x40+4);        
                                        }
                                                if(s1num==4)//第四次按下s1键,并恢复计时
                                                {
                                                        TR0=1;
                                                        s1num=0;
                                                        write_com(0x0c);        
                                                }                
        }
        if(s1==1)//确认s1没按下
        {
                if(s2==0)//按下s2键
                delay(5);//延时消抖
                if(s2==0)//再次确定s2有没有被按下
                {
                        while(!s2);//s2为1时(既松开s2键),执行下一条语句
                                if(s1num==1)//秒,每按一次秒就加一
                                miao++;
                                if(miao==60)
                                miao=0;
                                write_sfm(10,miao);
                                write_com(0x80+0x40+10);
                                        if(s1num==2)//分,每按一次分就加一
                                        {
                                                fen++;
                                                if(fen==60)
                                                fen=0;
                                                write_sfm(7,fen);
                                                write_com(0x80+0x40+7);
                                        }
                                                if(s1num==3)//时,每按一次时就加一
                                                {
                                                        shi++;
                                                        if(shi==24)
                                                        shi=0;
                                                        write_sfm(4,shi);
                                                        write_com(0x80+0x40+4);
                                                }                
                        }
        }
        if(s1==1)//确认s1没按下
        {
                if(s3==0)//按下s2键
                delay(5);//延时消抖
                if(s3==0)//再次确定s2有没有被按下
                {
                        while(!s3);//s2为1时(既松开s2键),执行下一条语句
                                if(s1num==1)//秒,每按一次秒就加一
                                miao--;
                                if(miao==-1)
                                miao=59;
                                write_sfm(10,miao);
                                write_com(0x80+0x40+10);
                                        if(s1num==2)//分,每按一次分就加一
                                        {
                                                fen--;
                                                if(fen==-1)
                                                fen=59;
                                                write_sfm(7,fen);
                                                write_com(0x80+0x40+7);
                                        }
                                                if(s1num==3)//时,每按一次时就加一
                                                {
                                                        shi--;
                                                        if(shi==-1)
                                                        shi=23;
                                                        write_sfm(4,shi);
                                                        write_com(0x80+0x40+4);
                                                }                
                }
        }
}
/********************************
        主函数
*******************************/
void main()
{
        init();//调用初始化函数
        while(1)
        {        
                keyscan();//键盘扫描
                if(t==1)//时间开始走动,先是秒,再是分,后是时
                {
                        t=0;//t清零
                        miao++;
                        if(miao==60)
                        {
                                miao=0;
                                fen++;
                                if(fen==60)
                                {
                                        fen=0;
                                        shi++;
                                        if(shi==24)
                                        {
                                                  shi=0;
                                                        ri++;

                                                        t1=t1+3;//星期
                                                        if(t1<22)
                                                        {
                                                                if(t1==21)
                                                                        t1=0;
                                                                write_com(0x80+0x0d);
                                                                write_data(table2[t1]);
                                                                write_data(table2[t1+1]);
                                                                write_data(table2[t1+2]);
                                                        }
                                                //日
                                                        
                                                                if((nian%400==0)||(nian%100!=0)&&(nian%4==0))//判断闰年
                                                                {//是闰年
                                                                        if(ri==table3[yue-1]+1)
                                                                        {
                                                                                ri=1;
                                                                                yue++;
                                                                                if(yue==13)
                                                                                {
                                                                                        yue=1;
                                                                                        nian++;
                                                                                }
                                                                                write_nian(nian);
                                                                                
                                                                        }
                                                                        write_ry(0x07,yue);        
                                                                }//
                                                                
                                                                        else//不是闰年
                                                                        {//
                                                                                if(ri==table4[yue-1]+1)
                                                                                {
                                                                                        ri=1;
                                                                                        yue++;
                                                                                        if(yue==13)
                                                                                        {
                                                                                                yue=1;
                                                                                                nian++;
                                                                                        }
                                                                                        write_nian(nian);
                                                                                        
                                                                                }
                                                                                write_ry(0x07,yue);        
                                                                         }
                                                                        write_ry(0x0a,ri);
                                                        
                                        


                                        }
                                        write_sfm(4,shi);        
                                }
                                write_sfm(7,fen);
                        }
                        write_sfm(10,miao);//把变化的时间写入LCD
                }
        }
}
/********************************
        中断程序
********************************/
void time0() interrupt 1 using 2
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        t++;        
}



这是电子钟的程序(包括年月日,星期,十分秒,其中时分秒可以调节),有很多不完善的地方,希望 各位高手指出,不胜感激。该程序用到液晶显示模块RT-1602C

系统分类: 单片机   |   用户分类: 个人成长   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(312)    回复(5)  

投一票您将和博主都有获奖机会!

  • ilove314

    2008-10-4 7:32:15

    有我当年的风格,哈哈,再接再厉

  • zyw19987

    2008-10-4 12:21:50

    呵呵 这不是你写的吧 LCD的数据口是什么啊 怎么只定义了EA RS 和RW呢 你用的是什么液晶12864吗带汉字库??

  • zyw19987

    2008-10-4 12:23:02

    呵呵 这不是你写的吧 LCD的数据口是什么啊 怎么只定义了EA RS 和RW呢 你用的是什么液晶12864吗带汉字库??

  • ilove314

    2008-10-5 9:05:08

    LS的这么说好像就是啊

  • mcp2002

    2008-10-5 11:35:50

    到我的博客上看看我高中时候做的