在线仿真器:仿真芯片SST89E516
动态检测:
#include <reg52.h> #include <intrins.h> #define uint8 unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; sbit led7=P0^7; void showKey(uint8 num); //静态显示 void keyScan(); void delayms(uint8); uchar code table[]= //数码管显示0-F的编码 { 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0 }; void main() { showKey(18); //初始显示的是6个负号 while (1) { //循环检测 keyScan(); } } void showKey(uint8 num) { P0=0xc0; //11000000 打开6个数码管 wela=0; wela=1; P0=table[num]; dula=1; dula=0; } void keyScan() { uint8 num=0; //定义显示的数字 uint8 temp=0; //P3口回读信息 uint8 i=0; //定义矩阵键盘行号索引 for (i=0; i<4;i++) //共4行 { P3=_crol_(0xfe,i); //扫描的行索引号,从第0行到第3行 temp=P3; //读取P3口 ////////////////////////////////////////////////////////////////////////// //这个地方我想了很久,开始时明明已经给P3赋值为_crol_(0xfe,i),那么接下来 //temp应该也和P3的值相同呢,其实不是~~~~~~~~~~~~~~~~~~~ //P3被赋值后,由于键已经被按下,所以P3会迅速恢复按下的状态值,于是与开始赋值 //就不一样了,此时的P3是当前值 //////////////////////////////////////////////////////////////////////////// temp=temp&0xf0; //提取高4位 if (temp!=0xf0) //按键了 { delayms(5); //消抖 temp=P3; temp=temp&0xf0; if (temp!=0xf0) //真的按键了 { switch (temp) { case 0xe0: //1110 0000 { num=0+4*i; break; } case 0xd0: //1101 0000 { num=1+4*i; break; } case 0xb0: //1011 0000 { num=2+4*i; break; } case 0x70: //0111 0000 { num=3+4*i; break; } default: { num=18; //18号索引是负号 led7=0; // 按了不该按的指示灯 break; } } while (1) //松开按键检测 { temp=P3; //读取P3口 temp=temp&0xf0; //提取高4位 if (temp==0xf0) //松开按键了 { delayms(5); temp=P3; temp=temp&0xf0; if (temp==0xf0) //真的松开键盘了 { break; } } } showKey(num); //静态显示按键 } } } } void delayms(uint8 x) { uint8 i,j; for (j=x;j>0;j--) for (i=110;i>0;i--) ; }