#include
#include"intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit fmq=P3^0; //蜂鸣器控制
char table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0xff, 0xc6, 0xc7, 0x88,}; //共阳极数码管编码 “0-9”
// 0 1 2 3 4 5 6 7 8 9 不显示 C L A
uchar val[8]={0,0,0,0,0,0,11,12}; //数码管显示缓冲区
uint count=0; //
char shi=0,fen=0,miao=0; //时分秒变量
char nzshi=0,nzfen=0,nzmiao=0; //闹钟时分秒变量
uchar wei=0x01,duan=0; // 控制数码管段 和位显示的变量
void led() //数码管扫描函数
{
P0=0Xff;
P2=wei;
if((duan==1)||(duan==3)) //这里是加小数点用的
{
P0=(table[val[duan]]&0x7f);
}
else
{
P0=table[val[duan]];
}
duan++;
if(duan>7)
duan=0;
wei=_crol_(wei,1);
}
void time0init() //定时器0初始化
{
TMOD=0X01;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
ET0=1;
TR0=1;
EA=1;
}
uchar keytime=0; //按键
uint bjtime=0; //报警计时变量
bit sjbs=0; //按键A 控制时间走停的变量
void time0() interrupt 1 // 定时器0中断服务函数
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
if(sjbs)
{
count++;
}
bjtime++;
keytime++;
led(); //2ms扫描一次数码管显示
}
uchar key() //按键扫描程序
{
static uchar kzt=0;
uchar sb=25;
switch(kzt)
{
case 0:
P1=0xff;
if(P1!=0xff)
{
kzt=1;
return 25;
}
break;
case 1:
P1=0xff;
if(P1!=0xff)
{
switch(P1)
{
case 0xfe:
sb=1;
break;
case 0xfd:
sb=2;
break;
case 0xfb:
sb=3;
break;
case 0xf7:
sb=4;
break;
case 0xef:
sb=5;
break;
case 0xdf:
sb=6;
break;
case 0xbf:
sb=7;
break;
case 0x7f:
sb=8;
break;
}
kzt=2;
return sb;
}
else
{
kzt=0;
return 25;
}
break;
case 2:
P1=0xff;
if(P1==0xff)
{
kzt=0;
return 25;
}
break;
}
return 25;
}
void sj() //时分秒时间更新
{
if(count>499)
{
count=0;
miao++;
if(miao>59)
{
miao=0;
fen++;
if(fen>59)
{
fen=0;
shi++;
if(shi>23)
{
shi=0;
}
}
}
}
}
void main()
{
uchar keycode=25,zt=1;
bit bjbs=0;
fmq=1;
time0init(); //初始化定时器0
while(1)
{
if(keytime>9) //20ms 扫描一次按键
{
keytime=0;
keycode=key();
}
if(((fen==0)&&(miao==0))||((shi==nzshi)&&(fen==nzfen)&&(miao==nzmiao)))
{ // 判断整点 判断是否到闹钟时间
bjbs=1;
fmq=0;
bjtime=0;
}
if(bjbs) //报警处理
{
if(bjtime>30000)
{
fmq=1;
bjbs=0;
}
if((keycode>1)&&(keycode<5)) //只要在鸣叫时调节就停止鸣叫
{
bjbs=0;
fmq=1;
}
}
switch(zt)
{
case 1: // 时钟显示
val[0]=shi/10; //显示数据更新
val[1]=shi%10;
val[2]=fen/10;
val[3]=fen%10;
val[4]=miao/10;
val[5]=miao%10;
val[6]=11;
val[7]=12;
if(keycode==1) //A 时间运行与暂停
{
sjbs=!sjbs;
keycode=25;
}
sj();
if(keycode==2) //B 秒加1
{
miao++;
if(miao>59)
{
miao=0;
}
keycode=25;
}
if(keycode==3)//C分 加1
{
fen++;
if(fen>59)
{
fen=0;
}
keycode=25;
}
if(keycode==4)//D 时加1
{
shi++;
if(shi>23)
{
shi=0;
}
keycode=25;
}
if(keycode==5) //E 进入闹钟设置状态
{
zt=2;
keycode=25;
}
break;
case 2: //闹钟显示与调节
sj(); //时间更新
val[0]=nzshi/10; //显示数据更新
val[1]=nzshi%10;
val[2]=nzfen/10;
val[3]=nzfen%10;
val[4]=nzmiao/10;
val[5]=nzmiao%10;
val[6]=13;
val[7]=12;
if(keycode==2) //B 闹钟秒加1
{
nzmiao++;
if(nzmiao>59)
{
nzmiao=0;
}
keycode=25;
}
if(keycode==3) //C 闹钟分加1
{
nzfen++;
if(nzfen>59)
{
nzfen=0;
}
keycode=25;
}
if(keycode==4) //D 闹钟时加1
{
nzshi++;
if(nzshi>23)
{
nzshi=0;
}
keycode=25;
}
if(keycode==5) //E 进入时钟显示状态
{
zt=1;
keycode=25;
}
break;
}
}
}