p3,p0为led显示。p1为键盘输入。p2_0为开关控制。最大定时为90分钟。
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar keyscan(); // 键盘扫描
void jianchu(); //键值处理
void xian(); // 显示
void ji(); // 计时中断
uchar ledcode[]=
{
//0 1 2 3 4
0x3f,0x06,0x5b,0x4f,0x66,
//5 6 7 8 9
0x6d,0x7d,0x07,0x7f,0x6f,
//A b C d E F
0x77,0x7c,0x39,0x5e,0x79,0x71,
};
uchar state; //按键次数
uint s,d,sd; //十进制字符
sbit P2_0=P2^0; //开关控制端
void delay(void)
{
uchar i;
for(i=0;i<200;i++)
{}
}
uchar keyscan(void)
{
uchar code_h; //行扫描
uchar code_l; //列扫描
P1=0xf0;
if((P1&0xf0)!=0xf0)
{
delay();
if((P1&0xf0)!=0xf0)
{
code_h=0xfe;
while((code_h&0x10)!=0xf0) //判断是否为最后一行,如不是,继续扫描
{
P1=code_h; //P1口输出行扫描值
if((P1&0xf0)!=0xf0) //如果P1.4~p1.7不全为1,该行有键按下
{
code_l=(P1&0xf0|0x0f); //保留P1口高四位,低四位变为1,作为列值
return((~code_h)+(~code_l));//键编码=行扫描值+列扫描值,返回主程序
}
else
code_h=(code_h<<1)|0x01; //这里是左移0x01的作用是,我们左移时系统补在后面的是0,不加这个就会读错
}
}
}
return(0); //无键按下,返回0
}
void main()
{
P2_0=1;
keyscan();
jianchu();
delay();
xian();
while(!sd)
{
P2_0=0;
}
}
void jianchu(void) //键处理函数
{
uchar key;
uint a;
key=keyscan();
switch(key)
{
case 0x11:a=0;break;
case 0x21:a=1;break;
case 0x41:a=2;break;
case 0x71:a=3;break;
case 0x12:a=4;break;
case 0x22:a=5;break;
case 0x42:a=6;break;
case 0x72:a=7;break;
case 0x14:a=8;break;
case 0x24:a=9;break;
case 0x44:a=10;break; //输入计时
case 0x74:a=11;break; //开始计时
case 0x17:a=12;break;
case 0x27:a=13;break;
case 0x47:a=14;break;
case 0x77:a=15;break;
}
while(a=10)
{
keyscan();
s=a*10;
keyscan();
d=a;
sd=s+d;
while(a=11)
{
delay();
TMOD=0X02;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
ji();
}
}
}
void ji(void) interrupt 1 using 1 //定时函数
{
uint i;
while(1)
{
for(i=0;i<120;i++)
{
do{}while(!TF0);
}
sd--;
}
}
void xian() //显示函数
{
P3=ledcode[sd/10];
P0=ledcode[sd%10];
} |