由定时器做到时钟,现在想改为矩阵按键,请各位大神帮忙指点?
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit shuA=P1^0;
sbit shuB=P1^1;
sbit shuC=P1^2;
uchar code table []={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40};
uint cnt100us; //定义100us变量//
uchar hour=0,min=0,sec=0;//定义时分秒变量//
/****************************
定时器0初始化程序100us
*******************************/
//void timer0Init()
//{
// TMOD=0X02; //8位自动重装载定时器//
// TH0=0X9C; //设置定时初值//
// TL0=0X9C; //设置定时初值//
// TF0=0; //清除TF0标志//
// TR0=1; //定时器0开始记时//
//}/
/********************************
计时子程序
********************************/
//void time()
//{
// if(TF0==1) //如果查询定时器溢出标志TF0为1
// {
// TF0=0; //定时器溢出周期100us
// cnt100us++; //定时器溢出标志TF0清0
// if(cnt100us>=10000) //时间变量Cnt100us自+1
// {
// cnt100us=0; //变量Cnt100us清0
// sec ++; //秒自+1
// if(sec>=60) //如果秒>=60
// {
// sec=0; //秒清0
// min++; //分自+1
// if(min>=60) //分>=60
// {
// min=0; //分清0
// hour++; //小时自+1
// if(hour>=24) //小时>=24
// hour=0; //小时清0
// }
// }
// }
//
// }
//}
/**************************
按键扫描程序
***************************/
extern unsigned char keyboard_matrix()
{
unsigned char num_key=0;//按键号
unsigned char temp=0;//读取P2口线数据
static unsigned char temp_code=0;//用于保存按键值
static unsigned char temp_circle=0xFE;//保存P2线上的循环扫描值
static unsigned char num_check=0;//低电平计数
static unsigned char key_flag=0;//按键有效标识
P2=temp_circle;//0xFX
temp=P2;//读取P2口线数据
if(temp!=temp_circle)//有按键动作
{
num_check++;//低电平计数|逢低电平加1
if(num_check==10)//连续10次(10ms)低电平有效
{
key_flag=1;//按键有效标识置1
temp_code=temp;//保存按键值
}
}
else//松手OR无按键动作,此时应该改变扫描线
{
num_check=0;
if(key_flag==1)//按键有效判断
{
key_flag=0;
switch(temp_code)//读取按键号
{
//P2^0线
case 0xEE: num_key=1;
break;
case 0xDE: num_key=2;
break;
case 0xBE: num_key=3;
break;
case 0x7E: num_key=4;
break;
//P2^1线
case 0xED: num_key=5;
break;
case 0xDD: num_key=6;
break;
case 0xBD: num_key=7;
break;
case 0x7D: num_key=8;
break;
//P2^2线
case 0xEB: num_key=9;
break;
case 0xDB: num_key=10;
break;
case 0xBB: num_key=11;
break;
case 0x7B: num_key=12;
break;
//P2^3线
case 0xE7: num_key=13;
break;
case 0xD7: num_key=14;
break;
case 0xB7: num_key=15;
break;
case 0x77: num_key=16;
break;
}
}
temp_circle=_crol_(temp_circle,1);//改变扫描线
if(temp_circle==0xEF)
{
temp_circle=0xFE;
}
}
return(num_key);//返回按键号
}
/*******************************
数码管显示程序
*********************************/
void display()
{
static uchar aa=0; //时分显示变量
static uchar bb=0; //计数延时变量
bb++;
if(bb>=40) // //1~255可调,数码管闪烁可减小,有鬼影可加大
{
bb=0;
switch (aa)
{
case 0: P0=0X00; shuA=0; shuB=0;shuC=0;
P0=table[hour/100%10];
aa=1;
break;
case 1: P0=0X00; shuA=1; shuB=0;shuC=0;
P0=table[hour/10];
aa=2;
break;
case 2: P0=0X00; shuA=0; shuB=1;shuC=0;
P0=table[hour%10];
aa=3;
break;
case 3: P0=0X00; shuA=1; shuB=1;shuC=0;
P0=table[min/100%10];
aa=4;
break;
case 4: P0=0X00; shuA=0; shuB=0;shuC=1;
P0=table[min/10];
aa=5;
break;
case 5: P0=0X00; shuA=1; shuB=0;shuC=1;
P0=table[min%10];
aa=6;
break;
case 6: P0=0X00; shuA=0; shuB=1;shuC=1;
P0=table[sec/10];
aa=7;
break;
case 7: P0=0X00; shuA=1; shuB=1;shuC=1;
P0=table[sec%10];
aa=0;
break;
}
}
}
void main(void)
{
// timer0Init(); //初始化定时器0 //
while(1) //大循环//
{
keyboard_matrix(); //按键扫描//
// time (); //计时//
display (); //显示//
}
}
P2=temp_circle;//0xFX
//加延时
temp=P2;//读取P2口线数据
if(temp!=temp_circle)//有按键动作
{
P2=temp_circle;//0xFX
//加延时
temp=P2;//读取P2口线数据
if(temp!=temp_circle)//有按键动作
{
没有解决我的问题,只是评论了下
根据你的实际电路重新定义矩阵键盘、段码、位码端口
#include <AT89X52.H>
#define uint unsigned int //宏定义无符号整型数据
#define uchar unsigned char //宏定义无符号字符型数据
sbit shuA=P1^0;
sbit shuB=P1^1;
sbit shuC=P1^2;
uchar code table[]={ //共阴数码管0~F
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar key=0; //定义键值全局变量
void keyscan() //按键扫描程序
{
static bit sign=0; //按键有效标志
static uint count=0; //消抖计数变量
uchar num=0; //临时变量
P2=0xf0; //赋值P2 1111 0000
if((P2!=0xf0)&&(sign==0)) //检测按键按下并有效
{
count++; //消抖计数
if(count>=500) //100~1000,根据主循环周期调整约10~20ms
{
sign=1; //按键有效标志置1
num=P2; //保存P2值xxxx 0000,x为0或1
num|=0x0f; //保存num按位或0x0f值xxxx 1111
P2=num; //赋值P2 xxxx 1111
num=P2; //保存P2值xxxx xxxx
switch(num)
{
case 0xee: key= 1; break;
case 0xde: key= 2; break;
case 0xbe: key= 3; break;
case 0x7e: key= 4; break;
case 0xed: key= 5; break;
case 0xdd: key= 6; break;
case 0xbd: key= 7; break;
case 0x7d: key= 8; break;
case 0xeb: key= 9; break;
case 0xdb: key=10; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
}
}
}
else //键抬起
{
sign=0; //按键有效标志清0
count=0; //消抖计数清0
}
}
void display()
{
static uchar aa=0; //时分显示变量
static uchar bb=0; //计数延时变量
bb++;
if(bb>=40) //1~255可调,数码管闪烁可减小,有鬼影可加大
{
bb=0;
switch(aa)
{
case 0: P0=0X00; shuA=0; shuB=0;shuC=0;
P0=table[key%10];
aa=1;
break;
case 1: P0=0X00; shuA=1; shuB=0;shuC=0;
P0=table[key/10];
aa=0;
break;
}
}
}
void main() //主函数
{
while(1)
{
keyscan(); //按键扫描程序
display(); //两位数码管显示程序
}
}