2.因为是按键(不是开关),所以实际上单片机读取的应该是脉冲形式的输入。设按键接单片机P01引脚,故可采用以下程序实现按键扫描
if(P01==0)//按下按键,进入下降沿
{
delay2()//20ms延时去按键前抖动
while(P01==0)//等待上升沿到
来,即按键d起
flag=~flag//flag取反,实现状态切换
}
void
delay2()//20ms延时子程序
{
unsigned
char
i,k
for(i=0i<100i++)
for(k=0k<100k++)
}
注:根据按键的具体接法,若按下按键向单片机输入低电平,则采用以上程序;若按下按键向单片机输入高电平,则将两处P01==0均改为P01==1。
这是4*4键盘扫描程序代码:void delay(uchar a)
{
uchar i,j
for(i=0i<ai++)
for(j=0j<125j++)
}
uchar kbscan(void)
{
unsigned char sccode,recode
P3=0x0f //发0扫描,列线输入
if ((P3 &0x0f) != 0x0f) //有键按下
{
delay(20) //延时去抖动
if ((P3&0x0f)!= 0x0f)
{
sccode = 0xef //逐行扫描初值
while((sccode&0x01)!=0)
{
P3=sccode
if((P3&0x0f)!=0x0f)
{
recode=(P3&0x0f)|0xf0
while((P3&0x0f)!=0x0f)//等待键抬起
return((~sccode)+(~recode))
}
else
sccode=(sccode<<1)|0x01
}
}
}
return 0 //无键按下,返回0
}
void getkey(void)
{
unsigned char key
key=kbscan()
if(key==0)
{
return
}
switch(key)
{
case 0x11:keyval=7break
case 0x12:keyval=4break
case 0x14:keyval=1break
case 0x18:keyval=10break
case 0x21:keyval=8break
case 0x22:keyval=5break
case 0x24:keyval=2break
case 0x28:keyval=0break
case 0x41:keyval=9break
case 0x42:keyval=6break
case 0x44:keyval=3break
case 0x48:keyval=11break
case 0x81:keyval=12break
case 0x82:keyval=13break
case 0x84:keyval=14break
case 0x88:keyval=15break
default:keyval=0xffbreak
}
}
ORG 00HLJMP MAIN
ORG 30H
MAIN: LCALL LOOP1
LCALL DELAY
LCALL LOOP1
LCALL LOOP2
LCALL LOOP3
LJMP MAIN
LOOP1: MOV P2,#0F0H判断有键按下?
MOV A,P2
MOV B,A
MOV P2,#0FH
MOV A,P2
ORL A,B
MOV 30H,A
CJNE A,#0FFH,LOOP11
LJMP MAIN
LOOP11: RET
LOOP2:MOV R3,#00H比较计算得出键值
LOOP21:MOV A,R3
INC R3
MOV DPTR,#TAB
MOVC A,@A+DPTR
CJNE A,30H,LOOP21
RET
LOOP3:MOV A,R3 数码管显示
MOV DPTR,#TAB1
MOVC A,@A+DPTR
MOV P1,A
MOV P1,#0F1H
RET
DELAY: 延时R5×10MS
MOV R6,#50
DELAY1:MOV R7,#100
DJNZ R7,$
DJNZ R6,DELAY1
RET
TAB:
DB 0EEH,0EDH,0EBH,0E7H
DB 0DEH,0DDH,0DBH,0D7H
DB 0BEH,0BDH,0BBH,0B7H
DB 07EH,07DH,07BH,077H
TAB1: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH
END
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)