#include<STC12C5A60S2.h>
char code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x00,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e}
void delayms(int xms)
{
int i,j
for(i=xmsi>0i--)//i=xms即延时约xms毫秒
for(j=110j>0j--)
}
void display(char num)
{
P1=table[num]//段选数据灶弯睁
}
void matrixkeyscan()
{
char temp,key
P3=0xfe
temp=P3
temp=temp&0xf0
{
delayms(10)//延时,去抖动
temp=P3
temp=temp&0xf0
if(temp!=0xf0)//说明按键被持续按下
{
temp=P3//记录P3口状态
switch(temp)//根据现在的状态判断哪个按键闹晌被按下
{
case 0xee: //p3^4被按下
key=0
break
case 0xde: //p3^5
key=1
break
case 0xbe://p3^6
key=2
break
case 0x7e://p3^7
key=3
break
}
while(temp!=0xf0)//按键松开之后跳出循环
{
temp=P3
temp=temp&0xf0
}
display(key)//显示
}
}
P3=0xfd
{......}
P3=0xfb:
{......}
P3=0xf7
{......}
void main()
{
P0M1 = 0x00//推挽输出的定义
P0M0 = 0x0f//推挽输出的定义
P0=0x0f
while(1)
{
matrixkeyscan()//不停调用键盘扫描程序
}
}
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
}
ucharkeyscan(void)//键盘扫描函数,使用行列反转扫描法
比如:行为低电位,列为高四位
{
uchar
cord_h,cord_l//行列值
P3=0x0f
//行线输出全为0
cord_h=P3&0x0f
//读入列线值
if(cord_h!=0x0f)
//这个句话意思是这样的,如果有启余按键按下的话。那肯定就不是0x0f了。
{
主要就是识别按键按下作用
delay(100)
//去抖
if(cord_h!=0x0f)
//这是双重判定作用而已
{
cord_h=P3&0x0f
//读入列线值
P3=cord_h|0xf0
//输出当前列线值
cord_l=P3&0xf0
//读入液碧行线值
return(cord_h+cord_l)//键盘最后组合码值
}
}return(0xff)
//返回该值
}
好像你的程序解释得很好了。但是好像这么快,最好要延时下才准的。
我教闹旁举你按键的原理吧
就是那根线如果是高电平的话,遇到底电平就会变为底电平的。所以如果有按键按下的话,高电平就会变为低电平了。所以就可以读取了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)