电子时钟 键盘扫描代码
#include "STC/STC15F2K60S2.H"
sbit SEGLE=P2^7;
sbit DIGLE=P2^6;
sbit LEDLE=P2^5;
unsigned char code Tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char code Tab1[10] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
unsigned char count; //记录中断次数
char second; //储存秒
char min;
char hour;
unsigned char num;
unsigned char keyval,index,k,min1,second1,hour1;
void delay(void) //延时约0.6毫秒
{
unsigned char i;
for(i=0;i<200;i++) ;
}
//消抖 延迟
void delay30ms(void)
{
unsigned char i,j;
for(i = 0;i < 100;i++)
for(j = 0;j < 100;j++);
}
void Displaysecond(unsigned char k);
void Displaymin(unsigned char k);
void Displayhour(unsigned char k);
unsigned char keyscan();
void leftmove();
void rightmove();
void jian();
void add();
void main(void) //主函数
{
P0 = 0x00;
DIGLE = 1;
DIGLE = 0;
SEGLE = 1;
SEGLE = 0;
P0 = 0xff;
LEDLE = 1;
LEDLE = 0;
TMOD=0x01;
TH0=(65536-46083)/256; //=50000微秒=50毫秒
TL0=(65536-46083)%256;
EA=1;
ET0=1;
TR0=1;
k = 1;
index = 0; //允许标志
count=0; //中断次数初始化
second=0; //秒初始化
min=0;
hour=0;
while(1)
{
switch(keyval)
{
case 0:
Displayhour(hour);
Displaymin(min);
Displaysecond(second);
keyval = keyscan();
break;
case 1:
index = 1; //设置允许位置1
TR0 = 0; //关闭时钟0
hour1 = hour; //将修改后的时间变量的值
min1 = min; //赋值给存储时间初始值变量
second1 = second; //
keyval = 0;
break;
case 3:
if(!index) //是否允许进行设置
{
keyval = 0;
break;
}
index = 0; //设置允许位置0
TR0 = 1; //打开时钟0
keyval = 0; //确认时间设定
break;
case 4:
if(!index)
{
keyval = 0;
break;
}
hour = hour1; //将存储时间初始值变量的值
min = min1; //赋值给修改后的时间变量
second = second1; //
keyval = 0;
break;
case 10:
if(!index)
{
keyval = 0;
break;
}
leftmove(); //数码管位选左移
break;
case 12:
if(!index)
{
keyval = 0;
break;
}
rightmove(); //数码管位选右移
break;
case 7:
if(!index)
{
keyval = 0;
break;
}
add(); //选定时间值加1
break;
case 15:
if(!index)
{
keyval = 0;
break;
}
jian(); //选定时间值减1
break;
default:
keyval = 0; //键码赋值0,进行下次扫描
break;
}
}
}
void time0() interrupt 1 using 1
{
TR0 = 0;
count++;
if(count==20)
{
count=0;
second++;
if(second == 60)
{
second = 0;
min++;
if(min == 60)
{
min = 0;
hour++;
if(hour == 24)
hour = 0;
}
}
}
TH0=(65536-46083)/256; //重新给计数器T0赋初值
TL0=(65536-46083)%256;
TR0=1; //启动定时器T0
}
//键盘扫描
unsigned char keyscan()
{
unsigned char scode; //定义行扫描变量
unsigned char rcode ; //定义返回编码变量
unsigned char m; //定义行首编码变量
unsigned char k; //定义列检测码
unsigned char i,j; //定义循环控制变量
P1 = 0x0f; //发全列为0扫描码,行线输入
if((P1 & 0x0f) != 0x0f) //若有键按下
{
delay30ms(); //延时消抖
if((P1 & 0x0f) != 0x0f) //若有键按下
{
m = 1; //行首编码变量赋初值
scode = 0xfe; //行扫描变量赋初值
for(i = 0;i < 4;i++)
{
P1 = scode; //输出列线吗
k = 0x10; //列检测码赋初值
for(j = 0;j < 4;j++)
{
if((P1 & k) == 0) //本列有键按下
{
rcode = m + j; //求键码
while((P1 & 0xf0) != 0xf0); //等待按键释放
return (rcode); //返回键码
}
else
k = k <<1 ; //列检测码左移一位
}
m = m + 4; //下一行行首编码
scode = scode << 1; //行扫描变量左移一位
}
}
}
return 0; //若没键按下,返回0
}
void Displaysecond(unsigned char k)
{
P0=0xef;
SEGLE=1;
SEGLE=0;
P0=Tab[k/10];
DIGLE=1;
DIGLE=0;
delay();
P0=0xdf;
SEGLE=1;
SEGLE=0;
P0=Tab[k%10];
DIGLE=1;
DIGLE=0;
delay();
}
void Displaymin(unsigned char k)
{
P0=0xfb;
SEGLE=1;
SEGLE=0;
P0=Tab[k/10];
DIGLE=1;
DIGLE=0;
delay();
P0=0xf7;
SEGLE=1;
SEGLE=0;
P0=Tab1[k%10];
DIGLE=1;
DIGLE=0;
delay();
}
void Displayhour(unsigned char k)
{
P0=0xfe;
SEGLE=1;
SEGLE=0;
P0=Tab[k/10];
DIGLE=1;
DIGLE=0;
delay();
P0=0xfd;
SEGLE=1;
SEGLE=0;
P0=Tab1[k%10];
DIGLE=1;
DIGLE=0;
delay();
}
void leftmove()
{
k--;
if(k < 1)
k=3;
while(keyval == 10||keyval == 0 ) //没有键按下,显示选中数码管位
{
if(k ==3)
Displaysecond(second);
if(k ==2)
Displaymin(min);
if(k == 1)
Displayhour(hour);
keyval = keyscan(); //键盘扫描
if(keyval == 10) //若本函数的识别键再次被按下,则退出循环
break;
}
}
void rightmove()
{
k++;
if(k > 3)
k=1;
while(keyval == 12 || keyval == 0) //没有键按下,显示选中数码管位
{
if(k ==3)
Displaysecond(second);
if(k ==2)
Displaymin(min);
if(k == 1)
Displayhour(hour);
keyval = keyscan(); //键盘扫描
if(keyval == 12) //若本函数的识别键再次被按下,则退出循环
break;
}
}
void add()
{
if(k == 3) //数码管位选为秒位
{
second++;
if(second == 60)
second = 0;
}
if(k == 2) //数码管位选为分位
{
min++;
if(min == 60)
min = 0;
}
if(k == 1) //数码管位选为时位
{
hour++;
if(hour == 24)
hour = 0;
}
while(keyval == 7 || keyval == 0) //没有键按下,显示选中数码管位
{
Displaysecond(second);
Displaymin(min);
Displayhour(hour);
keyval = keyscan(); //键盘扫描
if(keyval == 7) //若本函数的识别键再次被按下,则退出循环
break;
}
}
void jian()
{
if(k == 3)
{
second--;
if(second < 0)
second = 59;
}
if(k == 2)
{
min--;
if(min < 0)
min = 59;
}
if(k == 1)
{
hour--;
if(hour< 0)
hour = 23;
}
while(keyval == 15 || keyval == 0)
{
Displayhour(hour);
Displaymin(min);
Displaysecond(second);
keyval = keyscan();
if(keyval == 15)
break;
}
}