数字闹钟

2020-02-05 08:47发布

#include<reg52.h>   //头文件
#include<intrins.h>
#define uchar unsigned char  //宏定义
#define uint unsigned int
//位定义
sbit rs=P2^5;       //液晶位定义     
sbit lcden=P2^7;
sbit s1=P2^0;       //时间功能切换按键
sbit s2=P2^1;       //按键加
sbit s3=P2^3;       //按键减
sbit s4=P2^4;       //闹钟功能切换键
sbit rst=P1^5;      //ds1302引脚定义
sbit io=P1^6;
sbit sclk=P1^7;
sbit beep=P3^0;     //蜂鸣器

uchar num,count,shi,fen,miao,s1num,s2num,
year,month,day,week,flag,flag1,year1,month1,
day1,week1,shi1,fen1,miao1,year2,month2,
day2,week2,shi2,fen2,miao2,year5,month5,
day5,week5,shi5,fen5,miao5,wk,ashi,afen;     //参数定义

uchar code table[]="20  -  -      ";     //液晶固定显示
uchar code table1[]="  :  :    00:00";
/*
uchar time_dat[7]={12,1,6,6,12,59,59};  //年周月日时分秒
uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
*/
void write_com(uchar com);               //液晶写指令函数
void write_data(uchar date);             //液晶写数据函数
void write_ds1302(uchar add,uchar dat);  //ds1302芯片写指令函数
void set_rtc();                          //ds1302时间设置函数
void time_pros();                        //ds1302进制转换函数
void read_rtc();                         //ds1302读时间函数
void alarm();                            //闹钟函数

void delay(uint z)                       //延时函数
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void init()                    //初始化
{       
    lcden=0;
     flag=0;
     flag1=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
    write_com(0x80);            //液晶固定显示,第一行
        for(num=0;num<14;num++)      
        {
                write_data(table[num]);
                delay(5);
        }

        write_com(0x80+0x40);      //液晶显示第二行
        for(num=0;num<20;num++)
        {
            write_data(table1[num]);
                delay(5);
        }

}

void write_com(uchar com)//1602液晶写指令
{
        rs=0;
        P0=com;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}

void write_data(uchar date)//1602液晶写写数据
{
        rs=1;
    P0=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}


void write_sfm(uchar add,uchar date)//时分秒
{
        uchar shi3,ge;
        shi3=date/10;
        ge=date%10;
        write_com(0x80+0x40+add);
        write_data(0x30+shi3);
        write_data(0x30+ge);

}

void write_nyr(uchar ad,uchar date)//年月日
{
        uchar shi4,ge2;
        shi4=date/10;
        ge2=date%10;
        write_com(0x80+ad);
        write_data(0x30+shi4);
        write_data(0x30+ge2);
}


void write_week(uchar wk)  //星期按西方星期设置  星期天为第一天
{
    write_com(0x80+11);
    switch(wk)
    {
        case 1:     write_data('S');
                    delay(5);
                    write_data('U');
                    delay(5);
                    write_data('N');
                    break;

        case 2:     write_data('M');
                    delay(5);
                    write_data('O');
                    delay(5);
                    write_data('N');
                    break;

        case 3:     write_data('T');
                    delay(5);
                    write_data('U');
                    delay(5);
                    write_data('E');
                    break;
                           
        case 4:     write_data('W');
                    delay(5);
                    write_data('E');
                    delay(5);
                    write_data('D');
                    break;

        case 5:     write_data('T');
                    delay(5);
                    write_data('H');
                    delay(5);
                    write_data('U');
                    break;

        case 6:     write_data('F');
                    delay(5);
                    write_data('R');
                    delay(5);
                    write_data('T');
                    break;

        case 7:     write_data('S');
                    delay(5);
                    write_data('A');
                    delay(5);
                    write_data('T');
                    break;   
                                         

    }  

}

void keyscan()              //按键函数
{
    if(s1==0)
    {
        delay(5);
        if(s1==0)
        {
            write_com(0x0f);
            s1num++;   //记录按键次数
             flag=1;
             flag1=1;
             while(!s1);
            
             switch(s1num)//光标闪烁点定位
             {
                case 1:write_com(0x80+0x40+6);   //秒
                            break;

                case 2:write_com(0x80+0x40+3);   //分
                            break;
                                          
                case 3:write_com(0x80+0x40+0);   //时
                            break;
                                          
                case 4:write_com(0x80+11);       //星期
                            break;  
                case 5:write_com(0x80+8);        //日
                            break;
                             
                case 6:write_com(0x80+5);        //月
                            break;
                             
                case 7:write_com(0x80+2);        //年
                            break;  

                case 8:s1num=0;
                       write_com(0x0c);//设置开显示光标不显示 关闭时间设置
                        set_rtc();
                       flag=0;
                          break;
             }
        
        }
    }

    if(s1num!=0)                         //按键加减
    {
        if(s2==0)                         //加按键函数
        {
            delay(10);
            if(s2==0)
            {

                while(!s2);
                switch(s1num) //根据功能键相应次数做出调节
                {
                    case 1:     miao++;                   //秒加
                                if(miao==60)   
                                    miao=0;
                                 write_sfm(6,miao);
                                 write_com(0x80+0x40+6);
                                 break;

                    case 2:      fen++;                    //分加
                                if(fen==60)   
                                     fen=0;
                                 write_sfm(3,fen);
                                 write_com(0x80+0x40+3);
                                 break;

                    case 3:     shi++;                     //时加
                                if(shi==24)   
                                    shi=0;
                                 write_sfm(0,shi);
                                 write_com(0x80+0x40+0);
                                 break;

                    case 4:     week++;                     //星期加
                                if(week==8)   
                                    week=1;
                                 write_week(week);
                                 write_com(0x80+11);
                                 break;

                    case 5:     day++;                     //日加
                                if(day==32)   
                                    day=1;
                                 write_nyr(8,day);
                                 write_com(0x80+8);
                                 break;

                    case 6:     month++;                    //月加
                                if(month==13)   
                                    month=1;
                                 write_nyr(5,month);
                                 write_com(0x80+5);
                                 break;

                    case 7:     year++;                     //年加
                                if(year==100)   
                                    year=0;
                                 write_nyr(2,year);
                                 write_com(0x80+2);
                                 break;
                                
                }
               
            }
            
        }

        if(s3==0)                                   //减按键函数同上
        {
            delay(10);
            if(s3==0)
            {
                while(!s3);
                switch(s1num) //根据功能键相应次数做出调节
                {
                    case 1:     miao--;
                                if(miao==-1)   
                                    miao=59;
                                 write_sfm(6,miao);
                                 write_com(0x80+0x40+6);
                                 break;

                    case 2:      fen--;
                                if(fen==-1)   
                                     fen=59;
                                 write_sfm(3,fen);
                                 write_com(0x80+0x40+3);
                                 break;

                    case 3:     shi--;
                                if(shi==-1)   
                                    shi=23;
                                 write_sfm(0,shi);
                                 write_com(0x80+0x40+0);
                                 break;

                    case 4:     week--;
                                if(week==-1)   
                                    week=7;
                                 write_week(week);
                                 write_com(0x80+11);
                                 break;

                    case 5:     day--;
                                if(day==-1)   
                                    day=31;
                                 write_nyr(8,day);
                                 write_com(0x80+8);
                                 break;

                    case 6:     month--;
                                if(month==-1)   
                                    month=12;
                                 write_nyr(5,month);
                                 write_com(0x80+5);
                                 break;

                    case 7:     year--;
                                if(year==-1)   
                                    year=99;
                                 write_nyr(2,year);
                                 write_com(0x80+2);
                                 break;
                                 

                }
               
            }
        }
      
    }


    if(s4==0)               //闹钟按键
    {
        delay(5);
        if(s4==0)
        {
            write_com(0x0f); //光标闪烁
            s2num++;   //记录按键次数
             flag=1;
             while(!s4);
             switch(s2num)//光标闪烁点定位
             {
                case 1:write_com(0x80+0x40+13);   //分
                            break;

                case 2:write_com(0x80+0x40+10);     //时
                            break;

                case 3:write_com(0x0c);             //关闭闹钟设置
                           flag=0;
                           s2num=0;
                           break;                          
               
             }
        
        }
    }

    if(s2num!=0)        //闹钟设置
    {
        if(s2==0)        //闹钟加
        {
            delay(10);
            if(s2==0)
            {
                while(!s2);
                switch(s2num) //根据功能键相应次数做出调节
                {
                    case 1:     afen++;
                                if(afen==60)   
                                   afen=0;
                                 write_sfm(13,afen);
                                 write_com(0x80+0x40+13);
                                 break;

                    case 2:     ashi++;
                                if(ashi==24)   
                                    ashi=0;
                                 write_sfm(10,ashi);
                                 write_com(0x80+0x40+10);
                                 break;
                    
                }
            }
        }

        if(s3==0)                //闹钟减
        {
            delay(10);
            if(s3==0)
            {
                while(!s3);
                switch(s2num) //根据功能键相应次数做出调节
                {
                    case 1:      afen--;
                                if(afen==-1)   
                                     afen=59;
                                 write_sfm(13,afen);
                                 write_com(0x80+0x40+13);
                                 break;

                    case 2:     ashi--;
                                if(ashi==-1)   
                                    ashi=23;
                                 write_sfm(10,ashi);
                                 write_com(0x80+0x40+10);
                                 break;

                }
            }
        }
      
    }
}

void wirte_ds1302_byte(uchar dat)           //ds1302字节写
{
    uchar i;
    for(i=0;i<8;i++)
    {
        sclk=0;
        io=dat&0x01;
        dat=dat>>1;
        sclk=1;
    }
}

void write_ds1302(uchar add,uchar dat)        //ds1302写函数
{
    rst=0;
    _nop_();// 空操作
    sclk=0;
    _nop_();
    rst=1;
    _nop_();
    wirte_ds1302_byte(add);
    wirte_ds1302_byte(dat);
    rst=0;
    io=1;
    sclk=1;
}

uchar read_ds1302(uchar add)                //ds1302读函数
{
    uchar i,value;
    rst=0;
    _nop_();// 空操作
    sclk=0;
    _nop_();
    rst=1;
    _nop_();
    wirte_ds1302_byte(add);
    for(i=0;i<8;i++)
    {   
        value=value>>1;
        sclk=0;
        if(io)
        {
            value=value|0x80;
        }
        sclk=1;
    }
    rst=0;
    _nop_();// 空操作
    sclk=0;
    _nop_();
    sclk=1;
    io=1;
    return value;
}

void set_rtc()                             //ds1302时间设置
{   
    write_ds1302(0x8e,0x00);   //关写保护
    year1=year/10;              //转换为十六进制
    year=year%10;
    year=year+year1*16;
    write_ds1302(0x8c,year);

    week1=week/10;
    week=week%10;
    week=week+week1*16;
    write_ds1302(0x8a,week);

    month1=month/10;
    month=month%10;
    month=month+month1*16;
    write_ds1302(0x88,month);

    day1=day/10;
    day=day%10;
    day=day+day1*16;
    write_ds1302(0x86,day);

    shi1=shi/10;
    shi=shi%10;
    shi=shi+shi1*16;   
    write_ds1302(0x84,shi);

    fen1=fen/10;
    fen=fen%10;
    fen=fen+fen1*16;
    write_ds1302(0x82,fen);

    miao1=miao/10;
    miao=miao%10;
    miao=miao+miao1*16;
    write_ds1302(0x80,miao);

    write_ds1302(0x8e,0x80);   //开写保护
    flag1=0;
   
}

void read_rtc()                      //从ds1302中读时间
{   
        year2=read_ds1302(0x8d);
        week2=read_ds1302(0x8b);
        month2=read_ds1302(0x89);
        day2=read_ds1302(0x87);
        shi2=read_ds1302(0x85);
        fen2=read_ds1302(0x83);
        miao2=read_ds1302(0x81);
   
}

void time_pros()                      //从ds1302中读出的时间转换为十进制
{
     
     year5=year2/16;     
     year2=year2%16;
     year2=year2+year5*10;

     month5=month2/16;
     month2=month2%16;
     month2=month2+month5*10;

     day5=day2/16;
     day2=day2%16;
     day2=day2+day5*10;

     shi5=shi2/16;
     shi2=shi2%16;
     shi2=shi2+shi5*10;

     fen5=fen2/16;
     fen2=fen2%16;
     fen2=fen2+fen5*10;

     miao5=miao2/16;
     miao2=miao2%16;
     miao2=miao2+miao5*10;




}

void display()                        //显示函数
{
     write_sfm(6,miao2);
     write_com(0x80+0x40+6);

     write_sfm(3,fen2);
     write_com(0x80+0x40+3);

     write_sfm(0,shi2);
     write_com(0x80+0x40+0);

     write_week(week2);
     write_com(0x80+11);

     write_nyr(8,day2);
     write_com(0x80+8);

     write_nyr(5,month2);
     write_com(0x80+5);

     write_nyr(2,year2);
     write_com(0x80+2);

     if((ashi==shi2)&&(afen==fen2))
     {
        alarm();
     }

}

void alarm()   //    闹钟
{
    beep=0;
    delay(1000);
    beep=1;

}


void main()                   //主函数
{
        init();                   //初始化
    while(1)
    {   
        keyscan();            //按键函数

        if(flag==0)
        {
            keyscan();         
            read_rtc();
            time_pros();
            display();
        }
        
    }

}
单片机1.png (38.02 KB, 下载次数: 8) 下载附件 2012-7-14 13:56 上传
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。