先检测独立的,然后检测矩阵的,挺简单的还是。 |
lgz1860 发表于 2020-3-27 09:58 解决问题了,十分感谢这个兄弟,确实是好多年前的问题了,但是在网上也没找到解决办法。 |
思路:利用中断 扫描矩阵键盘,矩阵键盘每次扫描完,又把P2 口赋高电平,主程序检测独立键盘,两者互不干扰。 利用我的程序需要将 P0 口接 六位共阴极液晶显示, P1口接流水灯。 不知道发图片,可以肯定的是能够实现,我的程序100% 仿真成功。 |
#include <reg52.h> #define uint unsigned int #define uchar unsigned char sbit dula= P3^6;//段选,液晶的每一个引脚 sbit wela= P3^7;//位选,液晶的公共端 sbit s1=P2^4; sbit s2=P2^5; sbit s3=P2^6; sbit s4=P2^7; sbit d1=P1^0; sbit d2=P1^1; sbit d3=P1^2; sbit d4=P1^3; uint temp,z; uchar num=0; void delay(z); void duli (); void display(num); scanjuzheng (); uchar code led[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71, 0x00}; void init() { TMOD=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; P0=0xfe; wela=1; wela=0; P2=0xff; num=16; P0=0x00; dula=1; dula=0; } //主程序 void main () { init(); while(1) { duli(); } } //独立按键子程序 void duli () { if(s1==0) { delay(5); if(s1==0) { d1=0; } while(s1==0); delay(5); while(s1==0); } else { d1=1; } if(s2==0) { delay(5); if(s2==0) { d2=0; } while(s2==0); delay(5); while(s2==0); } else { d2=1; } if(s3==0) { delay(5); if(s3==0) { d3=0; } while(s3==0); delay(5); while(s3==0); } else { d3=1; } if(s4==0) { delay(5); if(s4==0) { d4=0; } while(s4==0); delay(5); while(s4==0); } else { d4=1; } } //延时子程序 void delay(z)// 延时1ms定时器 { uint a,b; for(a=z;a>0;a--) for(b=123;b>0;b--); } void display(num) { P0=led[num]; dula=1; dula=0; delay(5); } //矩阵键盘子程序 scanjuzheng () { //0123 扫描 if(P2==0xff) { temp=0xfe; P2=temp; if((P2&temp)!=0xfe) { delay(5); if((P2&temp)!=0xfe) { switch(P2&temp) { case 0xee: (num=0); break; case 0xde: (num=1); break; case 0xbe: (num=2); break; case 0x7e: (num=3); break; } } } //4567 扫描 temp=0xfd; P2=temp; if((P2&temp)!=0xfd) { delay(5); if((P2&temp)!=0xfd) { switch(P2&temp) { case 0xed: (num=4); break; case 0xdd: (num=5); break; case 0xbd: (num=6); break; case 0x7d: (num=7); break; } } } //89AB 扫描 temp=0xfb; P2=temp; if((P2&temp)!=0xfb) { delay(5); if((P2&temp)!=0xfb) { switch(P2&temp) { case 0xeb: (num=8); break; case 0xdb: (num=9); break; case 0xbb: (num=10); break; case 0x7b: (num=11); break; } } } //CDEF 扫描 temp=0xf7; P2=temp; if((P2&temp)!=0xf7) { delay(5); if((P2&temp)!=0xf7) { switch(P2&temp) { case 0xe7: (num=12); break; case 0xd7: (num=13); break; case 0xb7: (num=14); break; case 0x77: (num=15); break; } } } temp=0xff; P2=temp; return num; } } void timer0() interrupt 1 //中断程序 t0 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; if(P2==0xff) //用于判断独立键盘 没有按下 { display(scanjuzheng()); } } |
虽然这是多年前的问题了,但我百度确未解决问题,苦恼一晚上,借鉴了他人的思路。利用中断解决了这个问题。 |
应该很容易。因为它们的检测原理是不一样的。独立按键,是直接与低电平连接,按下键后,I/O口电平被拉低。 矩阵键盘,是通过分别对I/O口赋值,进行扫描,得到是哪个按键被按下。 所以,不用担心它们会干扰,不然也不会那样设计电路了。 当然,如果你同时按下了独立按键和矩阵键盘的键,是会有问题的,你会同时按下吗? |