微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 按键的C51源程序

按键的C51源程序

时间:11-22 来源:互联网 点击:
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;设置跳变标志(防止放键

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top