原创 4*4键盘多模块演示程序

2006-12-30 01:51 5150 10 11 分类: MCU/ 嵌入式
4*4键盘多模块演示程序
mood25.gif HotPower 发表于 2004-5-9 13:07 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖举报该贴


;--------PS/2-----------------------
PS2CLOCK       BIT   INT1;PC小键盘时钟
PS2DATA        BIT   T1;PC小键盘数据
;--------X5045----------------------
WREN           EQU   00000110B;
WRDI           EQU   00000100B;
RDSR           EQU   00000101B;
WRSR           EQU   00000001B;
READ           EQU   00000011B;
WRITE          EQU   00000010B;
WD1            BIT   5;
WD0            BIT   4;
BL1            BIT   3;
BL0            BIT   2;
WEL            BIT   1;
WIP            BIT   0;
;%%%%%%%DS1302串行时钟芯片%%%%%%%%%%%%%%%%%%%%
timerst        BIT P2.2
timeio         BIT P2.5
timeclk        BIT P2.6

timemaxaddr    EQU 01fh;(XX11111X)

;                 rDDDDDr(1)
;                1a     /
;                 m43210w(0)
timewriteram0  EQU 11000000b;0c0h
timereadram0   EQU 11000001b;0c1h
timewriteram1  EQU 11000010b;0c2h
timereadram1   EQU 11000011b;0c3h
timewriteram2  EQU 11000100b;0c4h
timereadram2   EQU 11000101b;0c5h
timewriteram3  EQU 11000110b;0c6h
timereadram3   EQU 11000111b;0c7h
timewriteram4  EQU 11001000b;0c8h
timereadram4   EQU 11001001b;0c9h
timewriteram5  EQU 11001010b;0cah
timereadram5   EQU 11001011b;0cbh
timewriteram6  EQU 11001100b;0cch
timereadram6   EQU 11001101b;0cdh
timewriteram7  EQU 11001110b;0ceh
timereadram7   EQU 11001111b;0cfh
timewriteram8  EQU 11010000b;0d0h
timereadram8   EQU 11010001b;0d1h
timewriteram9  EQU 11010010b;0d2h
timereadram9   EQU 11010011b;0d3h
timewriteram10 EQU 11010100b;0d4h
timereadram10  EQU 11010101b;0d5h
timewriteram11 EQU 11010110b;0d6h
timereadram11  EQU 11010111b;0d7h
timewriteram12 EQU 11011000b;0d8h
timereadram12  EQU 11011001b;0d9h
timewriteram13 EQU 11011010b;0dah
timereadram13  EQU 11011011b;0dbh
timewriteram14 EQU 11011100b;0dch
timereadram14  EQU 11011101b;0ddh
timewriteram15 EQU 11011110b;0deh
timereadram15  EQU 11011111b;0dfh
timewriteram16 EQU 11100000b;0e0h
timereadram16  EQU 11100001b;0e1h
timewriteram17 EQU 11100010b;0e2h
timereadram17  EQU 11100011b;0e3h
timewriteram18 EQU 11100100b;0e4h
timereadram18  EQU 11100101b;0e5h
timewriteram19 EQU 11100110b;0e6h
timereadram19  EQU 11100111b;0e7h
timewriteram20 EQU 11101000b;0e8h
timereadram20  EQU 11101001b;0e9h
timewriteram21 EQU 11101010b;0eah
timereadram21  EQU 11101011b;0ebh
timewriteram22 EQU 11101100b;0ech
timereadram22  EQU 11101101b;0edh
timewriteram23 EQU 11101110b;0eeh
timereadram23  EQU 11101111b;0efh
timewriteram24 EQU 11110000b;0f0h
timereadram24  EQU 11110001b;0f1h
timewriteram25 EQU 11110010b;0f2h
timereadram25  EQU 11110011b;0f3h
timewriteram26 EQU 11110100b;0f4h
timereadram26  EQU 11110101b;0f5h
timewriteram27 EQU 11110110b;0f6h
timereadram27  EQU 11110111b;0f7h
timewriteram28 EQU 11111000b;0f8h
timereadram28  EQU 11111001b;0f9h
timewriteram29 EQU 11111010b;0fah
timereadram29  EQU 11111011b;0fbh
timewriteram30 EQU 11111100b;0fch
timereadram30  EQU 11111101b;0fdh
timewriteramall EQU 11111110b;0feh;多字节写DS1302命令(ram)
timereadramall EQU 11111111b;0ffh;多字节读DS1302命令(ram)


;                 rDDDDDr(1)
;                1a     /
;                 g43210w(0)

timewriteseg   EQU 10000000b;080h
timereadseg    EQU 10000001b;081h

timewritemin   EQU 10000010b;082h
timereadmin    EQU 10000011b;083h

timewritehr    EQU 10000100b;084h
timereadhr     EQU 10000101b;085h

timewritedate  EQU 10000110b;086h
timereaddate   EQU 10000111b;087h

timewritemonth EQU 10001000b;088h
timereadmonth  EQU 10001001b;089h

timewriteday   EQU 10001010b;08ah
timereadday    EQU 10001011b;08bh

timewriteyear  EQU 10001100b;08ch
timereadyear   EQU 10001101b;08dh

timewriteregall EQU 10001110b;08eh;多字节写DS1302命令(reg)
timereadregall EQU 10001111b;08fh;多字节读DS1302命令(reg)

tricklewrite    equ  10010000b;90h
trickleread     equ  10010001b;91h
;-------------------------------------------------
;                    HABCDEFG
LEDCHAR0        EQU  01111110B;'0'
LEDCHAR1        EQU  00110000B;'1'
LEDCHAR2        EQU  01101101B;'2'
LEDCHAR3        EQU  01111001B;'3'
LEDCHAR4        EQU  00110011B;'4'
LEDCHAR5        EQU  01011011B;'5'
LEDCHAR6        EQU  01011111B;'6'
LEDCHAR7        EQU  01110000B;'7'
LEDCHAR8        EQU  01111111B;'8'
LEDCHAR9        EQU  01111011B;'9'
LEDCHARA        EQU  01110111B;'A'
LEDCHARB        EQU  00011111B;'B'
LEDCHARC        EQU  01001110B;'C'
LEDCHARD        EQU  00111101B;'D'
LEDCHARE        EQU  01001111B;'E'
LEDCHARF        EQU  01000111B;'F'
LEDCHAR         EQU  11111111B;'8.'
;-------------------------------------------------
TIME1_25MS      EQU  -1152;-1250*0.9216;1.25MS
TIME8MS         EQU  -8000;*0.9216;8MS
;-----------------------------------------------
DEFBEEPMODE1        EQU 10000000B;响1声
DEFBEEPMODE2        EQU 10110000B;响2声
DEFBEEPMODE3        EQU 10101100B;响3声
DEFBEEPMODE4        EQU 10101011B;响4声
;-------------------------------------
CS      BIT     P2.7
WDT    BIT       P2.7;X5045CS
SCK     BIT     P2.6
SI      BIT     P2.5
SO      BIT     P2.5
SIO     BIT     P2.5
WP      BIT     P2.4
BEEP    BIT    P2.3
RST     BIT     P2.2;DS1302CS
;------------------------------------
ISDCS   BIT     P2.4;ISD4004
SCLK    BIT     P2.6
MOSI    BIT     P2.5
MISO    BIT     P2.5
;-------------------------------------
LOAD    BIT     P2.1;MAX7219CS
CLK     BIT     P2.6
DIN     BIT     P2.5
;------------------------------------
;BBCBUS BIT     P2.0;模拟串口(9600bps)
;-----------------------------------
; 8052 Extensions
WDTRST  DATA    0A6H
AUXR    DATA    08EH
T2CON   DATA    0C8H
RCAP2L  DATA    0CAH
RCAP2H  DATA    0CBH
TL2     DATA    0CCH
TH2     DATA    0CDH
ET2     BIT     0ADH
PT2     BIT     0BDH
T2EX    BIT     091H
T2      BIT     090H
TF2     BIT     0CFH
EXF2    BIT     0CEH
RCLK    BIT     0CDH
TCLK    BIT     0CCH
EXEN2   BIT     0CBH
TR2     BIT     0CAH
C_T2    BIT     0C9H
CP_RL2  BIT     0C8H
;-------RS1EQU0,RS0EQU0 系统服务区----------
REGR00     DATA    000H
REGR01     DATA    001H
REGR02     DATA    002H
REGR03     DATA    003H
REGR04     DATA    004H
REGR05     DATA    005H
REGR06     DATA    006H
REGR07     DATA    007H

R00     DATA    000H
R01     DATA    001H
R02     DATA    002H
R03     DATA    003H
R04     DATA    004H
R05     DATA    005H
R06     DATA    006H
R07     DATA    007H
;-------RS1EQU0,RS0EQU1 系统服务区----------
R10     DATA    008H
R11     DATA    009H
R12     DATA    00AH
R13     DATA    00BH
R14     DATA    00CH
R15     DATA    00DH
R16     DATA    00EH
R17     DATA    00FH
;-------RS1EQU1,RS0EQU0 键盘缓冲区----------
R20     DATA    010H
R21     DATA    011H
R22     DATA    012H
R23     DATA    013H
R24     DATA    014H
R25     DATA    015H
R26     DATA    016H
R27     DATA    017H
;-------RS1EQU1,RS0EQU1 键盘缓冲区----------
R30     DATA    018H
R31     DATA    019H
R32     DATA    01AH
R33     DATA    01BH
R34     DATA    01CH
R35     DATA    01DH
R36     DATA    01EH
R37     DATA    01FH
;---------------系统定义------------------
KEYBUF1          DATA   20H
KEYBUF2          DATA   21H
KEYCOUNT         DATA   22H;键号
LEDBIT           DATA   23H;
LEDCPLBIT        BIT    LEDBIT.0
BEEPMODE         DATA   2FH
;-----------------------------------------
BEEPCOUNT        DATA   30H
BEEPBUFF         DATA   31H
SYSTEMTIME1_25MS DATA   32H;1.25MS
SYSTEMTIME125MS  DATA   33H;0.5秒
SYSTEMTIME500MS  DATA   34H;0.5秒
;----------------------------------------
LEDHIGHBUFF1     DATA   40H
LEDLOWBUFF1      DATA   41H
LEDHIGHBUFF2     DATA   42H
LEDLOWBUFF2      DATA   43H
;----------------------------------------
TIMEWRBIT        DATA   48H;时间写入位
;----------------------------------------
LEDBUFF          DATA   50H;50H~5FH
LEDBUFF0         DATA   50H
LEDBUFF1         DATA   51H
LEDBUFF2         DATA   52H
LEDBUFF3         DATA   53H
LEDBUFF4         DATA   54H
LEDBUFF5         DATA   55H
LEDBUFF6         DATA   56H
LEDBUFF7         DATA   57H
LEDBUFF8         DATA   58H
LEDBUFF9         DATA   59H
LEDBUFFA         DATA   5AH
LEDBUFFB         DATA   5BH
LEDBUFFC         DATA   5CH
LEDBUFFD         DATA   5DH
LEDBUFFE         DATA   5EH
LEDBUFFF         DATA   5FH
RAM_55H      DATA   7EH
RAM_AAH      DATA   7FH
;---------------------------------------
SP_MIN         DATA RAM_AAH
;-------主程序开始----------------------
    ORG    0000H
START:
    LJMP  MAINSTART;主程序开始
    ORG   0003H
;-------掉电保护中断INT0服务程序--------
INT0_INTADDR:
    RETI
    ORG   000BH
;-------定时器T0中断服务程序------------
T0_INTADDR:
    LJMP  T0INTPROC;定时器T0中断服务程序
    RETI
    ORG   0013H
;-------外部中断INT1服务程序------------
INT1_INTADDR:
        LJMP  PS2PROC;PS/2键盘中断服务程序
    RETI
    ORG   001BH
;-------定时器T1中断服务程序------------
T1_INTADDR:
    LJMP  T1INTPROC;定时器T1中断服务程序
    RETI
    ORG   0023H
;-------串行中断服务程序----------------
SINT_INTADDR:
    RETI
    ORG   002BH
;-------定时器T2中断服务程序------------
    LJMP  T2INTPROC;执行中断服务程序
    RETI
;-------取键号---------------------------
GETKEYNUM:
        MOV   A,KEYCOUNT;取键号;0~15
    ANL   A,#0FH
    ADD   A,#LOW(KEYVALTAB-GETKEYNUMOFF)
    MOVC  A,@A+PC
GETKEYNUMOFF:
    RET
;-------4*4键盘接线示意-----------------
;         |  |  |  |
;P1.7  <->C--8--4--0--
;P1.6  <->D--9--5--1--
;P1.5  <->E--A--6--2--
;P1.4  <->F--B--7--3--
;P1.3  <->|  |  |  |
;P1.2  <---->|  |  |
;P1.1  <------->|  |
;P1.0  <---------->|
;-------键值表---------------------------
KEYVALTAB:
KEY07:  DB    10000001B;0(p1.0-p1.7)
KEY06:  DB    01000001B;1(p1.0-p1.6)
KEY05:  DB    00100001B;2(p1.0-p1.5)
KEY04:  DB    00010001B;3(p1.0-p1.4)

KEY17:  DB    10000010B;4(p1.1-p1.7)
KEY16:  DB    01000010B;5(p1.1-p1.6)
KEY15:  DB    00100010B;6(p1.1-p1.5)
KEY14:  DB    00010010B;7(p1.1-p1.4)

KEY27:  DB    10000100B;8(p1.2-p1.7)
KEY26:  DB    01000100B;9(p1.2-p1.6)
KEY25:  DB    00100100B;A(p1.2-p1.5)
KEY24:  DB    00010100B;B(p1.2-p1.4)

KEY37:  DB    10001000B;C(p1.3-p1.7)
KEY36:  DB    01001000B;D(p1.3-p1.6)
KEY35:  DB    00101000B;E(p1.3-p1.5)
KEY34:  DB    00011000B;F(p1.3-p1.4)
;-------执行键盘命令----------------------
;本程序利用散转回收技术
;它的最大优点是散转处的子程序可被它用
KEYPROC:
    ANL   A,#00111111B;有键压下键码0~15,16~31
    MOV   B,A
    RL    A;*2
    MOV   R1,A
    ADD   A,#LOW(KEYJMPPROCTAB-KEYPROC_OFF1+1)
    MOVC  A,@A+PC;取低8位地址
KEYPROC_OFF1:
        PUSH  ACC;压入低8位地址
    MOV   A,R1
    ADD   A,#LOW(KEYJMPPROCTAB-KEYPROC_OFF2)
    MOVC  A,@A+PC;取高8位地址
KEYPROC_OFF2:
        PUSH  ACC;压入高8位地址
        MOV   A,B;取键号;0~15
    RET;执行键盘命令
;-------压键事件处理地址表--------------------
KEYJMPPROCTAB:
    DW    KEYPROC0
    DW    KEYPROC1
    DW    KEYPROC2
    DW    KEYPROC3
    DW    KEYPROC4
    DW    KEYPROC5
    DW    KEYPROC6
    DW    KEYPROC7
    DW    KEYPROC8
    DW    KEYPROC9
    DW    KEYPROCA
    DW    KEYPROCB
    DW    KEYPROCC
    DW    KEYPROCD
    DW    KEYPROCE
    DW    KEYPROCF
;-------放键事件处理地址表--------------------
    DW    KEYPROC0X
    DW    KEYPROC1X
    DW    KEYPROC2X
    DW    KEYPROC3X
    DW    KEYPROC4X
    DW    KEYPROC5X
    DW    KEYPROC6X
    DW    KEYPROC7X
    DW    KEYPROC8X
    DW    KEYPROC9X
    DW    KEYPROCAX
    DW    KEYPROCBX
    DW    KEYPROCCX
    DW    KEYPROCDX
    DW    KEYPROCEX
    DW    KEYPROCFX
;-------长压键事件处理地址表--------------------
    DW    KEYPROC0W
    DW    KEYPROC1W
    DW    KEYPROC2W
    DW    KEYPROC3W
    DW    KEYPROC4W
    DW    KEYPROC5W
    DW    KEYPROC6W
    DW    KEYPROC7W
    DW    KEYPROC8W
    DW    KEYPROC9W
    DW    KEYPROCAW
    DW    KEYPROCBW
    DW    KEYPROCCW
    DW    KEYPROCDW
    DW    KEYPROCEW
    DW    KEYPROCFW
;------------------------------------------
GETTIMETAB:
    MOV   A,TIMEWRBIT;取时间写入位
    RR    A;/2
    ANL   A,#07H;
    ADD   A,#LOW(GETTIMETABTAB-GETTIMETABOFF)
    MOVC  A,@A+PC
GETTIMETABOFF:
    RET
;-------取时间显示次序表地址-------------
GETTIMETABTAB:
    DB    timewriteram30;千年
        DB    timewriteyear;年
        DB    timewritemonth;月
        DB    timewritedate;日
        DB    timewritehr;时
        DB    timewritemin;分
        DB    timewriteseg;秒
        DB    timewriteday;星期
;------------------------------
MAINSTART:
;-------P0口初始化------------------
    MOV   P0,#11111111B
;-------P1口初始化------------------
    MOV   P1,#11111111B
;-------P2口初始化------------------
    MOV   P2,#11101011B;P2.2,P2.4=0
;-------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   DPTR,#MAINNEXT
    PUSH  DPL
    PUSH  DPH
    RETI
MAINNEXT:
    MOV   DPTR,#MAINPROC
    PUSH  DPL
    PUSH  DPH
    RETI
MAINPROC:
    LCALL MAININIT;系统初始化
;-------主循环-------------------------------------------
;所有正常中断都必须返回到此处,否则,软狗造成系统复位
MAINLOOP:
        MOV   IE,#10101011B;开中断,害怕关定时器中断
    ORL   PCON,#00001101B;待机,喂软狗(pcon<2,3>=1)
    SJMP  MAINLOOP;死循环,所有程序只能通过中断完成!
;-------主程序初始化-------------------------------------
MAININIT:
;-------接口初始化--------------------------
    LCALL SYSTEMIOINIT;系统接口初始化
    MOV   PCON,#00001100B;喂软狗
     CLR   WDT;发送外看门狗喂狗信号
    MOV   WDTRST,#01EH;AT89S52喂内狗
    MOV   WDTRST,#0E1H;AT89S52喂内狗
     SETB  WDT;发送外看门狗喂狗信号
;-------内存初始化-------------------------
    MOV   A,RAM_55H
    XRL   A,RAM_AAH
    CPL   A
    JZ    MAININITNEXT;内存未破坏
    MOV   RAM_55H,#055H
    MOV   RAM_AAH,#0AAH
    LCALL SYSTEMINIT;系统初始化
MAININITNEXT:
;-------运行初始化---------------
    LCALL SYSTEMSETUP;系统设置
    RET
SYSTEMINIT:
;-------开机铃声----------------------------------
        MOV   A,#DEFBEEPMODE3;开机正常铃声
    LCALL SETBEEPMODE;设置响铃方式
;-----------------------------------
    RET
;-------系统接口初始化------------------------------
SYSTEMIOINIT:
;-------键盘初始化------------------------------
    RET
;-------系统设置--------------------------------------
SYSTEMSETUP:
;-------系统主频11.0592MHz---------------------------------
    MOV   AUXR,#01H;关闭EMI
;---------------------------------------------------
    MOV   PCON,#00001100B;喂软狗
        CLR   WDT;发送外看门狗喂狗信号
    MOV   WDTRST,#01EH;AT89S52喂内狗
    MOV   WDTRST,#0E1H;AT89S52喂内狗
     SETB  WDT;发送外看门狗喂狗信号
    MOV   IP,#00100001B;中断优先级EX0>ET2>ET0>EX1>ES
     MOV   TMOD,#00010001B;定时器0,1为方式1(十六位定时器)
    MOV   TCON,#01010101B;启动定时器TR1EQUTR0EQU1,IT1EQUIT0EQU1
;------------------------------------------------------
    MOV   TL0,#LOW(TIME8MS);设置定时器0时间常数
    MOV   TH0,#HIGH(TIME8MS)
;------------------------------------------------------
    MOV   TL1,#LOW(TIME8MS);设置定时器1时间常数
    MOV   TH1,#HIGH(TIME8MS)
;-------设置最小时间片1.25mS---------------------------
        MOV   RCAP2L,#LOW(TIME1_25MS)
        MOV   RCAP2H,#HIGH(TIME1_25MS)
        MOV   TL2,RCAP2L;设置定时器2时间常数
        MOV   TH2,RCAP2H
    SETB  TR2;启动定时器2
    mov   SYSTEMTIME1_25MS,#00h
    mov   SYSTEMTIME500MS,#00h
    LCALL timeDS1302open
        MOV   DPTR,#01FEH
        MOV   A,#055H
        LCALL X5045WRITEBYTE
        INC   DPTR
        MOV   A,#0AAH
        LCALL X5045WRITEBYTE
;-------系统延时参数设置------------------------
    LCALL LEDINIT
    LCALL KEYINIT
    RET
KEYINIT:
    MOV   KEYCOUNT,#00H
    MOV   B,#10H
    MOV   R0,#R20
KEYINITLOOP:
    MOV   @R0,#00H
    INC   R0
    DJNZ  B,KEYINITLOOP
    RET
;-------定时器T0中断服务程序------------
T0INTPROC:
    PUSH  PSW
;;;;;;;;喂软狗信号处理程序;;;;;;;;;;;;;;;;;;;;;;;;;;;
    MOV   A,PCON
    ANL   A,#00001100B
    JZ    T01INTPROCERR;T0T1都无喂狗信号,程序飞
    ANL   PCON,#11111011B;清除喂软狗信号0(自毁)
;--------------------------------------------------
;       XXXX  XXXX
;--------------------------------------------------
    POP   PSW
    RETI
;-------定时器T1中断服务程序------------
T1INTPROC:
    PUSH  PSW
;;;;;;;;喂软狗信号处理程序;;;;;;;;;;;;;;;;;;;;;;;;;;;
    MOV   A,PCON
    ANL   A,#00001100B
    JZ    T01INTPROCERR;T0T1都无喂狗信号,程序飞
    ANL   PCON,#11110111B;清除喂软狗信号1(自毁)
;--------------------------------------------------
;       XXXX  XXXX
;--------------------------------------------------
    POP   PSW
    RETI
;-------T0T1都无喂狗信号,程序飞--------------------
;中断后未回到主循环MAINLOOP处喂软狗,程序必飞
T01INTPROCERR:
        MOV   IE,#00H;关中断
    MOV   SP,#SP_MIN;复位系统SP
    MOV   DPTR,#ERRORPROC
    PUSH  DPL
    PUSH  DPH
    RETI
;-------系统软启动----------------------
ERRORPROC:
        CLR   A
        PUSH  ACC
        PUSH  ACC
        RETI
;-------定时器T2中断服务程序------------
;1.250mS中断
T2INTPROC:
        CLR   TF2
    MOV   AUXR,#01H;关闭EMI
    PUSH  PSW
    PUSH  ACC
T2INTPROC_START:
;---------------------------------------------------
        CLR   WDT;发送外看门狗喂狗信号
    MOV   WDTRST,#01EH;AT89S52喂内狗
    MOV   WDTRST,#0E1H;AT89S52喂内狗
     SETB  WDT;发送外看门狗喂狗信号
;--------------------------------------------------
        INC   SYSTEMTIME1_25MS;1.25MS计数
        MOV   A,SYSTEMTIME1_25MS
        CJNE  A,#80,T2INTPROC_NEXTKEY;80*1.25MS=100mS
        MOV   SYSTEMTIME1_25MS,#00H
;-------100mS到-----------------------------
    INC   SYSTEMTIME125MS;
    LCALL SYSTEMT125MSPROC
    INC   SYSTEMTIME500MS;
        MOV   A,SYSTEMTIME500MS
        CJNE  A,#5,T2INTPROC_NEXTKEY;4*125MS=500mS
        MOV   SYSTEMTIME500MS,#00H
    CPL   LEDCPLBIT
;-------500mS到-------------------------------
        LCALL GETSYSTEMTIME;
    LCALL DISPLAY
T2INTPROC_NEXTKEY:
    LCALL TESTKEY;键扫描(扫描当前键号=T2中断进入号)
    INC   KEYCOUNT;准备下一键号
    ANL   KEYCOUNT,#00001111B
        POP   ACC
    POP   PSW
    RETI
;-------双向双次键扫描-------------------
INKEY:
;入口:
;       无
;出口:
;       ACC若为0,表示无键压下
;       ACC若非0,表示有键压下
    PUSH  B
    MOV   P1,#0F0H;发送低4位(行)
    NOP
    MOV   B,P1;接收高4位(列)
    MOV   P1,#00FH;发送高4位(列)
    NOP
    MOV   A,P1;接收低4位(行)
    MOV   P1,#0FFH
    ORL   A,B;得到负逻辑键值
    CPL   A;变为正逻辑键值
    POP   B
    RET
;-------双向双次键变换-------------------
;本程序与查表GETKEYNUM同功能,但太慢
GETKEYVAL:
    PUSH  B
       MOV   B,A;存键值
       ANL   B,#00001111B;行
       ANL   A,#11110000B;列
       JNB   B.2,GETKEYVAL1
       XRL   B,#00000111B;00000100B->00000011B
GETKEYVAL1:
        JNB   B.3,GETKEYVAL2
       XRL   B,#00001100B;00001000B->00000100B
GETKEYVAL2:
    DEC   B;0~3
    SWAP  A
       JNB   ACC.2,GETKEYVAL3
       XRL   A,#00000111B;01000000B->00110000B
GETKEYVAL3:
    JNB   ACC.3,GETKEYVAL4
       XRL   A,#00001100B;10000000B->01000000B
GETKEYVAL4:
    DEC   A
    XRL   A,#00000011B
    XCH   A,B
       RL    A
       RL    A
       ORL   A,B;合并得到键号。
    POP   B
    RET
;-------MCU多任务键盘事件处理-----------------------
TESTKEY:
;-------16键(4*4)测试----------------------------------------------
;键测试程序每1.25mS执行1次,16键被依次执行,共需16*1.25mS=20mS
;即每键的键扫描频率为20mS,这样就节约了消抖时间
;键测试程序进入的次序号即为键号,这样就可用查表节约查询时间
;用压键次数替代键盘缓冲区,实现压键,放键,长压键3个功能
;键盘缓冲区及双击键事件处理主要适用于文字处理
;长压键事件处理在工控中应用较广(避免多键操作,例手机的锁键盘处理)
;-------------------------------------------------------------------
    PUSH  B;保护现场
;-------键扫描---------------------------------
;本例采用4*4键盘,使用双向双次键扫描技术
        LCALL INKEY;双向双次键扫描
    JZ    TESTKEYERR;无键压下,进行放键事件处理
    MOV   B,A;保存正逻辑键值(采用GETKEYVAL变换,B应存进入次序号)
;-------取键号------------------------------------------------------
;关键:淘汰循环查表的陋习
;不该扫描的键不去管它,上天入地都随它!!!
    LCALL GETKEYNUM;查表取键号(也可用GETKEYVAL变换,但不如查表快和灵活)
;采用GETKEYNUM查表,比较编码
;采用GETKEYVAL变换,比较次序
        CJNE  A,B,TESTKEYERR;非法键(或多键)注意:每次只查本次!!!
;-------有键压下---------------------------------
        MOV   A,KEYCOUNT;取键号;0~15
        ADD   A,#R20;压键次数首址(10H)
    MOV   R0,A;得到压键次数首址(10H+键号)
           MOV   A,@R0;取当前被扫描键的压键次数
;----------------------------------------------
;可改动20*NmS,本例为N=2(键不太好)
;可以根据需要(键盘的好坏),设置N(1~255)
           CJNE  A,#2,$+3;1,20*2=40mS抖动
        JC    TESTKEYINC;键在抖动期,只计压键次数,不执行事件处理
;-------键压下---------------------------------------------
    JB    ACC.7,TESTKEYINC;单击键已执行,阻止单次重入
;-------压键必须解决重入问题-------------------------------
    SETB  ACC.7;设置禁止单次重入标志(压键次数的最高位)
    MOV   @R0,A;保存禁止单次重入标志
        MOV   A,KEYCOUNT;取键号;事件处理地址区域0~15
        LCALL KEYPROC;执行单击事件(散转回收技术)
        MOV   A,#DEFBEEPMODE1;压键铃声(响1声)
    LCALL SETBEEPMODE;设置响铃方式(只设置,发声自动处理)
TESTKEYINC:
    MOV   A,@R0;取压键次数地址
    INC   A;压键计次
    MOV   @R0,A;保存压键次数
    CLR   ACC.7;去掉单次重入标志,允许多次重入
;-------长压键判断-------------------------------------------
;0.5S长压键 500/20mS=25
;1.0S长压键1000/20mS=50
;1.5S长压键1500/20mS=75
;2.0S长压键2000/20mS=100
;若再长必须在对应长压键事件处理中再设计数器,以达到超长时间处理
    CJNE  A,#100,TESTKEYINCEXIT;100*20mS=2S长压
        MOV   @R0,#80H;设置禁止单次重入标志,允许多次重入
        MOV   A,KEYCOUNT;取键号(程序运行次数);0~15
    SETB  ACC.5;2S设置长压键事件处理地址区域;32~47
        LCALL KEYPROC;执行长压键事件(散转回收技术)
        MOV   A,#DEFBEEPMODE1;压键铃声(响1声)
    LCALL SETBEEPMODE;设置响铃方式(只设置,发声自动处理)
TESTKEYINCEXIT:
    POP   B;恢复现场
    RET
TESTKEYERR:
;-------无键压下--------------------------------
        MOV   A,KEYCOUNT;取键号(程序运行次数);0~15
        ADD   A,#R20;压键次数首址(10H)
    MOV   R0,A;得到压键次数首址(10H+键号)
    MOV   A,@R0;取当前被扫描键的压键次数
    JNB   ACC.7,TESTKEYCLR;未压过键,不处理放键事件
;-------键释放----------------------------------
        MOV   A,KEYCOUNT;取键号(程序运行次数);0~15
    SETB  ACC.4;设置放键事件处理地址区域,16~31
        LCALL KEYPROC;执行放键事件(散转回收技术)
TESTKEYCLR:
    MOV   @R0,#00H;清除本键压键次数
    POP   B
    RET

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2016-4-13 08:36

评论是对思考最好的总结…

用户377235 2016-4-13 08:35

评论是对思考最好的总结…

用户1376340 2008-9-8 16:04

不好意思没学汇编,看不懂,顶一下
相关推荐阅读
雁塔菜农 2012-04-05 17:51
2012年度新唐Cortex-M0助学开发套件有约束条件赠送申报贴
2012年度新唐Cortex-M0助学套件从4月起每月有约束条件发放16套。 申报人必须是21ic或 EDNC 会员 并具备1月的会龄。 申报时必须注明“遵守约束条件,缴纳250元订金,上...
雁塔菜农 2012-04-05 17:04
2012年度Cortex-M0助学园地推广框图
...
雁塔菜农 2012-04-01 17:59
2012年度Cortex-M0助学园地奖励计划细则
抢楼请点击:菜地公告:即日起创建《菜农Cortex-M0助学园地》(盖楼入口) 每月10号和25号的下午2:50进行2次抢楼,规则同去年12月的疯狂抢楼活动。 奖品由21IC、北航、广州迪圣...
雁塔菜农 2012-02-03 08:19
菜农谋略:搞定牛人宋俊德,对女牛人孙昌旭说:“记住,俺是雁塔菜农~~~ ”
http://www.baidu.com/s?wd=%B2%CB%C5%A9%D0%A6%CC%B8%A1%B6%D0%C2%C0%CB%C3%FB%C8%CB%D0%A7%D3%A6%A1%B7...
EE直播间
更多
我要评论
1
10
关闭 站长推荐上一条 /3 下一条