/************************************************************************************************************
程序效果:上电后,倒计时默认为40分钟,继电器吸合,台灯亮;倒计时至0分钟,继电器断开,台灯熄灭,蜂鸣器报警。
1:倒计时过程中按下K0键,时间跳到0分钟,断开继电器,熄灭台灯;然后按下K一键增加固定时间,
每次增加5分钟,最大时间为95分钟。
2:设定时间后,按下K0键确认,继电器吸合,台灯点亮,倒计时开始。
注:定时器按11.0592MHZ晶振设计。
*************************************************************************************************************/
#include //头文件
//#include///包含移位寄存器的头文件
#define uchar unsigned char//宏定义
#define uint unsigned int
sbit key1=P3^2; //时间设置键
sbit key2=P3^3; //时间加
sbit fmq=P3^6; //蜂鸣器 开发板定义本行及以下行为
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秒
****************************************************/
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]; //显示个位
min1=0;
delay250us(5);
}
if(flag<=10)
{
min10=1;
min1=1;
P0=(table[fen]&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) /
{
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++; //标志位
}