打印

基于DS12C887时钟闹钟问题

[复制链接]
1644|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
根根|  楼主 | 2013-6-14 17:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机上电时,闹钟就响,若按停止键后,再设置新闹钟时间闹铃却不响,我是菜鸟,希望各位高手不吝赐教!程序在下面
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;//定义段和位选
sbit wela=P2^7;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit lcden=P2^5;//定义液晶使能
sbit s1=P3^4;//功能键
sbit s2=P3^5;//增加键
sbit s3=P3^6;//减小键
sbit s4=P3^7;//闹钟查看键
sbit beep=P2^3;        //蜂鸣器
sbit dscs=P1^4;
sbit dsas=P1^5;
sbit dsrw=P1^6;
sbit dsds=P1^7;
sbit dsirq=P3^3;
sbit DENG=P1^2;
uchar m1=0,m2=0,m3=0,m4=0;  
bit flag1,flag_ri;//定义两个位变量
uchar count,s1num,flag,t0_num;        //定义其他变量
char miao,shi,fen,year,month,day,week,amiao,afen,ashi;
uchar code table[]=" 20  -  -   SUN ";//液晶固定显示内容
uchar code table1[]="      :  :  ";
void write_ds(uchar,uchar);         //函数申明
void set_alarm(uchar,uchar,uchar);
void read_alarm();
uchar read_ds(uchar);
void set_time();
/********************子函数区********************************/
void delay(uchar z)        //延时
{
        uchar x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);

}

void di()//蜂鸣器
{
        beep=0;
        delay(100);
        beep=1;       
}

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

}

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

void init()
{
        uchar num;
        EA=1;//开总中断
        EX1=1;//开外部中断
        IT1=1;//设置下降沿触发中断
        flag1=0; //变量初始化
        t0_num=0;
        s1num=0;
        week=1;
        dula=0;
        wela=0;
        lcden=0;
        lcdrw=0;

        write_ds(0x0a,0x20);//打开振荡器
        write_ds(0x0b,0x26);//设置24小时模式,数据二进制格式,开启闹铃中断
        set_time();//设置上电默认时间,调试的时候用       

        write_com(0x38);//设置显示模式
        write_com(0x0c);//设置开显示,不显示光标
        write_com(0x06);//设置写一个字符地址加1
        write_com(0x01);//显示清零,数据指针清零
        write_com(0x80);//数据指针初始化

        for(num=0;num<16;num++)
        {
                write_date(table[num]);
                delay(5);
        }
        write_com(0x80+0x40);
        for(num=0;num<12;num++)
        {
                write_date(table1[num]);
                delay(5);
        }


}



void write_sfm(uchar add,char date)//1602刷新时分秒
{
        char shi,ge;
        shi=date/10;
        ge=date%10;
        write_com(0x80+0x40+add);
        write_date(0x30+shi);
        write_date(0x30+ge);
}

void write_nyr(uchar add,uchar date)//显示年月日
{
        char shi,ge;
        shi=date/10;
        ge=date%10;
        write_com(0x80+0x00+add);
        write_date(0x30+shi);
        write_date(0x30+ge);
}

void write_week(char we)//写星期
{
  write_com(0x80+12);
  switch(we)
  {
          case 1: write_date('M');delay(5);
                          write_date('O');delay(5);
                        write_date('N');
                        break;
          case 2: write_date('T');delay(5);
                          write_date('U');delay(5);
                        write_date('E');
                        break;

          case 3: write_date('W');delay(5);
                        write_date('E');delay(5);
                        write_date('D');
                        break;

           case 4: write_date('T');delay(5);
                        write_date('H');delay(5);
                        write_date('U');
                        break;
          case 5: write_date('F');delay(5);
                          write_date('R');delay(5);
                        write_date('T');
                        break;
           case 6: write_date('S');delay(5);
                          write_date('A');delay(5);
                        write_date('T');
                        break;

          case 7: write_date('S');delay(5);
                        write_date('U');delay(5);
                        write_date('N');
                        break;
  }

}

void keyscan()
{
        if(flag_ri==1)
        {
                if((s1==0)||(s2==0)||(s3==0)||(s4==0))//取消闹钟报警,按任意键取消报警
                {
                        delay(5);                                                  //延时去抖
                        if((s1==0)||(s2==0)||(s3==0)||(s4==0))
                        {
                                while(!(s1&&s2&&s3&&s4));//等待按键释放
                                        di();
                                        flag_ri=0;//清除报警标志
                                //        dsirq=1;
                        }
               
                }
       
       
        }

        if(s1==0)
        {
                delay(5);
                if(s1==0)
                {
                        while(!s1);//等待释放按键
                        s1num++;
                        di();
                        if(flag1==1)        //设置闹铃为1时才对s1num调整,只调秒,分,时
                        {
                                if(s1num==4)
                                        s1num=1;
                        }
                                flag=1;        //在调整时间时标志位flag为1,不进行正常操作
                        switch(s1num)
                        {
                                case 1:
                                           write_com(0x80+0x40+10);
                                                write_com(0x0f);//光标闪烁//光标跳转到miao位
                                           break;
                                case 2:
                                            write_com(0x80+0x40+7);//光标跳转到fen位
                                           break;
                                case 3:       
                                           write_com(0x80+0x40+4);//光标跳转到时位
                                           break;
                       
                                case 4:
                                                write_com(0x80+0x00+12);//光标跳转到星期
                                            break;

                                case 5:
                                                write_com(0x80+0x00+9);//光标跳转到天
                                            break;
                                               
                                case 6:
                                                write_com(0x80+0x00+6);//光标跳转到月
                                            break;
                                               
                                case 7:
                                                write_com(0x80+0x00+3);//光标跳转到年
                                            break;               
                                case 8:
                                           s1num=0;
                                       write_com(0x0c);//恢复显示
                                           flag=0;
                                           write_ds(0,miao);
                                           write_ds(2,fen);
                                           write_ds(4,shi);
                                           write_ds(6,week);
                                           write_ds(7,day);
                                           write_ds(8,month);
                                           write_ds(9,year);
                                           break;
                        }               
               
               
                }
       
        }

        if(s1num!=0)
        {
                if(s2==0)
                {
                        delay(10);
                        if(s2==0)
                        {
                                while(!s2);
                                di();
                                switch(s1num)
                                {
                                        case 1:miao++;
                                                   if(miao==60)
                                                                   miao=0;
                                                write_sfm(10,miao);
                                                write_com(0x80+0x40+10);
                                                   break;
                                        case 2: fen++;
                                                        if(fen==60)
                                                                fen=0;
                                                write_sfm(7,fen);
                                                write_com(0x80+0x40+7);       
                                                   break;
                                        case 3:
                                                        shi++;
                                                        if(shi==24)
                                                                shi=0;
                                                        write_sfm(4,shi);
                                                        write_com(0x80+0x40+4);
                                                   break;
                                        case 4:week++;
                                                   if(week==8)
                                                                   week=1;
                                                        write_week(week);
                                                        write_com(0x80+0x00+12);
                                                        break;

                                        case 5:
                                                        day++;
                                                        if(day==32)
                                                                day=1;
                                                        write_nyr(9,day);
                                                        write_com(0x80+0x00+9);
                                                        break;

                                        case 6:       
                                                        month++;
                                                        if(month==13)
                                                                month=1;
                                                        write_nyr(6,month);
                                                        write_com(0x80+0x00+0x06);
                                                        break;

                                        case 7:       
                                                                year++;
                                                                if(year==100)
                                                                        year=0;
                                                        write_nyr(3,year);
                                                        write_com(0x80+0x00+3);
                                                        break;

                                                       
                                }
                       
                        }
               
                }
       
           if(s3==0)
           {
                           delay(5);
                        if(s3==0)
                        {
                                while(!s3);
                                di();
                                switch(s1num)
                                {
                                        case 1:miao--;
                                                   if(miao==-1)
                                                                   miao=59;
                                                write_sfm(10,miao);
                                                write_com(0x80+0x40+10);
                                                   break;
                                        case 2: fen--;
                                                        if(fen==-1)
                                                                fen=59;
                                                write_sfm(7,fen);
                                                write_com(0x80+0x40+7);       
                                                   break;
                                        case 3:
                                                        shi--;
                                                        if(shi==-1)
                                                                shi=23;
                                                        write_sfm(4,shi);
                                                        write_com(0x80+0x40+4);
                                                   break;
                                        case 4:week--;
                                                   if(week==0)
                                                                   week=7;
                                                        write_week(week);
                                                        write_com(0x80+0x00+12);
                                                        break;

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

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

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

                  if(s4==0)
                  {
                          delay(5);
                        if(s4==0)
                        {
                                flag1=~flag1;
                                while(!s4);
                                di();
                                if(flag1==0)
                                {
                                        // 退出闹钟设置
                                        flag=0;
                                        write_com(0x80+0x40);
                                        write_date(' ');
                                        write_date(' ');
                                        write_com(0x0c);
                                        write_ds(1,miao);
                                        write_ds(3,fen);
                                        write_ds(5,shi);
                                        DENG=0;                               
                                }

                                else
                                {
                                        read_alarm();//读取原始数据
                                        miao=amiao;//重新赋值用以按键调节
                                        fen=afen;
                                        shi=ashi;
                                        write_com(0x80+0x40);
                                        write_date('R');
                                        write_date('i');                       
                                        write_com(0x80+0x40+3);
                                        write_sfm(4,ashi);
                                        write_sfm(7,afen);
                                        write_sfm(10,amiao);
                                }
                       
                        }
                  
                  
                  }
        }

}

void write_ds(uchar add,uchar date)//写12c887函数
{
        dscs=0;
        dsas=1;
        dsds=1;
        dsrw=1;
        P0=add;
        dsas=0;//先写地址
        dsrw=0;
        P0=date;//再写数据
        dsrw=1;
        dsas=1;
        dscs=1;
}

uchar read_ds(uchar add)//读12c887函数
{
        uchar ds_date;
        dsas=1;
        dsds=1;
        dsrw=1;
        dscs=0;
        P0=add;//先写地址
        dsas=0;
        dsds=0;
        P0=0xff;
        ds_date=P0;//再写数据
        dsds=1;
        dsas=1;
        dscs=1;
        return ds_date;

}

void set_time()         //初始化
{
        write_ds(0,0);        //秒                           kkkkk
        write_ds(1,0);        //秒闹铃
        write_ds(2,3);        //分钟       
        write_ds(3,4);        //分钟闹铃
        write_ds(4,0);        //小时
        write_ds(5,0);        //小时闹铃
        write_ds(6,0);        //星期
        write_ds(7,1);        //日
        write_ds(8,1);        //月
        write_ds(9,12);        //年
}

void read_alarm()
{
        amiao=read_ds(1);
        afen=read_ds(3);
        ashi=read_ds(5);
}

void main()
{
        init();
        while(1)
        {
                keyscan();
                if(flag_ri==1)
                {               
                                di();
                                delay(100);
                                di();
                                delay(500);
                }
                if(flag==0&&flag1==0)//正常工作时
                {
                        keyscan(); //按键扫描
                        year=read_ds(9);//读取12C887数据
                        month=read_ds(8);
                        day=read_ds(7);
                        week=read_ds(6);
                        shi=read_ds(4);
                        fen=read_ds(2);
                        miao=read_ds(0);
                        write_sfm(10,miao);//送液晶
                        write_sfm(7,fen);
                        write_sfm(4,shi);
                        write_week(week);
                        write_nyr(3,year);
                        write_nyr(6,month);
                        write_nyr(9,day);
               
                }
       
        }

}

void exter()interrupt 2         //外部中断1服务程序
{
        uchar c;
        flag_ri=1;
        c=read_ds(0xc0);//读取12c887的c寄存器表示响应中断
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝