/************************************************************************************************************
程序效果:上电后,倒计时默认为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++; //标志位
}
|