CODE如下:
DATA SEGMENT
TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,7FH,6FH 预置显示值
BUFFER DB ? 预留一个字节装键值
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA 初始化 *** 作
MOV DS,AX
SET: MOV DX,206H初始化8255
MOV AL,89H
OUT DX,AL
WAIT-IN: MOV AL,00H检测按键所有行输出0
MOV DX,2048255的 C口地址
OUT DX,AL
IN AL,DX读列线
AND AL,70H
CMP AL,70H比较是否有按键按下
JZ WAIT-IN无就等待
DONE: CALL DAELAY延时消除抖动
MOV BL,0键号初始值为0
MOV CL,0FEH扫描初始值
MOV DL,3计数值行数
SCANR: MOV AL,CL扫描一行
MOV DX,204HC口地址
OUT DX,AL
ROL AL,1修改行数
MOV CL,AL
IN AL,DX读列数
AND AL,70H
CMP AL,70H 判断列线状态
JNZ SCANL有低转
ADD BL,3没有使键号=键号值+列数
DEC DL
JNZ SCANR行未完转
JMP HANDLE扫描结束
SCANL: OR AL,0FH高位置1,避免出错
RCR AL,1
JNC HANDLE列为低,确定按键值
INC BL
JMP SCANL查找下一列
HANDLE MOV AL,BL传按键
MOV BX,OFFSET TABLE段码表首址
XLAT
MOV DX,200H A口地址
OUT DX,AL送段码
CALL DELAY
MOV AH,04H
INT 21H
CODE ENDS
END STATRT
/*按键扫描函数*/void keyScan(void)
{
//P3=0x00
col1=0col2=1col3=1col4=1
temp=P2&0x3f
if(col1==0) //假设第一列有按键
{
if(temp!=0x3f) //没有按键退出这次对第一列键盘扫描
{
temp=P2&0x3C // 3CH=00111100,目的是先把P2.2、P2.3、P2.4、P2.5 这中间四位先置1,即预读先置1,做好输入的准备
switch(temp)
{
case 0x38: key=12 break
// 38H=00111000,只看中间四位,其中只有P2.2=0,代表第4行第1列为低电平,所在键值恰好是12(即C)
case 0x34:key=8break
// 34H=00110100,只看中间四位,其中只有P2.3=0,代表第3行第1列为低电平,所在键值恰好是8
case 0x2C:key=4break
// 2CH=00101100,只看中间四位,其中只有P2.4=0,代表第2行第1列为低电平,所在键值恰好是4
case 0x1C:key=0break
// 1CH=00011100,只看中间四位,其中只有P2.5=0,代表第0行第1列为低电平,所在键值恰好是0
}
}
}
col1=1col2=0col3=1col4=1
temp=P2
temp=temp&0x3f
if(col2==0)
{
if(temp!=0x3f)
{
temp=P2&0x3C
switch(temp)
{
case 0x38: key=13break//’0’键被按下时导通,则对应端口变为低电平
case 0x34:key=9break
case 0x2C:key=5break
case 0x1C:key=1break
}
}
}
col1=1col2=1col3=0col4=1
temp=P2
temp=temp&0x3f
if(temp!=0x3f)
{
temp=P2&0x3C
switch(temp)
{
case 0x38: key=14break//’0’键被按下时导通,则对应端口变为低电平
case 0x34:key=10break
case 0x2C:key=6break
case 0x1C:key=2break
}
}
col1=1col2=1col3=1col4=0
temp=P2
temp=temp&0x3f
if(temp!=0x3f)
{
temp=P2&0x3C
switch(temp)
{
case 0x38: key=15break//’0’键被按下时导通,则对应端口变为低电平
case 0x34:key=11break
case 0x2C:key=7break
case 0x1C:key=3break
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)