郭天祥键盘部分的代码真是冗长,难道是为了易懂,但也不是越长越好懂啊,看看我写的。
扫描法
#include <reg52.h> #include <intrins.h> sbit we=P2^7; sbit du=P2^6; unsigned char code table[] = { 0x3f , 0x06 , 0x5b , 0x4f, 0x66 , 0x6d , 0x7d , 0x07, 0x7f , 0x6f , 0x77 , 0x7c, 0x39 , 0x5e , 0x79 , 0x71, 0x00}; void ini_t0(); void show(); void delayms(unsigned time); void keyscan(); void matrixscan(); unsigned char num[6]={0,0,16,0,0,16}; unsigned char count=0; unsigned char nums=0; void main() { ini_t0(); while(1) { keyscan(); num[1]=nums/10; num[0]=nums%10; matrixscan(); show(); } } void matrixscan() { unsigned char i,j; unsigned char temp; for(i=0;i<4;i++) { P3=~(1<<i); //第i+1行给低电平 if((P3|0x0f)!=0xff) //判断此时是否有列为低电平 { //有则得到行列位置i+1,j+1 delayms(10); if((temp=P3|0x0f)!=0xff) { while((P3|0x0f)!=0xff); for(j=0;j<4 && ( temp& 0x10<<j );j++) ; num[4]=i+1; num[3]=j+1; break; } } } P3=0xff; //还原电平 } void keyscan() { unsigned char temp; if((P3|0x0f)!=0xff) { delayms(10); if((temp=P3|0x0f)!=0xff) { while((P3|0x0f)!=0xff); switch(temp) { case 0xef: if(++nums==60) nums=0; break; case 0xdf: if(nums--==0) nums=59; break; case 0xbf: nums=0; break; case 0x7f: TR0=~TR0; break; } } } } void t0_time() interrupt 1 { TH0=(65536-45872)/256; TL0=(65536-45872)%256; count++; if(count==20) { count=0; if(++nums==60) nums=0; } } void ini_t0() { EA=1; ET0=1; TMOD=0x01; TH0=(65536-45872)/256; TL0=(65536-45872)%256; } void show() { unsigned char i; for(i=0;i<6;i++) { P0=0xff; we=1; we=0; P0=table[num[i]]; du=1; du=0; P0=~(0x20>>i); we=1; we=0; delayms(1); } } void delayms(unsigned time) { unsigned i,j; for(i=time;i>0;i--) for(j=110;j>0;j--) ; }
行列反转法,更简单的方法。可以再外加一个 “if和延时” 来去抖动
1 void matrixscan() 2 { 3 unsigned char temp,i; 4 5 P3=0x0f; 6 if(P3!=0x0f) 7 { 8 temp=P3; 9 P3=0xf0; 10 temp|=P3; 11 while(P3!=0xf0) 12 ; 13 for(i=0;i<4 && (temp& 0x01<<i);i++) 14 ; 15 num[1]=i+1; 16 for(i=0;i<4 && (temp& 0x10<<i);i++) 17 ; 18 num[0]=i+1; 19 } 20 }