/*矩阵键盘扫描程序:线反转法(经典矩阵键盘检测程序) 动态扫描显示数码管、线反转法检测4×4矩阵键盘 P1口流水灯实时显示P3口电平(熄灭表示高电平、点亮表示低电平) 用程序状态寄存器PSW中的PSW^5,作为全局标志位 // Header:P3口低4位接矩阵键盘行、高4位接矩阵键盘列 // File Name:经典矩阵键盘检测程序(线反转法) // Author:田卫卫 // Date:2012年12月7日 */ #include//STC89C52RC 头文件 #include//_crol_函数的头文件 #define uint unsigned int//宏定义 #define uchar unsigned char//宏定义 uchar num;//定义全局变量 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阳极数码管字符表 void delay(uint xms) //延时函数 { uint i,j; for(i=0;i for(j=0;j<110;j++); } void display(num) //显示函数 { uchar numwe,xwei; xwei=6;//用几位数码管显示? numwe=0xfe;//初始化数码管位选控制 for(;xwei!=0;xwei--) { dula=1; //开段选锁存器 P0=table[num];//送显示数 dula=0; //关段选锁存器 P0=0xff;//消影 wela=1; //开位选锁存器 P0=numwe;//送数码管位选控制 wela=0; //关位选锁存器 numwe=_crol_(numwe,1); //对数码管位选控制 左移位 delay(1);//调用延时函数 } } void keyscan()//矩阵键盘扫描函数 开始 { uchar x,y,key,temp;//定义:行坐标x、列坐标y、按键key temp=0x0f;// 0000 1111 P3=temp;//P3口:4列送0000、4行送1111; if (P3!=temp)//1判断是否有按键按下; { delay(10);//延时10毫秒消抖动; P3=temp;//P3口:列送0000、行送1111; if (P3!=temp)//2次判断是否有按键按下; { x=P3&temp;//取按下矩阵键盘的行坐标 temp=~temp;//按位取反,线反转使用; P3=temp;//线反转P3口:4列送高电平、4行送低电平; y=P3&temp;//取按下矩阵键盘的列坐标 key=x|y;//行坐标x、列坐标y 进行或运算组合在一起。 while(P3!=temp);//按键释放检测语句 P1=key;//用流水灯显示当前的P3口状态 switch (key) //进入开关多分支语句判断 { case 0xee: num=0; F0=1; break; case 0xde: num=1; F0=1; break; case 0xbe: num=2; F0=1; break; case 0x7e: num=3; F0=1; break; case 0xed: num=4; F0=1; break; case 0xdd: num=5; F0=1; break; case 0xbd: num=6; F0=1; break; case 0x7d: num=7; F0=1; break; case 0xeb: num=8; F0=1; break; case 0xdb: num=9; F0=1; break; case 0xbb: num=10; F0=1; break; case 0x7b: num=11; F0=1; break; case 0xe7: num=12; F0=1; break; case 0xd7: num=13; F0=1; break; case 0xb7: num=14; F0=1; break; case 0x77: num=15; F0=1; break; default://出错处理! F0=0;//程序状态字 置0 break; } } } }//矩阵键盘扫描函数 结束 void init()//初始化函数 { F0=0;//程序状态字:上电数码管不显示、以及出错处理 num=0; } void main() //主函数 开始 { init(); //调用 初始化函数 while(1)//大循环 开始 { keyscan();//调用按键扫描函数 if (F0==1)//判断是否正确按下了矩阵按键 { display(num);//调用 显示函数 } else//错误按键处理(关闭数码管显示、关闭流水灯) { dula=1; //开U1锁存器 P0=0xff;//送关闭数据 dula=0; //关U1锁存器 wela=1; //开U2锁存器 P0=0xff; //送关闭数据 wela=0; //关U2锁存器 P1=0xff;//熄灭流水灯 } }//大循环 结束 }//主函数 结束
|