我们用电开的开发板模仿金沙滩的矩阵按键的检测的程序,不能很好的实现,但不得不说金沙滩的方法还是很好的,非常的严谨,非常值得学习,但奈何咱的开发板有些高级,还有自己水平的不足,有些跟不上
然后我就找其他的教程,在网上搜到了一些自己能懂的方法和根具自己开发板的结构,编写了程序。其原理是先检验列,然后检验行,当行与列都决定了,显示数值
但有个问题,按键按下去的时候也能显示但有时显示的数不对,再按一下,数又对了,而且那个不对的数一直是同一个数。这....
经过我多次的尝试与观察,发现出错的数的值就是对应列的值,也就是说,它只检验了列,没有检验行。程序如果是顺利的从上走到下,是不会漏下对行的检测的。如果多按那么一两次的话,数值又显示对了。是方法问题还是我们的板子独特的设置问题?
#include <STC12C5A60S2.H>
sbit ENLED = P1^1;
sbit ADDR0 = P2^0;
sbit ADDR1 = P2^1;
sbit ADDR2 = P2^2;
unsigned char LedCount;//数码管显示值
unsigned char a = 0;
unsigned char code LedChar[]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};//用数组来储存数码管的真值表,
void delay();
void main()
{
ENLED = 0;
P0 = LedChar[0];//初始显示0
while(1)
{
ENLED = 1;//检测按键前关闭74HC245,防止LED和其他数码管的影响
P2 = 0x0F; //进行列检测
if(P2!=0x0F)//判断按键是否按下
{
delay(); //按下消抖
if(P2!=0x0F) //确实已经按下
{
P2 = 0x0F; //重新赋值,以便检测
switch(P2)
{
case 0x0EedCount = 0;break;//第一列
case 0x0DedCount = 1;break;//第二列
case 0x0BedCount = 2;break;//第三列
case 0x07edCount = 3;break;//第四列
default:break;
}
P2 = 0xF0; //对行检测
switch(P2)
{
case 0xE0edCount = LedCount;break; //如果是第一行四个某个按下,则值就等于上面的返回值
case 0xD0edCount = LedCount+4;break; //如果是第二行四个某个按下,则值就是上面对应的返回值加四,因为是第二行嘛
case 0xB0edCount = LedCount+8;break;
case 0x70edCount = LedCount+12;break;
default:break;
}
while((a<40)&&(P2!=0xF0)) //弹起消抖,用与运算,判断按键是否弹起,弹起就跳出循环,a<40,是时间判定,值可自己设
{
delay();
a++;
}
}
}
ADDR0 = 1;
ADDR1 = 0;
ADDR2 = 1;
ENLED= 0; //按键检测完使能74HC245,并让最右面的数码管显示
P0 = LedChar[LedCount];
}
}
void delay() //软件延时函数,大约延时10毫秒
{
unsigned int i = 1000;
while(i--);
}
|