行列线的交叉位置布置按键。所有行和列加上拉电阻。
所有行作输出先送低电平,然后读入列值。 如果有任意键按下,那么一定对应列值有0出现,也就知道了按下的键所在列。
反过来驱备昌动这一列为0,其他列为1。把行作输入。就可以判断按下的键所在行顷缓。
2、掌握8255的接口。如何配置输入和输出。如何访问他们。
根据以上两点,和注释,你就能读懂程序的意图了。
C51 P1端口 4X4键盘说明这是一个用C51单片机P1端口制作的4X4键盘,p1端口低4位是键盘列扫描线,高4位是键盘行扫描线,
列扫描线是输出,行扫描线是输入。
下面就程序作一个说明
(***)表示注意点
1、首先判断整个键盘有无按下键,只要行扫描线输入不为全1,(1111)即有键按下;
P1 = 0xf0if((P1&0xf0)!=0xf0) 如果无按键按下,全1,则返回return -1
如果有键按下则延时,再次判断有无按键按下,Delay()if((P1&0xf0)!=0xf0)如果无按键按下则返回return -1。
有键按下则继续,这个过程就是判键消抖,避免多次读键值,***或者因为按键抖动到读键值的时候无键按下,发生错误,***列扫描线是厅型源输出全0,P1 = 0xf0。租则
2、进入读键值了,与上面不同,每一次判断,***列扫描线只有一根输出为0,即P1=0xfe,0xfd,0xfb,0xf7
首先列扫描线P1.0,sCode = 0xfe如果行扫描线全1,则本列无键按下,扫描下一列
sCode = _crol_(sCode,1)***sCode左移一位,即0xfd,如此扫描4次,行扫描线都全0,则无键按下,
返回return -1
如果行扫描线不全0,就是有键按下,现在可以读键值了
kCode = ~P1//P1=EE,ED...
for(i=0i<16i++)
{
if(kCode == KeyCodeTable[i])
return i
}
1.首先kCode = ~P1***p1值取反行扫描线可能的是1,2,4,8;同样列扫描线对应值1,2,4,8
合起p1有16个值,就是KeyCodeTable[i]表的x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,
0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88
如果 if(kCode == KeyCodeTable[i]) 成立,对应的 i 值就是键号。
2.返回i值就是键号,return i。
uchar Keys_Scan()
{
uchar sCode,kCode,i,k
P1 = 0xf0
if((P1&0xf0)!=0xf0) //扫描列
{
Delay()
if((P1&0xf0)!=0xf0)//消抖
{
sCode = 0xfe
for(k=0k<4k++)
{
P1 = sCode//查找低位
if((P1&0xf0)!=0xf0)//只有等于才执行else P1和0xf0作与为0xf0 与 同真为真,一扮态假为假
{
kCode = ~P1//P1=EE,ED...
for(i=0i<16i++)
{
if(kCode == KeyCodeTable[i])
return i
}
}
else
sCode = _crol_(sCode,1)
}
}
}
return -1
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)