/************************************************************************************************************
程序效果:上電后,倒計時默認為40分鐘,繼電器吸合,臺燈點亮;倒計時至0分鐘時,繼電器斷開,臺燈熄滅,蜂鳴器報警。
1:倒計時過程中,按一下K0鍵,時間跳至0分鐘,斷開繼電器,臺燈熄滅;再按K1鍵增加定時時間,
每按1次增加5分鐘,最大定時時間為95分鐘。
2:設置好定時時間后,按一下K0鍵確認,繼電器吸合,臺燈點亮,倒計時開始。
說明:定時器按11.0592MHZ晶振設計。
*************************************************************************************************************/
#include<reg52.h> //頭文件
//#include<intrins.h> //包含移位寄存器的頭文件
#define uchar unsigned char//宏定義
#define uint unsigned int
sbit key1=P3^2; //時間設置鍵
sbit key2=P3^3; //時間加
sbit fmq=P3^6; //蜂鳴器 本行與以下3行為開發板定義
sbit jdq=P3^7; //繼電器
sbit min10=P2^6; //十分位數碼管
sbit min1=P2^7; //個分位數碼管
//sbit fmq=P1^5; //蜂鳴器 本行與以下3行為紅外臺燈定時控制板定義
//sbit jdq=P1^6; //繼電器
//sbit min10=P1^0; //十分位數碼管
//sbit min1=P1^1; //個分位數碼管
/*uchar code table[]={0x3f,0x06,0x5b,//數碼管顯示的數值(共陰)
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0xbf,0x86,0xdb,//帶小數點的數值
0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; */
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
//數碼管顯示的數值(共陽0,1,2,3,4,5,6,7,8,9,)
/*0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10*/};
//帶小數點的數值 (0./1./2./3./4./5./6./7./8./9.)
void jia(); //函數聲明
uchar fen=40,miao=59; //顯示初始值
uchar flag,cnt,count;//定義全局變量
/********************************************
延時子程序0.25MS
******************************************/
void delay250us(unsigned int i)
{
unsigned char j;
while(i--)
{
for(j=25;j>0;j--);
}
}
/****************************************************
蜂鳴器發聲函數,每1次大約響1秒
****************************************************/
void beep(unsigned char a) //
{
unsigned int b;
while(a--)
{
for(b=0;b<1000;b++)
{
fmq=0;
delay250us(1);
fmq=1;
delay250us(1);
}
}
}
/****************************************************
初始化函數
****************************************************/
void init()
{
TMOD=0X01; //工作方式1
TH0=0x49; //定時時間為:50ms
TL0=0x44;
ET0=1; //打開定時器
EA=1; //開總中斷
TR0=1; //啟動定時器
}
/****************************************************
顯示子函數,用于顯示時間數值
****************************************************/
void display()
{
min10=1;
min1=1;
P0=table[fen/10]; //顯示十分位
min10=0;
delay250us(5);
if(flag>10)
{
min10=1;
min1=1;
P0=table[fen%10]; //顯示個分位
min1=0;
delay250us(5);
}
if(flag<=10)
{
min10=1;
min1=1;
P0=(table[fen%10]&0x7f); //顯示個分位
min1=0;
delay250us(5);
}
}
/****************************************************
時間子函數
****************************************************/
void shijian()
{
if(flag>=20) //判斷是否到一秒
{
flag=0; //到了,則標志位清零
miao--; //秒減1
if(miao<=0) //判斷秒是否到0s
{
miao=59;//到了,則秒為59S
fen--; //分減1
if(fen<=0) //如果分計時至0分鐘
{
fen=0;
miao=0;
beep(1); //蜂鳴器報警
TR0=0; //關閉定時器
//TH0=(65536-50000)/256; //定時時間為:50ms
//TL0=(65536-50000)%256;
}
}
}
}
/****************************************************
鍵盤掃描子函數
****************************************************/
void key_scan()
{
if(key1==0) //判斷設置鍵是否按下
{
while(!key1) //防止掉顯
{
if(cnt==0||cnt==1||cnt==2) //設置按鍵沒按下或按1次或按2次
{
display();
}
}
cnt++; //記下按鍵key1按下的次數
if(cnt==1) //如果設置鍵按下第1次
{
TR0=0; //停止計數
fen=0;miao=59; //將時間設置為0分鐘
display();
}
if(cnt==2) //如果設置鍵按下第2次
{
cnt=0; //按下次數清零
if(fen>0) //如果設置分鐘值大于0分鐘
{
TR0=1; //開始計數
}
}
}
if(key2==0) //判斷時間增加鍵是否按下
{
while(!key2) //防止掉顯
{
if(cnt==0||cnt==1||cnt==2||cnt==3)
{
display();
}
}
jia();//調用時間增加子函數
}
}
/****************************************************
時間增加子函數
****************************************************/
void jia() //
{
if(cnt==1) //判斷設置鍵按下的次數是否為第1次
{
fen=fen+5; //是,則分鐘加5
if(fen>99) //判斷分鐘是否大于99,是,則分鐘清零
fen=0;
}
}
/****************************************************
主函數
****************************************************/
void main()
{
delay250us(800); //上電后延時2S啟動定時器和繼電器工作,防止燒燈。
init();//調用初始化子函數
while(1)
{
key_scan(); //調用鍵盤掃描子函數
shijian(); //時間子函數
if(cnt==0||cnt==1||cnt==2||cnt==3)
{
display();
}
if(fen!=0&&cnt!=1)
{
jdq=0;
}
else jdq=1;
}
}
/****************************************************
定時器函數
****************************************************/
void time0() interrupt 1 //定時器0
{
TH0=0x49; //初值50ms
TL0=0x44;
flag++; //標志位
}
|