本帖最后由 忘川轮回 于 2013-2-10 23:35 编辑
times New Roman">/*********************************************************功能描述:T0定时器中断法,矩阵键盘扫描。返回值:key键值为1-16,出错码为0。**********************************************************/#include<reg52.h> /*头文件*/#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); }} void Time0 () 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)显示完毕?*/ }}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>