//矩阵键盘扫描和可调的电子时钟
//选用翻转辨认法(相对代码少一些)处理矩阵键盘,
//在按下15号键的时分处理电子时钟,然后能够发动12号键
//用来调理时刻
#include
#define uchar unsigned char //类型重界说
#define uint unsigned int
uchar key=0;
uchar count=0;
int second=40,minute=59,hour=23;
int second_shi=0,second_ge=0,minute_shi=0,minute_ge=0,hour_shi=0,hour_ge=0;
uchar flag=0;//界说标志位(判别15号键是不是按下)
uchar movePlace;//调理时钟时的定位方位计数
//以下是界说6个数码管是否加上小数点
uchar point0=0;
uchar point1=0;
uchar point2=0x80;
uchar point3=0;
uchar point4=0x80;
uchar point5=0;
//共阴数码管编码如下(0-15)
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
//位选编码(选中第0-7位数码管)
uchar code table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//函数声明
void display(uchar Duan_value);//显现按键值函数
void delay(uchar t);//延时1ms函数
void key_scan();//按键扫描函数
void display_time();//显现电子时钟函数
void init();//寄存器初始化函数
void main()
{
init();//寄存器初始化
while(1)
{
key_scan();//按键扫描
if(flag==1)//15号键按下,处理电子时钟
{
if(movePlace==1)
{//按键定位到秒值方位,对应的秒值小数点亮
point0=0x80;
point1=0x80;
point2=0;
point3=0;
point4=0;
point5=0;
}
else if(movePlace==2)
{//按键定位到秒值方位,对应的分值小数点亮
point0=0;
point1=0;
point2=0x80;
point3=0x80;
point4=0;
point5=0;
}
else if(movePlace==3)
{//按键定位到秒值方位,对应的小时小数点亮
point0=0;
point1=0;
point2=0;
point3=0;
point4=0x80;
point5=0x80;
}
else if(movePlace==0)
{//按键定位归零,封闭时钟显现,回复默认值
point0=0;//小时与分中心加小数点,分与秒之间加小数点
point1=0;
point2=0x80;
point3=0;
point4=0x80;
point5=0;
}
display_time();//显现时钟值
}
else//15号键没有按下
{
display(key);//终究一位显现按键值
}
}
}
//守时器初始化函数
void init()
{
TMOD=0x01;//设定守时器0作业在方法1:16位守时器
TH0=(65536-50000)/256; //每50ms中止1次
TL0=(65536-50000)%256;
EA=1;//敞开总中止
ET0=1;//敞开守时器中止
TR0=1;//敞开守时器
}
//延时1ms函数
void delay(uchar t)
{
uchar x,y;
for(x=t;t>0;t–)
for(y=111;y>0;y–);
}
//按键数码管显现函数
void display(uchar value)
{
P2=table[value];
P3=table1[5];//只显现终究一位
delay(10);
}
//按键扫描函数
void key_scan()
{
uchar m0,m1;
uchar temp;
P1=0xf0;//这样设置是为了能使低四位将高四位拉低,开释时主动拉高高四位
temp=P1;
if(temp!=0xf0)
{
delay(10);//延时,去除颤动
if(temp!=0xf0)
{
m0=temp;//取得按键的列号(对应的便是高4位)
P1=0x0f;
temp=P1;
if(temp!=0x0f)
{
m1=temp;//取得按键的行号(对应的便是低4位)
temp=m0|m1;//组合成终究的按键好
}
switch(temp)
{
case 0xee:key=0;break;//按键对应的码表
case 0xde:key=1;break;
case 0xbe:key=2;break;
case 0x7e:key=3;break;
case 0xed:key=4;break;
case 0xdd:key=5;break;
case 0xbd:key=6;break;
case 0x7d:key=7;break;
case 0xeb:key=8;break;
case 0xdb:key=9;break;
case 0xbb:key=10;break;
case 0x7b:key=11;break;
case 0xe7:key=12;
if(flag==1)//15号键按下后,12号键按下,开端设置时钟
{
TR0=0;//设置时,封闭守时器
movePlace++;//对应的方位标量+1
if(movePlace==4)//假如按下了4下,表明撤销
{
TR0=1;//从头敞开守时器
movePlace=0;
flag=0;//封闭时钟显现,从头翻开按键显现
}
}
break;
case 0xd7:key=13;
if(flag==1)//若开端设置时钟,13键表明向上+1按键
{
if(movePlace==1) //秒值设置
{
second++;
if(second==60)
second=0;
}
else if(movePlace==2) //分值设置
{
minute++;
if(minute==60)
minute=0;
}
else if(movePlace==3)//小时设置
{
hour++;
if(hour==24)
hour=0;
}
}
break;
case 0xb7:key=14;
if(flag==1)//若开端设置时钟,14键表明向上-1按键
{
if(movePlace==1)//秒值设置
{
second–;
if(second==-1)
second=59;
}
else if(movePlace==2)//分值设置
{
minute–;
if(minute==-1)
minute=59;
}
else if(movePlace==3)//小时设置
{
hour–;
if(hour==-1)
hour=23;
}
}
break;
case 0x77:key=15;
flag=1;//当15号键按下去之后,把标志方位1,表明显现时钟
break;
}
do{
temp=P1;//消除按起颤动
temp&=0X0f;
}while(temp!=0x0f);
}
}
}
//显现电子时钟函数
void display_time()
{
second_shi=second/10; //别离得届时,分,秒值的个位,十位
second_ge=second%10;
minute_shi=minute/10;
minute_ge=minute%10;
hour_shi=hour/10;
hour_ge=hour%10;
P3=0xff;//消影处理显现秒值的个位
P2=table[second_ge]|point0; //是否显现小数点
P3=table1[5];
delay(3);
P3=0xff;//显现秒值的十位
P2=table[second_shi]|point1;
P3=table1[4];
delay(3);
P3=0xff;//显现分值的个位
P2=table[minute_ge]|point2;
P3=table1[3];
delay(3);
P3=0xff;//显现分值的十位
P2=table[minute_shi]|point3;
P3=table1[2];
delay(3);
P3=0xff;//显现小时的个位
P2=table[hour_ge]|point4;
P3=table1[1];
delay(3);
P3=0xff;//显现小时的十位
P2=table[hour_shi]|point5;
P3=table1[0];
delay(3);
}
//守时器0中止函数
void time0() interrupt 1using 0
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20)
{
count=0;
second++; //守时1s钟,秒值加1
if(second==60)
{
second=0;
minute++;//分钟加1
if(minute==60)
{
minute=0;
hour++;//小时加1
if(hour==24)
{
hour=0;
}
}
}
}
}