本帖最后由 忘川轮回 于 2013-2-10 23:35 编辑
/*********************************************************
功能描述:T0定时器中断法,矩阵键盘扫描。
返回值:key键值为1-16,出错码为0。
**********************************************************/
#include
/*
头文件*/
#include "num.h"
#include "key.h"
void main()
{
TMOD=0x01; /*T0工作方式1*/
TH0=0xfc; /*T0装载初值,定时1ms*/
TL0=0x18;
EA=1; /*开中断*/
ET0=1;
TR0=1; /*启动T0*/
while (1)
{
Keyscan();
Display(key,numwei);
}
}
voidtime0 () interrupt 1 /*T0中断服务程序*/
{
TH0=0xfc; /*T0装初值定时1ms*/
TL0=0x18;
numms++; /*数码管延时标记,单位ms*/
if (keyflag!=KEYFLAG1) keyms++; /*按键延时标记,单位ms*/
}
/**************************************
功能描述:TO定时器延时,矩阵键盘扫描(线反转法)
函数名:Keyscan()
入口参数:无
返回值:key键码为1-16,key错误码为0
包含函数:无
**************************************/
#define KEYXMS 12 /*KEYXMS =延迟消抖多少毫秒*/
#define KEYFLAG1 1 /*按键无动作状态*/
#define KEYFLAG0 0 /*按键按下状态*/
#define KEYFLAG2 2 /*按键释放检测*/
#define KEYPORT P3 /*矩阵键盘端口定义*/
unsigned char keyms=0,keyflag=1; /*Keyms按键持续ms数*/
unsigned char key; /*key键码*/
void Keyscan() /*矩阵键盘扫描函数开始*/
{
unsigned char x,y,temp; /*x行坐标;y列坐标;*/
KEYPORT = 0x0f; /*矩阵键盘高位置零*/
x = KEYPORT&0x0f; /*取行坐标*/
KEYPORT = 0xf0; /*线反转,写P3口*/
y = KEYPORT&0xf0; /*取列坐标*/
temp = x|y; /*进行或逻辑运算,取得按键值*/
switch (keyflag) /*当前按键标志*/
{
case KEYFLAG0: /*状态0:按键按下*/
if (keyms>=KEYXMS) /*延时判断*/
{
if (temp!=0xff) /*判断有无按键按下*/
{
switch (temp) /*有:提取按键键值*/
{
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;
default: key=0; break; /*出错码*/
}
keyflag = KEYFLAG2; /*提取键值后,转入状态2,按键释放检测*/
keyms = 0; /*延时清零*/
}
else /*无:这是一次干扰*/
{
keyflag = KEYFLAG1; /*进入默认的状态1:按键无动作*/
keyms = 0; /*延时清零*/
}
}
break;
case KEYFLAG1: /*状态1:按键无动作(默认)*/
if (temp!=0xff) /*判断有无按键按下*/
{
keyflag = KEYFLAG0; /*有:进入状态0,按键按下状态*/
keyms = 0; /*延时清零*/
}
break;
case KEYFLAG2: /*状态2:按键释放检测*/
if (keyms>=KEYXMS) /*延时判断*/
{
keyms = 0; /*延时清零*/
if ((key!=0)&(temp==0xff)) /*按键码无错误与按键已经释放同时为真?*/
{
keyflag = KEYFLAG1; /*按键已经释放,进入状态1,继续等待下次按键触发*/
keyms = 0; /*延时清零*/
/*添加用户程序段*/
/*添加用户程序段*/
}
}
break;
}
}
/*********************************************************
文件名称:num.h主控芯片:STC89C52RC
功能描述:定时器延时,6位(0-5)数码管动态显示
函数名称:Display(unsigned char date,unsigned char wei)
输入参数:date显示数据,wei数码管位选
返回值:无
备注:中断函数中添加:numms++; //数码管延时标记,单位ms
作者日期:田卫卫/2013年2月9日
版本:V1.1
*********************************************************/
#define NUMDELAY 3 /*NUMMS =刷新每位数码管的时间*/
#define NUMPORT P0 /*数码管连接的IO端口*/
unsigned char code NUM_TAB[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; /*共阴极数码管0-f*/
unsigned char code NUM_WEI[]={0x7e,0x7d,0x7b,0x77,0x6f,0x5f}; /*数码管位码从左至右6位(0-5);U2 Q7=0接AD片选信号*/
unsigned char numms; /*数码管延时标记,单位ms*/
unsigned char numwei; /*6位数码管*/
void Display(unsigned char date,unsigned char wei) /*date显示数据,wei数码管位选*/
{
if (numms>=NUMDELAY)
{
numms = 0;
dula = 1;
NUMPORT = NUM_TAB[date]; /*送显示数据*/
dula = 0;
NUMPORT = 0xff;
wela = 1;
NUMPORT = NUM_WEI[wei]; /*送数码管位码*/
wela = 0;
numwei++; /*数码管位选递增*/
if (numwei==6) numwei = 0; /*判断6位(0-5)显示完毕?*/
}
}
1