一、程序
#include <REG52.h>
#include "main.h"
sbit key1=P3^0;
sbit key2=P3^1;
sbit key3=P3^2;
sbit key4=P3^3;
sbit SW=P1^0;
unsigned char code SEG[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8E,0x86};
unsigned char i,cp,cp1,flash,key1flag,key2flag,key3flag,key4flag,MODE,dingshiflag=1;
char hour=23,min=29,sec=56,hour_t=23,min_t=30;
void delay(unsigned int x)
{
while(x--);
}
void display(void)
{
P0=0xFF; // proteus 仿真需要消隐
if(MODE==0)
{
switch(i)
// 共阳极,低电平显示
{ // 位或运算符:| 任意一个为1,结果就为1,否则为0
// 位与运算符:& 都为1,结果就为1,否则为0
// 当flash为0xFF(11111111)时,0x7F|flash为0xFF,运算后仍为SEG[min%0]
// 当flash为0x00(00000000)时,0x7F|flash为0x7F,运算后SEG[min%10]的
// 最高位变为0,小数点显示
case 0:P0=SEG[sec%10];P2=0xFE;break; // P2:1111 1110,最后一位为0,最后一位显示
case 1:P0=SEG[sec/10];P2=0xFD;break; //0000 0000 P2:1111 1101
case 2:P0=SEG[min%10]&(0x7F|flash);P2=0xFB;break; //0111 1111
case 3:P0=SEG[min/10];P2=0xF7;break;
case 4:P0=SEG[hour%10]&(0x7F|flash);P2=0xEF;break;
case 5:P0=SEG[hour/10];P2=0xDF;break;
}
}
if(MODE==1)
{
switch(i)
{
case 0:P0=SEG[sec%10];P2=0xFE;break;
case 1:P0=SEG[sec/10];P2=0xFD;break; //0000 0000
case 2:P0=SEG[min%10]&(0x7F|flash);P2=0xFB;break; //0111 1111
case 3:P0=SEG[min/10];P2=0xF7;break;
case 4:P0=SEG[hour%10]|flash;P2=0xEF;break;
case 5:P0=SEG[hour/10]|flash;P2=0xDF;break;
}
}
if(MODE==2)
{
switch(i)
{
case 0:P0=SEG[sec%10];P2=0xFE;break;
case 1:P0=SEG[sec/10];P2=0xFD;break; //0000 0000
case 2:P0=SEG[min%10]|flash;P2=0xFB;break; //0111 1111
case 3:P0=SEG[min/10]|flash;P2=0xF7;break;
case 4:P0=SEG[hour%10]&(0x7F|flash);P2=0xEF;break;
case 5:P0=SEG[hour/10];P2=0xDF;break;
}
}
if(MODE==3)
{
switch(i)
{
case 0:P0=SEG[sec%10]|flash;P2=0xFE;break;
case 1:P0=SEG[sec/10]|flash;P2=0xFD;break; //0000 0000
case 2:P0=SEG[min%10]&(0x7F|flash);P2=0xFB;break; //0111 1111
case 3:P0=SEG[min/10];P2=0xF7;break;
case 4:P0=SEG[hour%10]&(0x7F|flash);P2=0xEF;break;
case 5:P0=SEG[hour/10];P2=0xDF;break;
}
}
if(MODE==4)
{
switch(i)
{
case 0: if(dingshiflag==0) P0=SEG[10];
else P0=SEG[11]; P2=0xFE;break;
case 1:P0=0xFF;P2=0xFD;break; //0000 0000
case 2:P0=SEG[min_t%10]&(0x7F|flash);P2=0xFB;break; //0111 1111
case 3:P0=SEG[min_t/10];P2=0xF7;break;
case 4:P0=SEG[hour_t%10]|flash;P2=0xEF;break;
case 5:P0=SEG[hour_t/10]|flash;P2=0xDF;break;
}
}
if(MODE==5)
{
switch(i)
{
case 0: if(dingshiflag==0) P0=SEG[10];
else P0=SEG[11]; P2=0xFE;break;
case 1:P0=0xFF;P2=0xFD;break; //0000 0000
case 2:P0=SEG[min_t%10]|flash;P2=0xFB;break; //0111 1111
case 3:P0=SEG[min_t/10]|flash;P2=0xF7;break;
case 4:P0=SEG[hour_t%10]&(0x7F|flash);P2=0xEF;break;
case 5:P0=SEG[hour_t/10];P2=0xDF;break;
}
}
if(MODE==6)
{
switch(i)
{
case 0: if(dingshiflag==0) P0=SEG[10]|flash;
else P0=SEG[11]|flash; P2=0xFE;break;
case 1:P0=0xFF;P2=0xFD;break; //0000 0000
case 2:P0=SEG[min_t%10];P2=0xFB;break; //0111 1111
case 3:P0=SEG[min_t/10];P2=0xF7;break;
case 4:P0=SEG[hour_t%10]&(0x7F|flash);P2=0xEF;break;
case 5:P0=SEG[hour_t/10];P2=0xDF;break;
}
}
i++;
if(i>=6) i=0;
}
void key(void)
{
if(key1==0) //MODE
{
delay(300); // 延迟为了消抖
{
if(key1==0)
{
key1flag=1; // 消抖
}
}
}
if((key1==1)&&(key1flag==1)) // 消完抖之后要进行的行为
{
key1flag=0;
MODE++;
if(MODE>=7) MODE=0;
}
if(key2==0) // ++
{
delay(300);
{
if(key2==0)
{
key2flag=1;
}
}
}
if((key2==1)&&(key2flag==1))
{
key2flag=0;
if(MODE==1)
{
hour++;
if(hour>=24) hour=0;
}
if(MODE==2)
{
min++;
if(min>=60) min=0;
}
if(MODE==3)
{
sec++;
if(sec>=60) sec=0;
}
if(MODE==4)
{
hour_t++;
if(hour_t>=24) hour_t=0;
}
if(MODE==5)
{
min_t++;
if(min_t>=60) min_t=0;
}
if(MODE==6)
{
dingshiflag=!dingshiflag;
}
}
if(key3==0) // --
{
delay(300);
{
if(key3==0)
{
key3flag=1;
}
}
}
if((key3==1)&&(key3flag==1))
{
key3flag=0;
if(MODE==1)
{
hour--;
if(hour<0) hour=23;
}
if(MODE==2)
{
min--;
if(min<0) min=59;
}
if(MODE==3)
{
sec--;
if(sec<0) sec=59;
}
if(MODE==4)
{
hour_t--;
if(hour_t<0) hour_t=23;
}
if(MODE==5)
{
min_t--;
if(min_t<0) min_t=59;
}
if(MODE==2)
{
dingshiflag=!dingshiflag;
}
}
if(key4==0)
{
delay(300);
{
if(key4==0)
{
key4flag=1;
}
}
}
if((key4==1)&&(key4flag==1))
{
key4flag=0;
dingshiflag=!dingshiflag;
}
}
void main(void)
{
EA=1; // 打开中断总开关
ET0=1; // 设置中断允许寄存器IE中ET0的位,开启中断小开关
TMOD=0X01; // 设置计时器模式控制寄存器,Time0工作在定时方式1
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1; // 开始计数
SW=0;
while(1)
{
key();
if((hour==hour_t)&&(min==min_t)&(dingshiflag==1)) SW=1;
else SW=0;
}
}
void T0_ISP(void) interrupt 1 // 中断100次,为0.5秒
{
TH0=(65536-5000)/256; // 重装初值
TL0=(65536-5000)%256; // 重装初值
display();
cp++;
if(cp>=100)
{
cp=0;
flash=~flash;
cp1++;
if(cp1>=2)
{
cp1=0;
if(MODE==0) sec++;// 就是在不按模式的情况下,时间表才走
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24) hour=0;
}
}
}
}
}
二、仿真