本帖最后由 wulin 于 2019-2-11 07:33 编辑
//给你写一个1~999分钟开关机无限循环程序,利用小数点区分显示状态
//在实际电路中数码管要加限流电阻
//IO口可以按实际需要自行定义
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define key_S 20 //宏定义短按(20ms)
#define key_L 666 //宏定义长按(2/3s)
#define key_M 333 //宏定义长按步进(1/3s)
sbit K1 = P3^4; //调整选择/退出
sbit K2 = P3^5; //短按+,长按连+
sbit K3 = P3^6; //短按-,长按连-
sbit OUT= P2^2; //输出
sbit LED1= P2^3; //输出显示
sbit LED2= P2^4; //停止显示
sbit wela1=P2^5; //位选1
sbit wela2=P2^6; //位选2
sbit wela3=P2^7; //位选3
uchar code table[]={ //0~F数组
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uint Cnt1ms; //定义1毫秒变量
uchar Choice=0; //设置状态变量
uchar min_ON,min_OFF; //倒计时变量
uchar min_ON_1=3,min_OFF_1=2; //倒计时设置变量
bit sign=1,flag=0; //输出状态标志,1ms中断标志
/**************************************
定时器0/1初始化程序 @12.000MHz
**************************************/
void Timer0Init() //1毫秒@12.000MHz
{
TMOD= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TR0 = 1; //定时器0开始计时
EA=1; //开总中断
ET0=1; //开定时器0中断
}
/*************************
按键扫描程序
*************************/
void key_scan()
{
static bit key1_sign; //按键自锁标志
static uint count1,count2,count3=0;//消抖计数变量
if(!K1) //检测按键1按下
{
count1++; //消抖计数1自+1
if((count1>=key_S)&&(key1_sign==0))//检测消抖计数与按键1自锁标志
{
key1_sign=1; //按键1自锁标志置1
Choice++; //调整选择变量自+1
if(Choice>=3) //调整时间选择0正常倒计时,1调开机时长,2调关机时长
{
Choice=0; //调整时间选择清0
Cnt1ms=0; //时间变量Cnt200us自+1
min_ON=min_ON_1; //传递设定开机时长
min_OFF=min_OFF_1; //传递设定关机时长
}
}
}
else
{
key1_sign=0; //按键1自锁标志清0
count1=0; //消抖计数count1清0
}
if(!K2)
{
count2++;
if(count2>=key_L) //长按快调
{
if(Choice==1) //选择变量1调min_ON_1+
{
if(min_ON_1<999)
min_ON_1++;
}
if(Choice==2) //选择变量2调min_OFF_1+
{
if(min_OFF_1<999)
min_OFF_1++;
}
count2=key_M;
}
}
else //按键抬起
{
if(count2>key_S && count2<key_L)//短按
{
if(Choice==1) //选择变量1调min_ON_1+
{
if(min_ON_1<999)
min_ON_1++;
}
if(Choice==2) //选择变量2调min_OFF_1+
{
if(min_OFF_1<999)
min_OFF_1++;
}
}
count2=0; //count2清0
}
if(!K3)
{
count3++;
if(count3>=key_L) //长按
{
if(Choice==1) //选择变量1调min_ON_1+
{
if(min_ON_1>2)
min_ON_1--;
}
if(Choice==2) //选择变量2调min_OFF_1+
{
if(min_OFF_1>2)
min_OFF_1--;
}
count3=key_M;
}
}
else //按键抬起
{
if(count3>key_S && count3<key_L)//短按
{
if(Choice==1) //选择变量1调min_ON_1+
{
if(min_ON_1>2)
min_ON_1--;
}
if(Choice==2) //选择变量2调min_OFF_1+
{
if(min_OFF_1>2)
min_OFF_1--;
}
count3=key_M;
}
count3=0; //count3清0
}
}
/********************************
数码管显示程序
********************************/
void display()
{
static uchar num=0;
if((Choice==0)&&(sign==1))//显示开机倒计时
{
P0=0x00; //消隐
switch(num)
{
case 0:wela1=0;wela2=1;wela3=1;P0=table[min_ON / 100%10];num++;break;
case 1:wela1=1;wela2=0;wela3=1;P0=table[min_ON / 10%10];num++;break;
case 2:wela1=1;wela2=1;wela3=0;P0=table[min_ON % 10]|0x80;num=0;break;
}
}
if((Choice==0)&&(sign==0))//显示关机倒计时
{
P0=0x00; //消隐
switch(num)
{
case 0:wela1=0;wela2=1;wela3=1;P0=table[min_OFF / 100%10];num++;break;
case 1:wela1=1;wela2=0;wela3=1;P0=table[min_OFF / 10%10];num++;break;
case 2:wela1=1;wela2=1;wela3=0;P0=table[min_OFF % 10]|0x80;num=0;break;
}
}
if(Choice==1)//显示设置开机倒计时
{
P0=0x00; //消隐
switch(num)
{
case 0:wela1=0;wela2=1;wela3=1;P0=table[min_ON_1 / 100%10]|0x80;num++;break;
case 1:wela1=1;wela2=0;wela3=1;P0=table[min_ON_1 / 10%10];num++;break;
case 2:wela1=1;wela2=1;wela3=0;P0=table[min_ON_1 % 10];num=0;break;
}
}
if(Choice==2)//显示设置关机倒计时
{
P0=0x00; //消隐
switch(num)
{
case 0:wela1=0;wela2=1;wela3=1;P0=table[min_OFF_1 / 100%10];num++;break;
case 1:wela1=1;wela2=0;wela3=1;P0=table[min_OFF_1 / 10%10]|0x80;num++;break;
case 2:wela1=1;wela2=1;wela3=0;P0=table[min_OFF_1 % 10];num=0;break;
}
}
}
/********************************
主程序
********************************/
void main(void)
{
Timer0Init(); //初始化定时器
min_ON=min_ON_1; //开机倒计时赋初值
min_OFF=min_OFF_1; //关机倒计时赋初值
while(1)
{
if(min_ON>0)
{
LED1=0;
LED2=1;
OUT=0;
}
else
{
LED1=1;
LED2=0;
OUT=1;
}
if(flag==1)
{
flag=0;
if(Choice==0) //非设置状态允许计时
{
Cnt1ms++; //时间变量Cnt1ms自+1
if(Cnt1ms>=60000) //分钟
{
Cnt1ms=0;
if(sign)
{
min_ON--;
if(min_ON==0)
{
sign=0;
min_OFF=min_OFF_1;
}
}
else
{
min_OFF--;
if(min_OFF==0)
{
sign=1;
min_ON=min_ON_1;
}
}
}
}
key_scan();
display();
}
}
}
/*-----------------------------
定时器0中断服务程序 1ms
------------------------------*/
void timer0() interrupt 1
{
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
flag=1;
}
|