【单片机】含有闹钟的时钟设计

#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit key1 = P3^2; //手动控制数码管1,2位
sbit key2 = P3^3;   //手动控制数码管4,5位
sbit key3 = P3^4; //手动控制数码管7,8位
sbit key5 = P1^6;   //手动切换数码管显示(可显示三种情况:时钟,日期,闹钟时间)
sbit key6 = P1^7;   //停止闹钟音乐
sbit alarm = P1^4;  //闹钟

uchar count,hour,minute,second;      // 时钟时间 时分秒
uchar i;                             
uchar h,s,m;                         //闹钟时间  时分秒
uchar pattern=0;                     //工作模式 (0:时钟模式 1;日期模式 2:闹钟模式)
uint year,month,day;                    //日期时间 年月日 
uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段码
uchar num;
uchar code SONG[] ={ //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00};
/*定时器1中断:用于闹钟音乐播放*/
void Time0_Int() interrupt 3  
{
TH1= 0xD8;
TL1= 0xEF;     //计入初值,10毫秒定时
num++; //长度加1
}
/*功能:1MS延时子程序*/
void Delay_xMs(uint x) //音乐播放所需延时
{
unsigned int i,j;
for( i =0;i < x;i++ )
{
for( j =0;j<3;j++ );
}
}
/* 延时子程序:时钟显示所需*/
void delay(uint time) //延时
{
uchar j=5;
for(; time>0 ; time--)
for(;j>0;j--);
}
void wait(uchar n) //延时
{
for(i=0 ; i<n ; i++)
    delay(100); 
}
/*功能:闹钟歌曲播放子程序*/
void Play_Song()
{
unsigned char Temp1,Temp2;
unsigned int Addr;
num = 0; //中断计数器清0
Addr = 0;   //SONG下标
while(1)
{
Temp1 = SONG[Addr++];
if(key6!=1)   //判断key6键按下
{
     delay(100);   //硬件防抖
if(key6!=1)
{
   Temp1=0x00;
   }
 }
 if ( Temp1 == 0x00 ) //歌曲结束符
{
return;
}
else
{
Temp2 = SONG[Addr++];
TR1 = 1;
while(1)
{
alarm= ~alarm;
Delay_xMs(Temp1);
if ( Temp2 == num )
{
num = 0;
break;
}
}
}
}
}
void INT_T() interrupt 1    //中断子程序,时间,日期自动进位
{
TH0=0x3c;
TL0=0xb0;  
count++;
if(count==20)
    {
count=0;
second++;                      //秒自增
if(second==60)
{
second=0;    
    minute++;                 //分自增
if(minute==60)
{
minute=0;
hour++;                 // 时自增
    if(hour==24)

    hour=0;
day++;            //  日自增
                    if(((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day==32)||
                   ((month==4||month==6||month==9||month==11)&&day==31)||
                   ((month==2&&(year%400==0||(year%100!=0&&year%4==0)))&&day==30)||
                   ((month==2&&year%4!=0)&&day==29) )
    {
day=1;
    month++;
if(month==13)

    month=1;
year++;
if(year==100)
                      year=0; 
}
    }
        }
}
    }
    }
}
void main()                //主函数
{
TMOD=0X11;           //定时器1方式1;定时器0方式1
TH0=0x3c;
TL0=0xb0;                  //计入初值,定时50毫秒
EA=1;                     //总中断允许
ET0=1;                   //定时器中断允许
ET1=1;
TR0=1;                    //允许计数
hour=0;
minute=0;
second=0;                   //时钟初值
year=2017;
month=12;
day=12;                       //日期初值
h=8;
m=0;
s=0;                //闹钟初值
while(1)
{
          alarm=0;                //闹钟关闭
if(pattern==0) //pattern=0,时钟显示
{
P2=0x7f;
P0=led[hour/10];
    wait(1);
P2=0xbf;
P0=led[hour%10];
wait(1);
P2=0xdf;
P0=0x40;
wait(1);
P2=0xef;
P0=led[minute/10];
wait(1);
P2=0xf7;
P0=led[minute%10];
wait(1);
        P2=0xfb;
P0=0x40;
      wait(1);
P2=0xfd;
P0=led[second/10];
wait(1);
    P2=0xfe;
P0=led[second%10];
wait(1);             //各位赋值
if(key1!=1)    //按键1,时+1
{
delay(100);        //硬件防抖
if(key1!=1)
hour++;
delay(100);
while(key1==0);
}
if(key2!=1) //按键2,分+1
    {
delay(100);
if(key2!=1)
minute++;   
delay(100);
while(key2==0);
}
if(key3!=1)   //按键3,秒+1
{
delay(100);
if(key3!=1)
second++;    
delay(100);
while(key3==0);
}
if(key5!=1) //按键5,切换工作模式
{
delay(100);
if(key5!=1)
pattern++;
if(pattern==3)
pattern=0;
delay(100);
while(key5==0);
}
}
if (hour==h && minute==m && second==s) //到达闹钟时间点
{
Play_Song();

}    
if(pattern==1)    //pattern=1,日期显示
{
P2=0x7f;
P0=led[year/1000];
wait(1);
P2=0xbf;
P0=led[year%1000/100];
    wait(1);
P2=0xdf;
P0=led[year%100/10];
wait(1);
    P2=0xef;
P0=led[year%10];
wait(1);
P2=0xf7;
P0=led[month/10];
wait(1);
P2=0xfb;
P0=led[month%10];
        wait(1);
P2=0xfd;
P0=led[day/10];
    wait(1);
P2=0xfe;
P0=led[day%10];
    wait(1);
if(key1!=1)         //年+1

delay(100);    
if(key1!=1)
year++;
delay(100);
while(key1==0);
}
if(key2!=1)        //月+1
{
delay(100);
        if(key2!=1)
month++;   
delay(100);
while(key2==0);
         }
  if(key3!=1)     //日+1  
  {
delay(100);
if(key3!=1)
day++;    
delay(100);
while(key3==0);
  }
  if(key5!=1)     //切换工作模式
  {
delay(100);
         if(key5!=1)
         pattern++;
if(pattern==3)
              pattern=0;
delay(100);
while(key5==0);
}
if (hour==h && minute==m && second==s)
{

Play_Song();
}  
}
if(pattern==2)    //pattern=2,闹钟显示
{
    P2=0x7f;
P0=led[h/10];
   wait(1);
P2=0xbf;
P0=led[h%10];
wait(1);
P2=0xdf;
P0=0x40;
wait(1);
P2=0xef;
P0=led[m/10];
wait(1);
P2=0xf7;
P0=led[m%10];
wait(1);
P2=0xfb;
P0=0x40;
wait(1);
P2=0xfd;
P0=led[s/10];
wait(1);
P2=0xfe;
P0=led[s%10];
wait(1);
if(key1!=1)     //小时+1
{
delay(100);   //进位规则 时
if(key1!=1)
h++;
if(h==24)
h=0;
delay(100);
while(key1==0);
}
if(key2!=1)
    {                               //分
delay(100);
if(key2!=1)
m++;
if(m==60)
{
  m=0;
  h++;
}   
delay(100);
    while(key2==0);
}
if(key3!=1)                   //秒
{
delay(100);
if(key3!=1)
    s++;
if(s==60)
{
s=0;
m++;
}    
    delay(100);
  while(key3==0);
}
if (hour==h && minute==m && second==s)
{
Play_Song();
}
if(key5!=1)         //切换
       {
delay(100);
if(key5!=1)
pattern++;
if(pattern==3)
              pattern=0;
delay(100);
    while(key5==0);
   }
        }  




if(hour==24) hour=0; //手动更改时间时期时进位规则
if(minute==60)
{
hour++;
minute=0;
}
if(second==60)
{
minute++;
second=0;
}
if(year==100) year=0;
if(month==13)
{
    year++;  
      month=1;


if(((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day==32)||
  ((month==4||month==6||month==9||month==11)&&day==31)||
  ((month==2&&(year%400==0||(year%100!=0&&year%4==0)))&&day==30)||
  ((month==2&&year%4!=0)&&day==29))
{
day=1;
month++;
}


    }
}

解释一下:这段代码很简单,涉及到的硬件只有几个按键作为输入以及蜂鸣器与数码管输出,也就是说你只要把稍微改一改输入输出那块,把相应的输入输出对应到你的硬件上或者把代码中关于时钟实现的那部分逻辑代码摘出来放到你的代码里面去。

就OK了。

可能你要问了,它的内部是如何实现计时的呢?很简单,纯代码逻辑实现,不然你以为delay()和wait()干什么用的,

那它的中间过程有用到什么不可或缺的硬件(比如硬件计时器)了吗? 抱歉,没有。中间的硬件完全不重要,一小时60分,一分60秒,这完全是逻辑问题,我只要实现了秒,那么,分,时,月,年就很容易换算了。

重要的是输入以及输出。懂?

年代久远,东西都忘得差不多了,所以就不要问电路图什么的了,我真不知道!

你只需要稍微改一改程序,把输入输出对应上,然后……烧就完事了。

  • 9
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值