采用独特算法的键盘扫描程序


采用独特算法的键盘扫描程序
  大家一起计论,还有没有可能将代码再优化


行列式键盘扫描子程序.rar
(2008-07-20 18:58:04, Size: 44.7 KB, Downloads: 35)


我也来说两句 查看全部回复

最新回复

  • bonjour (2008-7-20 20:40:11)

    下载 了                            
  • fz5098 (2008-7-20 22:39:28)

  • yubo2007 (2008-7-21 06:40:37)

    顶一个!!!!!!!!!!!!
  • hgjinwei (2008-7-21 14:16:53)

    ;//======================================================================
    ;//
    ;//     程序名称:key_scan.asm
    ;//     程序用途:4*4矩阵键盘扫描检测
    ;//     功能描述:扫描键盘,确定按键值。程序不支持双键同时按下,
    ;//               如果发生双键同时按下时,程序将只识别其中先扫描的按键
    ;//     程序入口:void
    ;//     程序出口:CY : 有效性(0);ACC : 按键扫描值;KEY_STU : 按键状态记录
    ;//     编写人  :xxxx,2007-12-11
    ;//     最后修改:xxx,2007-12-12
    ;//
    ;//======================================================================
    KEY_STU         DATA    40H             ;b7-b5纪录按键状态,b4-b0记录等待时间
    R_TIME          EQU     30              ;重复按键输入等待时间(不能大于32)
    KEY_PORT        EQU     P1              ;键盘接口(必须完整I/O口)
    ;//======================================================================
    KEY_CHK:
    ;//=============按键检测程序=============================================
            ANL     KEY_PORT,#0FH           ;送扫描信号
            MOV     A,KEY_PORT              ;读按键状态
            CJNE    A,#0FH,KEY_NEXT1        ;ACC<=0FH
    ;       CLR     C                       ;Acc等于0FH,则CY为0,无须置0
    KEY_NEXT1:
    ;       SETB    C                       ;Acc不等于0FH,则ACC必小于0FH,CY为1,无须置1
            MOV     A,KEY_STU
            RRC     A                       ;ACC带CY右移一位,将当前状态记录到最高位
            ANL     A,#0E0H                 ;屏蔽低五位
            DEC     KEY_STU                 ;每执行一次,按键等待时间减1
            ANL     KEY_STU,#1FH            ;屏蔽高三位,准备接受新值
            ORL     KEY_STU,A               ;保留按键状态
    ;//=============判别按键状态,决定是否执行按键扫描========================
            CJNE    A,#0C0H,KEY_NEXT2       ;110按键稳定闭合,进入按键检测程序
            SJMP    KEY_SCAN
    KEY_NEXT2:
            CJNE    A,#0E0H,KEY_NEXT3       ;111按键长闭合,重复输入允许判断
            SJMP    KEY_WAIT
    KEY_NEXT3:
            CJNE    A,#040H,KEY_NEXT4
            ANL     KEY_STU,#01FH           ;010干扰,当000处理
           ;SJMP KEY_R_0                 ;ACC等于040H,不会等于0A0H,直接跳转可转为测试跳转
    KEY_NEXT4:
            CJNE    A,#0A0H,KEY_RET_0       ;101干扰,当111长闭合处理
            ORL     KEY_STU,#0E0H
    KEY_WAIT:
            MOV     A,KEY_STU
            ANL     A,#01FH                 ;屏蔽高三位(状态位)
            JZ      KEY_SCAN                ;时间已到,扫描键盘
    KEY_RET_0:     ;按键扫描无效,返回CY = 1
            SETB    C         ;没有按键,返回1,按键无效
            ORL     KEY_PORT,#0FFH
            RET
            RET
            RET
    ;//=============键盘扫描程序==============================================
    KEY_SCAN:
            MOV     R2,#4                   ;初始化列地址
            MOV     R3,#11111110B           ;初始化扫描码
    KEY_LOOP:
            MOV     A,R3
            RR      A
            MOV     R3,A                    ;保留扫描码
            MOV     KEY_PORT,A              ;送扫描码
            MOV     A,KEY_PORT              ;读键盘
            ORL     A,#0F0H                 ;屏蔽高四位
            CJNE    A,#0FFH,KEY_NEXT21      ;A不等于FFH,说明该列有按键动作
            DJNZ R2,KEY_LOOP
            SJMP KEY_RET_0               ;扫描没有检测到按键,返回0           
    ;//=======================================================================
    CORRECT equ 7 ;修正值
    KEY_NEXT21:
            JB      ACC.0,KEY_NEXT22
            MOV     R3,#1+CORRECT           ;第1行有按键
            SJMP    KEY_NEXT25
    KEY_NEXT22:
            JB      ACC.1,KEY_NEXT23
            MOV     R3,#2+CORRECT           ;第2行有按键
            SJMP    KEY_NEXT25
    KEY_NEXT23:
            JB      ACC.2,KEY_NEXT24
            MOV     R3,#3+CORRECT           ;第3行有按键
            SJMP    KEY_NEXT25
    KEY_NEXT24:
            MOV     R3,#4+CORRECT           ;第4行有按键
    KEY_NEXT25:                             ;计算按键地址
            MOV     A,R2
            RL      A
            RL      A                       ;列地址乘4(每列对应4行)
            ADD     A,R3                    ;加行地址
            MOVC    A,@A+PC
    KEY_RET_1:    ;按键扫描有效,返回按键值
            ORL     KEY_PORT,#0FFH
            ANL     KEY_STU,#0E0H
            ORL     KEY_STU,#R_TIME         ;送重复按键等待时间
           ;CLR     C                       ;ACC+R3不会进位,CY无须清0
            RET                             ;退出
            RET
            RET
    ;//=============按键名称表================================================
    KEYNAME_TTAB:
    DB      07H,08H,09H,0AH
    DB      04H,05H,06H,0BH
    DB      01H,02H,03H,0CH
    DB      0FH,00H,0EH,0DH
    不知这个程序算不算比较好.

    [ 本帖最后由 hgjinwei 于 2008-7-27 15:11 编辑 ]
  • arnxuezhe (2008-7-21 14:49:42)

    赚点钱用用先
  • arnxuezhe (2008-7-21 14:50:37)

    赚点钱用用先
  • skdyu (2008-7-21 14:53:56)

    实施看!!!!!谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!
  • fuda208 (2008-7-22 11:34:37)

    下下来瞅瞅 呵呵              
  • panhearii (2008-7-22 11:43:28)

    汇编 看不懂 。。。。。。。。。。。。。。。
  • qinhonghua (2008-7-22 11:48:10)

    呵呵呵,还是用汇编编的。。。。
  • hgjinwei (2008-7-22 12:51:50)

    简单的问题用汇编好点, 可以节省很多资源和程序运行时间.
  • jiankewuying (2008-7-23 20:18:44)

    确实不错噢.我又学到了一种新方法了,哈哈:
  • zcmhff (2008-7-25 22:04:10)

    這東西不錯 啊           ,支持啊
    哈哈
  • arnxuezhe (2008-7-26 14:19:38)

    我不喜欢汇编,C比较简单^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  • hgjinwei (2008-7-26 15:19:27)

    QUOTE:

    原帖由 arnxuezhe 于 2008-7-26 14:19 发表
    我不喜欢汇编,C比较简单^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    这家伙肯定很懒得动脑 ,
  • ybzjllj (2008-7-27 13:53:07)


    1.JPG

    CODE:

    /*****************************************************************
    文件名称:行列式键盘扫描程序
    作 者: 徐修亮
    版 本:
    说 明:
    日期 : 2008 4 26
    修改记录:2008 7 20 14:00 修改后能直接返回0-16的键值
    2008 7 20 17:30 优化了代码

    *******************************************************************/
    #include
    #define uchar unsigned char
    #define PORT P2 //义键盘行列端口,低位为行,高位为列,
    uchar scan (void);
    uchar key(void);
    void delay100us(uchar t);

    void main(void)
    { uchar idata key1;
    while(1)
    { key1=key();
    P1=key1;
    }
    }

    /*************************************************
    函数名称:uchar key(uchar x)
    函数功能:按顺充返回键值0到15,其中若为16则说明无键按下
    入口参数:无
    出口参数:uchar key() 即返回的键值
    备 注:
    *************************************************/
    /*
    uchar key(void)
    { uchar temp ;
    switch(scan())
    {
    case 0 : temp=16 ; break; //无键按下返回16
    case 0x11 : temp=0 ; break; //返回键值
    case 0x21 : temp=1 ; break;
    case 0x41 : temp=2 ; break;
    case 0x81 : temp=3 ; break;
    case 0x12 : temp=4 ; break;
    case 0x22 : temp=5 ; break;
    case 0x42 : temp=6 ; break;
    case 0x82 : temp=7 ; break;
    case 0x14 : temp=8 ; break;
    case 0x24 : temp=9 ; break;
    case 0x44 : temp=10 ; break;
    case 0x84 : temp=11 ; break;
    case 0x18 : temp=12 ; break;
    case 0x28 : temp=13 ; break;
    case 0x48 : temp=14 ; break;
    case 0x88 : temp=15 ; break;

    }
    return temp ;
    }
    */

    /*********************************************************
    函数名称:uchar key(uchar x)
    函数功能:按顺充返回键值0到15,其中若为16则说明无键按下
    入口参数:无
    出口参数:uchar key() 即返回的键值
    备 注: 利用算法对代码进行优化使程序与前面的单独进行比较
    方法相比,代码减少96个字节 ,虽然RAM多两个

    ***********************************************************/
    uchar key(void)
    { uchar y,high4,low4,temp,i,j;
    y=scan();
    if(y==0) temp=16;
    else
    {
    high4=0x10;
    low4 =0x01;
    for(i=0;i<4;i++)
    for(j=0;j<4;j++)
    {
    if(y==(high4<<J)+(LOW4<<I))
    temp=4*i+j;
    }
    }
    return temp ;
    }




    uchar scan(void)
    { uchar idata sccode;
    uchar idata recode;
    PORT =0xf0;
    if((PORT&0xf0)!=0xf0)
    { delay100us(100); // 延时10ms去抖动
    if ((PORT&0xf0)!=0xf0)
    { sccode=0xfe;
    while((sccode&0x10)!=0) //没有扫描到最后一行,则往下执行

    { PORT=sccode;
    if((PORT&0xf0)!=0xf0) //若有键按下则往下执行
    { recode=(PORT&0xf0)|0x0f;
    return ( (~sccode)+(~recode)) ; //特征值
    }
    else
    sccode=((sccode<<1)|0x01);
    }
    }
    }
    }
    /******************************
    函数名称:delay(uchar t)
    函数功能: 延时t/10 ms
    入口参数: uchar t
    出口参数: 无
    备 注:
    ******************************/
    void delay100us(uchar t)
    {
    uchar j;
    while(t--)
    {
    for (j=50 ;j>0;j--);
    }
    }
  • hygk (2008-7-30 15:25:16)

    我喜欢 汇编的
    有没有汇编的啊
  • hgjinwei (2008-7-30 19:07:18)

    5#不就是汇编的咯.
    不过不支持多键状态 ,  不知多键状态有什么好算法.
  • MCU_51 (2008-8-28 14:43:36)

    写的不错,我个人是比较喜欢C写的东西,其中键码识别用了两种方法,都不错,记得当时我是用查表法实现的,效果还可以!
  • hyzqq (2008-8-28 17:24:33)


    编好 ! 我喜欢