#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit fm="P3"^3; //蜂鸣器
sbit s1=P3^4; //s1按键,设置调时
sbit s2=P3^5; //s2按键,加1
sbit s3=P3^6; //s3按键,减1
sbit s4=P3^7; //s4按键,切换显示
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
//sbit led4=P1^3;
//sbit led5=P1^4;
//sbit led6=P1^5;
//sbit led7=P1^6;
//sbit led8=P1^7;
uchar count;
uchar sec,minu,hour,day,week,mon;
uchar n_sec,n_minu,n_hour;
uint year;
uchar set_1=0,set_4=0;
uchar hs,hg,mis,mig,ss,sg;
uchar nhs,nhg,nms,nmg,nss=0,nsg=0;
uchar ms,mg,ds,dg,w;
unsigned char data dis_digit;
unsigned char code dis_code[12]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff,0xbf};// 4, 5, 6, 7, 8, 9, off, -, --共阳
unsigned char data dis_buf[8];
unsigned char data dis_index;
uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年
void delay(uint); //延时函数
void timer0(); //走时中断函数
void jishi(); //计时函数
void key_change(); //切换显示按键函数
void key_set(); //设置时间按键函数
void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示的数据
void zd_clock(); //整点报时函数
void nz_clock(); //闹钟函数
uchar incone(uchar); //加1函数
uchar decone(uchar); //减1函数
void set_time(); //设置时间函数
void set_clock(); //设置闹钟函数
void set_mdw(); //设置月日星期函数
void main() //主函数
{
IE = 0x8a; // 使能timer0,1 中断
TR0 = 1;
TR1 = 1;
TMOD = 0x11; // 定时器0, 1工作模式1, 16位定时方式
dis_digit = 0xfe;
dis_index = 0;
hour=12;minu=0;sec=0; //赋初值:12点0分0秒
n_hour=8;n_minu=30;n_sec=00; //闹钟赋初值8点30分0秒
year=2008;mon=12;day=25;week=4;//年月日星期赋初值2008年12月25日星期四;
while(1)
{
hs="hour/10"; //时分秒HH.MM.SS
hg="hour"%10;
mis="minu/10";
mig="minu"%10;
ss="sec/10";
sg="sec"%10;
ms="mon/10"; //月日-星期MM.DD.-W
mg="mon"%10;
ds="day/10";
dg="day"%10;
w="week";
nhs="n"_hour/10; //闹钟定时HH.MM.SS
nhg="n"_hour%10;
nms="n"_minu/10;
nmg="n"_minu%10;
nss="n"_sec/10;
nsg="n"_sec%10;
key_change(); //s4按键扫描
key_set(); //s1按键扫描
set_time(); //设置时间
set_mdw(); //设置月日星期
set_clock(); //设置闹钟
if(set_4==0) //正常走时显示
{
disp(hs,hg,mis,mig,ss,sg);
}
if(set_4==1) //设置时间,LED1闪亮
{
disp(hs,hg,mis,mig,ss,sg);
if(sec%2==0)
{led2=1;led3=1;led1=~led1;}
// else
// {led1=1;}
}
if(set_4==2) //正常显示月日-星期
{
disp(ms,mg,ds,dg,11,w);
}
if(set_4==3) //设置月日-星期,LED2闪亮
{
disp(ms,mg,ds,dg,11,w);
if(sec%2==0)
{led1=1;led3=1;led2=~led2;}
// else
// {led2=1;}
}
if(set_4==4) //正常显示定时
{
disp(nhs,nhg,nms,nmg,nss,nsg);
}
if(set_4==5) //设置闹钟定时,LED3闪亮
{
disp(nhs,nhg,nms,nmg,nss,nsg);
if(sec%2==0)
{led1=1;led2=1;led3=~led3;}
// else
// {led3=1;}
}
zd_clock(); //整点报时
nz_clock(); //闹钟
}
}
void timer0() interrupt 1 //10ms中断函数
{
TMOD=0x01;
TH0=0xdc; //10ms初值 晶振12M
TL0=0x00;
count++;
if(count==100)
{
count="0";
sec++;
jishi(); //调计时函数
}
}
void jishi() //计时函数
{
if(sec==60)
{
sec="0";
minu++;
if(minu==60)
{
minu="0";
hour++;
if(hour==24)
{ hour="0";
day++;
week++;
if(week==8)
{week=1;}
if(year%4==0&&year%100!=0||year%400==0) //闰年
{
if(day==table1[mon]+1)
{
day="0";
mon++;
if(mon==13)
{mon=0;year++;}
}
}
else //非闰年
{
if(day==table2[mon]+1)
{
day="0";
mon++;
if(mon==13)
{mon=0;year++;}
}
}
}
}
}
}
void key_change() //s4按键扫描
{
if(s4==0)
{
delay(200);
if(s4==0)
{
set_4++;
while(!s4);
if(set_4==6)
{set_4=0;}
}
}
}
void key_set() //s1按键扫描
{
if(s1==0)
{
delay(10);
if(s1==0)
{
set_1++;
while(!s1);
if(set_1==3)
{set_1=0;}
}
}
}
void timer1() interrupt 3
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
// 选通P2.0口数码管
// dis_buf --- 显于缓冲区基地址
{
TH1 = 0xFC;
TL1 = 0x17;
P2 = 0xff; // 先关闭所有数码管
P0 = dis_buf[dis_index]; // 显示代码传送到P0口
P2 = dis_digit; //
dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管
dis_index++; //
dis_index &= 0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示的数据
{
dis_buf[0] = dis_code[a1]; // 时/月十位
dis_buf[1] = dis_code[a2]; // 时/月个位
dis_buf[3] = dis_code[a3]; // 分/日十位
dis_buf[4] = dis_code[a4]; // 分/日个位
dis_buf[6] = dis_code[a5]; // 秒/星期十位
dis_buf[7] = dis_code[a6]; // 秒/星期个位
dis_buf[2] = 0xbf; // 显示"-"
dis_buf[5] = 0xbf; // 显示"-"
}
void zd_clock() //整点报时函数
{
if(minu==59&&(sec==51||sec==53||sec==55||sec==57))
{
fm="0";
delay(1);
fm="1";
delay(1);
}
if(minu==59&&sec==59)
{
fm="0";
delay(1);
fm="1";
delay(1);
}
}
void nz_clock() //闹钟函数
{
if(hour==n_hour&&minu==n_minu&&sec==n_sec)
if((sec%2==0)&&sec<30)
{
fm="0";
delay(20);
fm="1";
delay(20);
}
}
void set_time() //设置时间函数
{
if(set_4==1)
{
if(set_1==0)
{
hour="incone"(hour);
if(hour==24)
{hour=0;}
// if(hour<0)
// {hour=23;}
hour="decone"(hour);
}
if(set_1==1)
{
minu="incone"(minu);
if(minu==60)
{minu=0;}
// if(minu<0)
// {minu=59;}
minu="decone"(minu);
}
}
}
void set_mdw() //设置月日星期函数
{
if(set_4==3)
{
if(set_1==0)
{
mon="incone"(mon);
if(mon==13)
{mon=1;}
mon="decone"(mon);
// if(mon==0)
// {mon=12;}
}
if(set_1==1)
{
day="incone"(day);
if(day==32)
{day=0;}
day="decone"(day);
// if(day==0)
// {day=0;}
}
if(set_1==2)
{
week="incone"(week);
if(week==8)
{week=0;}
week="decone"(week);
// if(week==0)
// {week=7;}
}
}
}
void set_clock() //设置闹钟函数
{
if(set_4==5)
{
if(set_1==0)
{
n_hour=incone(n_hour);
if(n_hour==24)
{n_hour=0;}
n_hour=decone(n_hour);
// if(n_hour==0)
// {n_hour=0;}
}
if(set_1==1)
{
n_minu=incone(n_minu);
if(n_minu==60)
{n_minu=0;}
n_minu=decone(n_minu);
// if(n_minu==0)
// {n_minu=0;}
}
}
}
uchar incone(uchar n) //加1函数
{
if(s2==0)
{ delay(200);
if(s2==0)
{
n++;
while(!s2);
}
}
return(n);
}
uchar decone(uchar m) //减1函数
{
if(s3==0)
{
delay(200);
if(s3==0)
{
m--;
while(!s3);
if(m<0)
{m=0;}
}
}
return(m);
}
void delay(uint k) //延时函数
{
uint i,j;
for(i=k;i>0;i--)
for(j=80;j>0;j--);
}
文章评论(0条评论)
登录后参与讨论