您的位置 首页 国产IC

按键的C51源程序

8条口线24按键的C51源程序键盘扫描处理,无按键返回0,有按键返回键值,键值对应于keycode[]下标值。8条(以P2为例)口线24按键键盘码也可

8条口线24按键C51源程序

//键盘扫描处理,无按键回来0,有按键回来键值,键值对应于keycode[]下标值。8条(以P2为例)口线24按键
//键盘码也可界说为部分数组变量
unsigned char code keycode[]=
{0x00,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb,0xd7,0xe7,0xb7,0x7b,0x7d,0x7e,0x77,

0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0x7f,0xbf};

unsigned char keyread(void)
{ unsigned char i,j,x,k1,k2;
P2=0xff;
if(P2!=0xff)
{k1=P2;
delay();
P2=0xff;
if(P2!=0xff)
{for(P2=0xff;P2!=0xff;P2=0xff)
x=k1;}
}
else{x=0;
}
//以上判别接地按键
//以下判别穿插按键(反转法)
if(x==0)
{P2=0x0f;
if(P2!=0x0f)
{delay();
P2=0x0f;
if(P2!=0x0f)
{k1=P2;
P2=0xf0;
if(P2!=0xf0)
{k2=P2;
for(P2=0xf0;P2!=0xf0;P2=0xf0)
x=k1^k2;}
}
}
else{x=0;} }
if(x==0){i=0;}
else{i=j=0xff;
do{i++;j++;
if(keycode[i]==x){j=24;}
else if(j==24){i=0;}else{;} }

while(j!=24);}

return(i);
}

void delay()//延时
{ unsigned char b;
for (b=0;b<=0xff;b++)
{
for (b=0;b<=0xff;b++)
{;}
}
}

96个key的零延时收集
Juliet宣布谈论于2006-5-10 11:35:00

96个key的零延时收集


HotPower 宣布于 2003-11-5 18:04 侃单片机 ←回来版面

;——-96键演示程序————————-
;这是1个回复题中的使用示例,已经过软仿真“验证”
;这仅仅键扫描技能的1个“缩影”,办法真实太多.
;有“丑陋之处”,敬请高手们批判指导.
;HotPower将虚心接受,坚决改正.重新做人.
;宣布意图: 在21IC中强大游击队.
;—————————————————-
;因为2051资源问题,本程序只取多任务键盘的压放键2个事情
;废弃长压键(压键1段时刻后才激活)事情
;废弃长放键(放键1段时刻后才激活)事情
;废弃双击键事情
;废弃恣意组合键事情
;———-常数界说——————————
TIME208US EQU -208;20mS/96=208uS
TIME50MS EQU -5000;50000uS
;KEYCOUNT EQU 1;键盘键个数(软仿真时用)
;————————————————
KEYCOUNT EQU 96;键盘键个数(实践使用)

;———-RAM地址界说—————————-
;——–96键键状况标志位数组Bits[12*8位]——–
KEYBUFF1 DATA 08H;08H~13H(12个字节96位)对应96键
;——–96键键跳变标志位数组Bits[12*8位]——–
KEYBUFF2 DATA 14H;14H~1FH(12个字节96位)对应96键
;————————————————
KEYNUM DATA 30H;
HotPower_55H DATA 6EH
HotPower_AAH DATA 6FH
;—————————————
SP_MIN DATA HotPower_AAH
;——-主程序开端———————-
ORG 0000H
START:
LJMP MAINSTART;主程序开端
ORG 0003H
;——-掉电维护中止INT0服务程序——–
INT0_INTADDR:
RETI
ORG 000BH
;——-定时器T0中止服务程序————
;作业在8位主动装载方法,每208uS中止一次
T0_INTADDR:
LJMP T0INTPROC;定时器T0中止服务程序
RETI
ORG 0013H
;——-外部中止INT1服务程序————
INT1_INTADDR:
RETI
ORG 001BH
;——-定时器T1中止服务程序————
T1_INTADDR:
LJMP T1INTPROC;定时器T1中止服务程序
RETI
; ORG 0023H
;——-串行中止服务程序—————-
;SINT_INTADDR:
; RETI
;——————————————-
; ORG 002BH
;——-定时器T2中止服务程序————
; LJMP T2INTPROC;履行中止服务程序
; RETI
;——-履行键盘指令———————-
;本程序使用散转收回技能(指针函数)
;它的最大长处是散转处的子程序可被它用(函数)
;它比JMP @A+DPTR指令要“游击”许多,灵敏和荫蔽了许多
;它在抵挡“反汇编”方面,比JMP @A+DPTR更“坏”
;HotPower打死也不必JMP @A+DPTR
KEYPROC:
;进口: DPTR散转地址表
; ACC 散转号
CJNE A,#KEYCOUNT,$+3
JNC KEYPROC_EXIT;不合法键(96~255)避免程序飞,不散转
RL A;*2;地址需求2字节(像ARM的大端形式)
ADD A,DPL
MOV DPL,A
CLR A
ADDC A,DPH
MOV DPH,A
MOV A,#01H;低8位
MOVC A,@A+DPTR;取低8位地址
PUSH ACC;压入事情处理低8位地址
CLR A;高8位
MOVC A,@A+DPTR;取高8位地址
PUSH ACC;压入事情处理高8位地址
KEYPROC_EXIT:
RET;履行键盘指令(散转JMP @A+DPTR)
;——-压键事情处理地址表——————–
KEYJMPPROCTAB:
DW KEYPROC0;0键压键
DW KEYPROC1
DW KEYPROC2
;……………………….
DW KEYPROC95;95键压键
;——-放键事情处理地址表——————–
KEYJMPPROCTABX:
DW KEYPROC0X;0键放键
DW KEYPROC1X
DW KEYPROC2X
;……………………….
DW KEYPROC95X;95键放键
MAINSTART:
;——-P0口初始化——————
MOV P0,#11111111B
;——-P1口初始化——————
MOV P1,#11111111B
;——-P2口初始化——————
MOV P2,#11111111B
;——-P3口初始化——————
MOV P3,#11111111B
;——————————–
MOV IE,#00000000B;EA=0,ES=ET2=ET1=EX1=ET0=EX0=0
MOV SP,#SP_MIN;
MOV PSW,#00000000B;RS1RS0=00,R0~R7=00H~07H
MOV A,#LOW(MAINNEXT)
PUSH ACC
MOV A,#HIGH(MAINNEXT)
PUSH ACC
RETI
MAINPROC:
LCALL MAININIT;体系初始化
MOV IE,#10001010B;开中止
;——-主循环——————————-
MAINLOOP:
ORL PCON,#10001101B;待机
SJMP MAINLOOP;死循环
MAINNEXT:
MOV A,#LOW(MAINPROC)
PUSH ACC
MOV A,#HIGH(MAINPROC)
PUSH ACC
RETI
;——-主程序初始化————————
MAININIT:
;——-接口初始化————————–
;——-内存初始化————————-
MOV A,HotPower_55H
XRL A,HotPower_AAH
CPL A
JZ MAININITNEXT;内存未损坏
MOV HotPower_55H,#055H
MOV HotPower_AAH,#0AAH
LCALL SYSTEMINIT;体系初始化
MAININITNEXT:
;——-运转初始化—————
LCALL SYSTEMSETUP;体系设置
RET
SYSTEMINIT:
LCALL KEYBUFFINIT
RET
SYSTEMSETUP:
;——-体系主频12MHz———————————
; MOV IP,#00100001B;中止优先级EX0>ET2>ET0>EX1>ES
MOV TMOD,#00010010B;T1=MODE1(16位定时器),T0=MODE2(8位定时器)
MOV TCON,#01010101B;发动定时器TR1EQUTR0EQU1,IT1EQUIT0EQU1
;——————————————————
MOV TL0,#TIME208US;设置定时器0时刻常数
MOV TH0,#TIME208US;设置定时器0时刻常数
;——————————————————
; MOV TL1,#LOW(TIMEXMS);设置定时器1时刻常数
; MOV TH1,#HIGH(TIMEXMS)
;——-
KEYBUFFINIT:
MOV KEYNUM,#00H
MOV R0,#KEYBUFF1
KEYBUFFINITLOOP:
MOV @R0,#00H
INC R0
CJNE R0,#KEYBUFF2+12,KEYBUFFINITLOOP
RET
;———————————————
INKEY:
;T0每中止1次,将进行1次键”扫描”
LCALL TESTKEY;键盘测验(不扫但描)
;——-键盘软仿真测验点—————–
;在此 A=0 无键压下,A<>0有键压下
;若调试n个键,需将KEYCOUNT设置为n.(KEYCOUNT=1~96)
;—————————————-
JNZ INKEY1;有键压下
INKEY0:
;——-无键压下————————
LCALL GETKEYBIT;取键状况
JZ INKEY01;键状况未产生变化
LCALL CLRKEYBIT;设置放键标志
LCALL SETKEYBITK;设置跳变标志(避免放键颤动)
RET
INKEY01:
LCALL GETKEYBITK;取键跳变标志
JZ INKEY02;键未产生跳变(避免2次事情处理)
LCALL CLRKEYBITX;设置重入标志
MOV A,KEYNUM;取键号
MOV DPTR,#KEYJMPPROCTABX;键盘放键事情处理表
LCALL KEYPROC;履行键盘放键事情处理
INKEY02:
RET
INKEY1:
;——-有键压下————————
LCALL GETKEYBIT;取键状况
JNZ INKEY11;键状况未产生变化(避免2次事情处理)
LCALL SETKEYBIT;设置压键标志
LCALL SETKEYBITK;设置跳变标志(避免压键颤动)
RET
INKEY11:
LCALL GETKEYBITK;取键跳变标志
JZ INKEY12;键未产生跳变
LCALL CLRKEYBITX;设置重入标志
MOV A,KEYNUM;取键号
MOV DPTR,#KEYJMPPROCTAB;键盘压键事情处理表
LCALL KEYPROC;履行键盘压键事情处理
INKEY12:
RET
GETKEYBITK:
MOV A,R0
ADD A,#12
MOV R0,A
SJMP GETKEYBITX
GETKEYBIT:
LCALL GETKEYBITADDR
LCALL GETKEYBITVAL
GETKEYBITX:
MOV A,@R0
ANL A,B
RET
SETKEYBITK:
MOV A,R0
ADD A,#12
MOV R0,A
SJMP SETKEYBITX
SETKEYBIT:
LCALL GETKEYBITADDR
LCALL GETKEYBITVAL
SETKEYBITX:
MOV A,@R0
ORL A,B
MOV @R0,A
RET
CLRKEYBITK:
MOV A,R0
ADD A,#12
MOV R0,A
SJMP CLRKEYBITX
CLRKEYBIT:
LCALL GETKEYBITADDR
LCALL GETKEYBITVAL
CLRKEYBITX:
MOV A,@R0
XRL B,#0FFH;取反B
ANL A,B
XRL B,#0FFH;复原B
MOV @R0,A
RET
;———————————–
;CPLKEYBITK:
; MOV A,R0
; ADD A,#12
; MOV R0,A
; SJMP CPLKEYBITX
;CPLKEYBIT:
; LCALL GETKEYBITADDR
; LCALL GETKEYBITVAL
;CPLKEYBITX:
; MOV A,@R0
; XRL A,B
; MOV @R0,A
; RET
;———————————————
GETKEYBITVAL:
MOV A,KEYNUM
ANL A,#07H
ADD A,#GETKEYBITTAB-GETKEYBITTABOFF
MOVC A,@A+PC
GETKEYBITTABOFF:
MOV B,A
RET
GETKEYBITTAB:
DB 00000001B
DB 00000010B
DB 00000100B
DB 00001000B
DB 00010000B
DB 00100000B
DB 01000000B
DB 10000000B
RET
;———————————————-
GETKEYBITADDR:
MOV A,KEYNUM
ANL A,#01111000B
RR A
RR A
RR A
ADD A,#KEYBUFF1
MOV R0,A
RET
;——-键测验子程序————————–
TESTKEY:
;键号KEYNUM=000 0000B~101 1111B(0~95)
;进口
;出口 ACC==0 无键压下(键号KEYNUM)
; ACC<>0 有键压下(键号KEYNUM)
MOV A,KEYNUM;取键号
ANL A,#0FH;取行号(键号低4位)
ANL P3,#0F0H;清行信号
ORL P3,A;发送别扫描信号DCBA;P3.3~P3.0
MOV A,KEYNUM;取键号
ANL A,#01110000B;取列号(键号高3位)
SWAP A;变换到低3位
ADD A,#TESTKEYTAB-TESTKEYTABOFF;得到表地址
MOVC A,@A+PC;取列表值
TESTKEYTABOFF:
JZ TESTKEYEXIT;6,7不合法列,以为无键压下
PUSH B;维护现场
MOV B,A;暂存
ANL A,P1;接纳列值P1.7~P1.2,有键压下为0
XRL A,B;有键压下非0
POP B;康复现场
TESTKEYEXIT:
RET
TESTKEYTAB:
DB 00000100B;0列
DB 00001000B;1列
DB 00010000B;2列
DB 00100000B;3列
DB 01000000B;4列
DB 10000000B;5列
DB 00000000B;6列不合法
DB 00000000B;7列不合法
;——-定时器T0中止服务程序——————–
;每个键20mS扫描1次,并主动进行压键或放键消抖处理
;这是1个大规模(96键)的键盘游击战的非典战例
;特色:
;1.不需键扫描.(T0中止的次第即为键扫描号)
;2.不需键消抖.(在T0中止96次后主动消抖)
;3.压键放键事情别离(散转收回技能)
;4.用户事情”并行处理”(mS级分时)
T0INTPROC:
PUSH PSW
PUSH ACC
PUSH B
PUSH DPL
PUSH DPH
T0INTPROC_START:
LCALL INKEY;键扫描并履行压放键事情处理
INC KEYNUM;预备下一键号(T0中止计数)
MOV A,KEYNUM
CJNE A,#KEYCOUNT,T0INTPROC_EXIT
MOV KEYNUM,#00H;开端下1轮键扫描
T0INTPROC_EXIT:
POP DPH
POP DPL
POP B
POP ACC
POP PSW
RETI
;——-定时器T1中止服务程序————
T1INTPROC:
RETI
;——-0键压键事情处理———————
KEYPROC0:
;在此增加用户压键事情
RET
;——-1键压键事情处理———————
KEYPROC1:
;在此增加用户压键事情
RET
;——-2键压键事情处理———————
KEYPROC2:
;在此增加用户压键事情
RET
;——-95键压键事情处理———————
KEYPROC95:
;在此增加用户压键事情
RET
;——-0键放键事情处理———————
KEYPROC0X:
;在此增加用户放键事情
RET
;——-1键放键事情处理———————
KEYPROC1X:
;在此增加用户放键事情
RET
;——-2键放键事情处理———————
KEYPROC2X:
;在此增加用户放键事情
RET
;——-95键放键事情处理———————
KEYPROC95X:
;在此增加用户放键事情
RET
;——-悉数程序完毕————————————–
END

按键扫描驱动程序
Juliet宣布谈论于2006-5-10 11:35:00

按键扫描驱动程序


//按键扫描驱动程序

unsigned char key,key_h,kpush;
unsigned int key_l;

//按键连接到p1.0、p1.1、p1.2

void int_t0(void) interrupt 1 {
unsigned char dd,i;
TL0=TL0+30;TH0=0xfb; //800

if ((P1&0x7)==0x7) {
if ((key_l>30)&&(key_l<800)&&(key_h>30)) { //开释按键,假如之前按键时刻少于1秒,读入键值
key=kpush;
}
if ((++key_h)>200) key_h=200;
key_l=0;
if (key>=0x80) key=0; //假如之前的按键为长按1秒,铲除键值
} else {
kpush=P1&0x7;
key_l++;
if ((key_l>800)&&(key_h>30)) { //假如按键超越1秒,键值加0x80标志长按键
key=kpush|0x80;
key_h=0;
key_l=0;
}
}
}
void main(void) {
TMOD=0x1;TR0=1;ET0=1;EA=1;
while (1) {
while (!key) {}
switch (key) {
case 1:break;
case 2:break;
}
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/ic/261776.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部