//*************************C語言寫的可調數字時鐘顯示 *************************
//*******************************2009-10-15***********************************
//***************************可調數字鐘功能介紹*******************************
//K1:adjtime K2:hour K3:min K4:OK
//K2:lookalarm K4:OK
//K3:adjalarm K2:hh K3:mm K4:OK
//K4:SET alarm OFF/ON
//****************************************************************************
#include"reg51.h"
unsigned char ss=0,hour=12,min=0,hh=7,mm=30; //初始化 顯示12:00鬧鈴:7:30
unsigned char code leds_a[]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9
unsigned char code leds_b[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //帶點的0-9
sbit P37=P3^7; //蜂鳴器開關
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3; //數碼管選位
#define K1 0xde
#define K2 0xee
#define K3 0xf6
#define K4 0xdd //按鍵的分別代碼
TIMER_INTO();
unsigned char kbscan(); //鍵盤掃描
void lookalarm(); //查看鬧鈴
void disp_off(); //鬧鈴關的顯示
void process(); //有按鍵按下的處理
void disp_on(); //鬧鈴開的顯示
void alarm(); //鬧鈴
void disp();
unsigned char flag_alarm=0; //鬧鐘標志位,默認鬧鈴關
static unsigned int count=0; //計數器初始
unsigned int dema; //數碼管顯示的延時標中斷志
unsigned int demb; //按鍵的延時中斷標志
unsigned int demc,demd,deme; //demc,demd分別是兩種頻率的半周期計數,deme是頻率之間轉換的標志
unsigned char key,flag,temp=0; //key:按鍵代碼的返回,flag:頻率的響應時間控制,temp:控制選擇輸出頻率
main() //主程序
{
TIMER_INTO(); //定時 中斷 初始化
while(1)
{
alarm(); //鬧鈴
key=kbscan();//掃描鍵盤
process();
disp();
}
}
void process() //按鍵的處理
{
if(key!=0)
{
if(key==K1)
{
while((key=kbscan())!=K4)
{
disp_off();
if((key=kbscan())==K2)
{
hour++;
disp_off();
if(hour>=24)
{
hour=0;
}
}
if((key=kbscan())==K3)
{
min++;
if(min>=60)
{
min=0;
}
}
}
}
else if(key==K2)
{
while((key=kbscan())!=K4)
{
lookalarm();
}
}
else if(key==K3)
{
while((key=kbscan())!=K4)
{
lookalarm();
if((key=kbscan())==K2)
{
hh++;
lookalarm();
if(hh>=24)
{
hh=0;
}
}
if((key=kbscan())==K3)
{
mm++;
if(mm>=60)
{
mm=0;
}
}
}
}
else if(key==K4)
{
if(flag_alarm==0)
{
flag_alarm=1;
}
else
{
flag_alarm=0;
}
}
}
}
TIMER_INTO() //中斷初始化
{
TMOD=0X01;
TH0=0Xfe;
TL0=0X0c; //500uS初值
TR0=1;
ET0=1;
EA=1;
}
timer0() interrupt 1 //中斷進程
{
TR0=0;
TH0=0Xfe;
TL0=0X0c; //重裝初值
TR0=1;
if(dema)
{
dema--; //2mS延時
}
if(demb)
{
demb--; //40mS延時
}
if(demc)
{
demc--;
}
if(demd)
{
demd--;
}
flag++;
if(flag>=2000)//調整此處可以調整頻率響應的時間
{
flag=0;
temp=1;
deme++;
if(deme>=2)
{
deme=0;//這里設計的是500HZ響應1S,1kHZ響應1S
temp=0;
}
}
count++;
if(count>=2000) //1S延時
{
count=0;
ss++;
if(ss>=60)
{
ss=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24)
{
hour=0;
}
}
}
}
}
void disp()
{
if(flag_alarm==0)
{
disp_off(); //關閉鬧鐘的顯示
}
else
{
disp_on(); //鬧鐘開啟 的顯示
}
}
void disp_off() //鬧鈴關的走時
{
P23=0;
P0=leds_a[min%10];
dema =4;//2mS
while(dema!=0);
P23=1;
P22=0;
P0=leds_a[min/10];
dema =4;
while(dema!=0);
P22=1;
P21=0;
P0=leds_b[hour%10];
dema =4;
while(dema!=0);
P21=1;
P20=0;
P0=leds_a[hour/10];
dema =4;
while(dema!=0);
P20=1;
}
void disp_on() //鬧鈴開的走時
{
P23=0;
P0=leds_b[min%10];
dema =4;
while(dema!=0);
P23=1;
P22=0;
P0=leds_a[min/10];
dema =4;
while(dema!=0);
P22=1;
P21=0;
P0=leds_b[hour%10];
dema =4;
while(dema!=0);
P21=1;
P20=0;
P0=leds_a[hour/10];
dema =4;
while(dema!=0);
P20=1;
}
void lookalarm() //查看鬧鐘
{
P23=0;
P0=leds_a[mm%10];
dema =4;
while(dema!=0);
P23=1;
P22=0;
P0=leds_a[mm/10];
dema =4;
while(dema!=0);
P22=1;
P21=0;
P0=leds_b[hh%10];
dema =4;
while(dema!=0);
P21=1;
P20=0;
P0=leds_a[hh/10];
dema =4;
while(dema!=0);
P20=1;
}
unsigned char kbscan() //掃描鍵盤
{
unsigned char sccode,recode,temp;
P1=0XF8;
temp=P1;
if(temp!=0xf8)
{
demb=80; //40mS
while(demb!=0);
if(temp==P1)
{
sccode=0xfe;
while((sccode&0xf7)!=0)
{
P1=sccode;
if((P1&0xf8)!=0xf8)
{
recode=P1&0Xf8;
sccode=sccode&0xc7;
return(recode|sccode);
}
else
sccode=sccode<<1|0x01;
}
}
}
return(0);
}
void alarm()//鬧鈴
{
if((min==mm)&&(hour==hh))
{
if(flag_alarm==1)
{
if(temp)
{
demb=2;
while(demb!=0);//500HZ 1mS取反
P37=~P37;
}
else
{
dema=1;
while(dema!=0);//1KHZ 500uS取反
P37=~P37;
}
}
else
{
P37=1;
}
}
else
P37=1;
}