10427|13

164

帖子

0

TA的资源

禁止发言

楼主
 

矩阵键盘程序汇总 [复制链接]

最简单矩阵键盘扫描程序
key:mov p0,#00001111b;上四位和下四位分别为行和列,所以送出高
低电压检查有没有按键按下
jmp k10;跳到K10处开始扫描,这里可以改成其它条件转移指令来决
定本次扫描是否要继续,例如减1为0转移或者位为1或0才转移,这主
要用来增加功能,确认上一按键功能是否完成?是否相当于经过了延
时?是否要封锁键盘?
goend:jmp kend;如果上面判断本次不执行键盘扫描程序,则立即转
到程序尾部,不要浪费CPU的时间
k10:jb p0.0,k20;扫描正式开始,先检查列1四个键是否有键按下,
如果没有,则跳到K20检查列2
k11:mov p0,#11101111b;列1有键按下时,P0.0变低,到底是那一个键
按下?现在分别输出各行低电平
jb p0.0,k12;该行的键不按下时,p0.0为高电平,跳到到K12,检查其
它的行
mov r1,#1;如果正好是这行的键按下,将寄存器R0写下1,表示1号键
按下了
k12:mov p0,#11011111b
jb p0.0,k13
mov r1,#2;如果正好是这行的键按下,将寄存器R0写下2,表示2号键
按下了
k13:mov p0,#10111111b
jb p0.0,k14
mov r1,#3;如果正好是这行的键按下,将寄存器R0写下3,表示3号键
按下了
k14:mov p0,#01111111b
jb p0.0,kend;如果现在四个键都没有按下,可能按键松开或干扰,
退出扫描(以后相同)
mov r1,#4如果正好是这行的键按下,将寄存器R0写下4,表示4号键
按下了
jmp kend;已经找到按下的键,跳到结尾吧
k20:jb p0.1,k30;列2检查为高电平再检查列3、4
k21:mov p0,#11101111b;列2有健按下时,P0.0会变低,到底是那一
行的键按下呢?分别输出行的低电平
jb p0.1,k22;该行的键不按下时p0.0为高电平,跳到到K22,检查另
外三行
mov r1,#5;如果正好是这行的键按下,将寄存器R0写下5,表示5号键
按下了(以后相同,不再重复了)
k22:mov p0,#11011111b
jb p0.1,k23
mov r1,#6
k23:mov p0,#10111111b
jb p0.1,k24
mov r1,#7
k24:mov p0,#01111111b
jb p0.1,kend
mov r1,#8
jmp kend;已经找到按下的键,跳到结尾吧(以后相同,不要重复了
此帖出自单片机论坛

最新回复

程序好长啊! 拿去看看,给楼主顶一个帖子,算是对于楼主给大家做贡献的一个 鼓励吧,嗯嗯,值得值得,希望楼主继续努力啊!加油  详情 回复 发表于 2011-11-3 19:09
点赞 关注
 

回复
举报

164

帖子

0

TA的资源

禁止发言

沙发
 

回复 楼主 的帖子

k30:jb p0.2,k40
k31:mov p0,#11101111b
jb p0.2,k32
mov r1,#9
k32:mov p0,#11011111b
jb p0.2,k33
mov r1,#10
k33:mov p0,#10111111b
jb p0.2,k34
mov r1,#11
k34:mov p0,#01111111b
jb p0.2,kend
mov r1,#12
jmp kend

k40:jb p0.3,kend
k41:mov p0,#11101111b
jb p0.3,k42
mov r1,#13
k42:mov p0,#11011111b
jb p0.3,k43
mov r1,#14
k43:mov p0,#10111111b
jb p0.3,k44
mov r1,#15
k44:mov p0,#01111111b
jb p0.3,kend
mov r1,#16
kend: ret
此帖出自单片机论坛
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

板凳
 

在51单片机学习网上看到的资料(转载)

行列扫描键盘可检测出双键按下
#include
#define ulong         unsigned long
#define uint        unsigned int
#define uchar         unsigned char
extern void delay(unsigned int x);
unsigned char Tab_key[]=        //行列式键盘映射
    {0x00,                        //无键按下
    '7','8','9','/',
    '4','5','6','*',
    '1','2','3','-',
    'C','0','=','+',
    //下面为按'C'同时再按的键:
    '7','8','9','/',
    '4','5','6','*',
    '1','2','3','-',
        '0','=','+',};
    //  P1口行列式键盘  //
#define KEYPIN_L  P1               // 定义键扫描列端口为 P1
低四位输入  //
#define KEYPIN_H  P1              // 定义键扫描行端口为 P1高
四位扫描输出  //
    //  P1口行列式键盘  //
    //公用函数
unsigned char KeysCAN(void);    //  键扫描函数            //
    //内部私有函数
unsigned char fnKeycode(unsigned char key);     //  根据键盘
映射表输出顺序键值            //
/*
    //  P1口行列式键盘  //
extern unsigned char KeysCAN(void);    //  键扫描函数        
    //
*/
    //  P1口行列式键盘  //
//---------------------------------------------------------
------------------//
unsigned char KeysCAN(void)                      //  键扫描
函数            //
{
    unsigned char sccode,recode,keytemp = 0;
    KEYPIN_L = KEYPIN_L|0x0f;                    //  P1低四
位为列线输入         //
    KEYPIN_H = KEYPIN_H&0x0f;                    //  P1高四
位为行线发全零扫描码 //
    if ((KEYPIN_L&0x0f) !=  0x0f)
        {
        delay(10);                                //  延时
10 MS 消抖       //
        if ((KEYPIN_L&0x0f) !=  0x0f)
            {
            sccode = 0xef;                        //  逐行扫
描码初值(1110 1111)  //
            while(sccode !=  0xff)               //将扫描4次
,keytemp为每次键值相 或的值 //
                {
                KEYPIN_H = sccode;                 //  输出
行扫描码          //
                if ((KEYPIN_L&0x0f) !=  0x0f)    //  本行有
键按下          //
                    {
                    recode = (KEYPIN_L&0x0f)|0xf0;    //  只
要低位,高位置1  //
                    keytemp |=  (~sccode)+(~recode);    //特
征码(高位为列P3,低位为行KEYPIN_H)  //
                }
                sccode = (sccode << 1)|0x01;    //  扫描码0
向高位移动 //
            }
        }
    }
    KEYPIN_H = KEYPIN_H|0xf0;
    return(fnKeycode(keytemp));
}
//---------------------------------------------------------
------------------//
unsigned char fnKeycode(unsigned char key)     //  根据键盘
映射表输出顺序键值            //
    {
    switch(key)
        {
        case    0x11:                //   1 键  //
            key = 0x01;
            break;
        case    0x21:                //   2 键  //
            key = 0x02;
            break;
        case    0x41:                //   3 键  //
            key = 0x03;
            break;
        case    0x81:                //   4 键  //
            key = 0x04;
            break;
        case    0x12:                //   5 键  //
            key = 0x05;
            break;
        case    0x22:                //   6 键  //
            key = 0x06;
            break;
        case    0x42:                //   7 键  //
            key = 0x07;
            break;
        case    0x82:                //   8 键  //
            key = 0x08;
            break;
        case    0x14:                //   9 键  //
            key = 0x09;
            break;
        case    0x24:                //   10 键  //
            key = 0x0A;
            break;
        case    0x44:                //   11 键  //
            key = 0x0B;
            break;
        case    0x84:                //   12 键  //
            key = 0x0C;
            break;
        case    0x18:                //   13 键  //
            key = 0x0D;
            break;
        case    0x28:                //   14 键  //
            key = 0x0E;
            break;
        case    0x48:                //   15 键  //
            key = 0x0F;
            break;
        case    0x88:                //   16 键  //
            key = 0x10;
            break;
                    //以下为功能键//
        case    0x19:                //   'C' +1 键  //
            key = 0x11;
            break;
        case    0x29:                //   'C' +2 键  //
            key = 0x12;
            break;
        case    0x49:                //   'C' +3 键  //
            key = 0x13;
            break;
        case    0x89:                //   'C' +4 键  //
            key = 0x14;
            break;
        case    0x1A:                //   'C' +5 键  //
            key = 0x15;
            break;
        case    0x2A:                //   'C' +6 键  //
            key = 0x16;
            break;
        case    0x4A:                //   'C' +7 键  //
            key = 0x17;
            break;
        case    0x8A:                //   'C' +8 键  //
            key = 0x18;
            break;
        case    0x1C:                //   'C' +9 键  //
            key = 0x19;
            break;
        case    0x2C:                //   'C' +10 键  //
            key = 0x1A;
            break;
        case    0x4C:                //   'C' +11 键  //
            key = 0x1B;
            break;
        case    0x8C:                //   'C' +12 键  //
            key = 0x1C;
            break;
//        case    0x18:                //   'C' +13 键  //
//            key = 0x1D;
//            break;
        case    0x38:                //   'C' +14 键  //
            key = 0x1D;
            break;
        case    0x58:                //   'C' +15 键  //
            key = 0x1E;
            break;
        case    0x98:                //   'C' +16 键  //
            key = 0x1F;
            break;
        default     :                //   无键   //
            key = 0x00;
            break;
    }
    return(Tab_key[key]);
}
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

4
 
矩键查寻键值44程序与显示
#include
//#include
#include
#define uchar unsigned char
#define TURE 1
#define FALSE 0
int key;
int del;
void Tkey(void);
void led(void);

/************主  程序*************/
void main(void)
{
  void tkey(void);
  void led(void);
  void delay(int);

  
  SCON=0x00;
  TI=0;
  while(TURE)
  {
   Tkey();
   led();
   delay(2000);
  }
}



/********矩键查寻键值4*4程序******/按键为P1.0---P1.7
void Tkey(void)
{
  uchar readkey;//rereadkey;
  uchar x_temp,y_temp;

  P1=0x0f;
  x_temp=P1&0x0f;
  if(x_temp==0x0f) goto keyout;
  P1=0xf0;
  y_temp=P1&0xf0;
  readkey=x_temp|y_temp;
  readkey=~readkey;

switch(readkey)
    {
     case 0x11:key=0; break;
    case 0x21:key=1; break;
  case 0x41:key=2; break;
  case 0x81:key=3; break;
  case 0x12:key=4; break;
  case 0x22:key=5; break;
  case 0x42:key=6; break;
  case 0x82:key=7; break;
  case 0x14:key=8; break;
  case 0x24:key=9; break;
  case 0x44:key=10;break;
  case 0x84:key=11;break;
  case 0x18:key=12;break;
  case 0x28:key=13;break;
  case 0x48:key=14;break;
  case 0x88:key=15;break;
  default:  key=16;break;
    }
keyout:_nop_();
}


/************显示程序*************/
void led(void)
{uchar code LEDValue[]=
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};  //0-9
uchar data num[6];
uchar k;
num[0]=0;
num[1]=0;
num[2]=0;
num[3]=0;
num[4]=key/10;
num[5]=key-(key/10)*10;
for(k=0;k<=5;k++)
{
   SBUF=LEDValue[num[5-k]];
   while(TI==0);
   TI=0;
}
}



/************延时程序*************/
void delay(del)
{
for(del;del>0;del--);
}
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

5
 
;伪定义        
KEYBUF EQU 30H    ;键值暂存单元,查表时用
;*************************************
;*                                   *
;*      主程序和中断程序入口         *
;*                                   *
;*************************************
ORG     0000H           ;程序执行开始地址
AJMP    MAIN            ;跳至MAIN执行
;*************************************
;*                                   *
;*        主  程  序                 *
;*                                   *
;*************************************
ORG     0040H
MAIN:   MOV     P1,#0FFH
MOV     P3,#0FFH
LCALL   KEYSCAN         ;主体程序。调用查键子程序
   LJMP  MAIN     ;转MAIN循环
   NOP       ;软件陷阱
   NOP
   NOP
   LJMP  MAIN   
;*************************************
;*                                   *
;* 键盘工作子程序(4 * 5 阵列)        *
;* 接口为2051的P3和P1口              *
;*************************************
KEYSCAN:MOV  P3,#0FFH ;清P3口,初始化键低电平有效
      CLR  P3.2  ;清P3.2口
      MOV  A,P1  ;读P1口状态
      ANL  A,#0FH  ;清高4位,保留低四位低电平有效
      XRL  A,#0FH  ;异或相同则为0不同结果为1,为0则表;示无键被按下(这一行)
      JZ  NOKEY1  ;为0则转下一行键值处理
      LCALL  DL10MS  ;有键按下则延时10ms再测一次抗干扰
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY1  ;是干扰则转下一行键值处理程序
      MOV  A,P1
      ANL  A,#0FH  ;保留低四?
KB1: CJNE  A,#0EH,KB2 ;如果值为#0E则为P1.4与P1.0组合的键
      MOV  KEYBUF,#0 ;赋键值
      LJMP  KEYWORK  ;转键处理
KB2:  CJNE  A,#0DH,KB3 ;如果值为#0D则为P1.4与P1.1组合的键
      MOV  KEYBUF,#1
      LJMP  KEYWORK
KB3:  CJNE  A,#0BH,KB4 ;如果值为#0B则为P1.4与P1.2组合的
      MOV  KEYBUF,#2
      LJMP  KEYWORK
KB4:  CJNE  A,#07H,KB5 ;如果值为#07则为P1.4与P1.3组合的
      MOV  KEYBUF,#3
      LJMP  KEYWORK
KB5:  NOP
;
NOKEY1: MOV  P3,#0FFH
      CLR  P3.3
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY2
      LCALL  DL10MS
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY2
      MOV  A,P1
      ANL  A,#0FH
      CJNE  A,#0EH,KB6
      MOV  KEYBUF,#4
      LJMP  KEYWORK
KB6:  CJNE  A,#0DH,KB7
      MOV  KEYBUF,#5
      LJMP  KEYWORK
KB7:  CJNE  A,#0BH,KB8
      MOV  KEYBUF,#6
      LJMP  KEYWORK
KB8:  CJNE  A,#07H,KB9
      MOV  KEYBUF,#7
      LJMP  KEYWORK
KB9:  NOP
;
NOKEY2: MOV  P3,#0FFH
      CLR  P3.4
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY3
      LCALL  DL10MS
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY3
      MOV  A,P1
      ANL  A,#0FH
      CJNE  A,#0EH,KB10
      MOV  KEYBUF,#8
      LJMP  KEYWORK
KB10:  CJNE  A,#0DH,KB11
      MOV  KEYBUF,#9
      LJMP  KEYWORK
KB11:  CJNE  A,#0BH,KB12
      MOV  KEYBUF,#10
      LJMP  KEYWORK
KB12:  CJNE  A,#07H,KB13
      MOV  KEYBUF,#11
      LJMP  KEYWORK
KB13:  NOP
;
NOKEY3: MOV  P3,#0FFH
      CLR  P3.5
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY4
      LCALL  DL10MS
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY4
      MOV  A,P1
      ANL  A,#0FH
      CJNE  A,#0EH,KB14
      MOV  KEYBUF,#12
      LJMP  KEYWORK
KB14:  CJNE  A,#0DH,KB15
      MOV  KEYBUF,#13
      LJMP  KEYWORK
KB15:  CJNE  A,#0BH,KB16
      MOV  KEYBUF,#14
      LJMP  KEYWORK
KB16:  CJNE  A,#07H,KB17
      MOV  KEYBUF,#15
      LJMP  KEYWORK
KB17:  NOP
;
NOKEY4: MOV  P3,#0FFH
      CLR  P3.7
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY5
      LCALL  DL10MS
      MOV  A,P1
      ANL  A,#0FH
      XRL  A,#0FH
      JZ  NOKEY5
      MOV  A,P1
      ANL  A,#0FH
      CJNE  A,#0EH,KB18
      MOV  KEYBUF,#16
      LJMP  KEYWORK
KB18:  CJNE  A,#0DH,KB19
      MOV  KEYBUF,#17
      LJMP  KEYWORK
KB19:  CJNE  A,#0BH,KB20
      MOV  KEYBUF,#18
      LJMP  KEYWORK
KB20:  CJNE  A,#07H,KB21
      MOV  KEYBUF,#19
      LJMP  KEYWORK
KB21:  NOP
;
NOKEY5: LJMP  MAIN
;
KEYWORK:MOV  A,KEYBUF  ;得到键值
       MOV   DPTR,#TABLE
       MOVC  A,@A+DPTR  ;查行键值送ACC
       MOV  P0,A
;
WAITFREE:
      MOV  A,P1   ;以下程序等待键释放
      MOV  KEYBUF,#00H
      ANL  A,#0FH
      XRL  A,#0FH
      JNZ  WAITFREE
      RET
;
;*************************************
;*                                   *
;*          延时513 us              *
;*                                   *
;*************************************
;
;513微秒延时程序
DELAY: MOV   R2,#0FEH
DELAY1: DJNZ    R2,DELAY1
   RET
;
;*************************************
;*                                   *
;*             延时10ms             *
;*                                   *
;*************************************
;
;10毫秒延时程序
DL10MS: MOV     R3,#14H
DL10MS1:LCALL   DELAY
        DJNZ    R3,DL10MS1
       RET
;
TABLE:                           ;七段显示器数据定义
DB  0C0H, 0F9H, 0A4H, 0B0H, 99H ; 01234
      DB  92H,  82H,  0F8H, 80H,  90H ; 56789
      DB  88H,  83H,  0C6H,  0A1H, 86H; ABCDE
      DB  8EH             ; F
;
      END                ;程序结束
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

6
 
KEYBUF EQU 30H
            ORG 00H
START:      MOV KEYBUF,#2
WAIT:   
            MOV P3,#0FFH
            CLR P3.4
            MOV A,P3
            ANL A,#0FH  
            XRL A,#0FH
            JZ NOKEY1
            LCALL DELY10MS
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY1
            MOV A,P3
            ANL A,#0FH
            CJNE A,#0EH,NK1
            MOV KEYBUF,#0
            LJMP DK1
NK1:        CJNE A,#0DH,NK2
            MOV KEYBUF,#1
            LJMP DK1
NK2:        CJNE A,#0BH,NK3
            MOV KEYBUF,#2
            LJMP DK1
NK3:        CJNE A,#07H,NK4
            MOV KEYBUF,#3
            LJMP DK1
NK4:        NOP
DK1:   
            MOV A,KEYBUF
            MOV DPTR,#TABLE
            MOVC A,@A+DPTR
            MOV P0,ADK1A:       MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JNZ DK1A
NOKEY1:
            MOV P3,#0FFH
            CLR P3.5
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY2
            LCALL DELY10MS
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY2
            MOV A,P3
            ANL A,#0FH
            CJNE A,#0EH,NK5
            MOV KEYBUF,#4
            LJMP DK2
NK5:        CJNE A,#0DH,NK6
            MOV KEYBUF,#5
            LJMP DK2
NK6:        CJNE A,#0BH,NK7
            MOV KEYBUF,#6
            LJMP DK2
NK7:        CJNE A,#07H,NK8
            MOV KEYBUF,#7
            LJMP DK2
NK8:        NOP
DK2:   
            MOV A,KEYBUF
            MOV DPTR,#TABLE
            MOVC A,@A+DPTR
            MOV P0,A
DK2A:       MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JNZ DK2A
NOKEY2:
            MOV P3,#0FFH
            CLR P3.6
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY3
            LCALL DELY10MS
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY3
            MOV A,P3
            ANL A,#0FH
            CJNE A,#0EH,NK9
            MOV KEYBUF,#8
            LJMP DK3
NK9:        CJNE A,#0DH,NK10
            MOV KEYBUF,#9
            LJMP DK3
NK10:       CJNE A,#0BH,NK11
            MOV KEYBUF,#10
            LJMP DK3
NK11:       CJNE A,#07H,NK12
            MOV KEYBUF,#11
            LJMP DK3
NK12:       NOP
DK3:
            MOV A,KEYBUF
            MOV DPTR,#TABLE
            MOVC A,@A+DPTR
            MOV P0,A
DK3A:       MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JNZ DK3A
NOKEY3:
            MOV P3,#0FFH
            CLR P3.7
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY4
            LCALL DELY10MS
            MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JZ NOKEY4
            MOV A,P3
            ANL A,#0FH
            CJNE A,#0EH,NK13
            MOV KEYBUF,#12
            LJMP DK4
NK13:       CJNE A,#0DH,NK14
            MOV KEYBUF,#13
            LJMP DK4
NK14:       CJNE A,#0BH,NK15
            MOV KEYBUF,#14
            LJMP DK4
NK15:       CJNE A,#07H,NK16
            MOV KEYBUF,#15
            LJMP DK4
NK16:       NOP
DK4:   
            MOV A,KEYBUF
            MOV DPTR,#TABLE
            MOVC A,@A+DPTR
            MOV P0,A
DK4A:       MOV A,P3
            ANL A,#0FH
            XRL A,#0FH
            JNZ DK4A
NOKEY4:
            LJMP WAIT
DELY10MS:
            MOV R6,#10
D1:         MOV R7,#248
            DJNZ R7,$
            DJNZ R6,D1
            RET
TABLE:      DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H
            DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H
            END
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

7
 
MOV R3,#F7H            ; 扫描初始值
MOV R1,#00H            ; 取码指标
SCAN1: MOV A,R3               ; 开始扫描
MOV P1,A               ; 将扫描值输出到 P1
MOV A,P1               ; 读入 P1 判断是否有按下
MOV R4,A               ; 存到 R4, 判断是否放开
SETB C                 ; C=1
MOV R5,#04H            ; 扫描 P14~P17
L1: RLC A                  ; 将按键值左移一位元
JNC KEYIN              ; 若 C=0, 有按, 执行 KEYIN
INC R1                 ; 将指标值加 1, 继续扫描下一行
DJNZ R5,L1 &
nbsp;         ; 扫描四行
MOV A,R3               ; 载入扫描值
SETB C                 ; C=1
RRC A                  ; 扫描下一列(P13~P10)
MOV R3,A               ; 存回扫描值
JC SCAN1               ; C=1, 尚未完成扫描
RET                    ; 结束键盘扫描, 回到 Main Program
KEYIN: MOV R7,#10             ; 消除弹跳
D2: MOV R6,#248
DJNZ R6,$
DJNZ R7,D2
D3: MOV A,P1               ; 读入 P1
XRL A,R4
JZ D3
MOV A,R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
Table:
   db   0c0h,0f9h,0a4h,0b0h,099h   ;0-4
   db   092h,082h,0f8h,080h,090h   ;5-9
   db   088h,083h,0a7h,0a1h,086h   ;A-E
   db   08eh               ;F
end
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

8
 
;-----------------------------------------------------
;反转法询键值子程序  (A)=键值顺序码
;先读取键盘的状态,得到按键的特征编码。
;根据按键的特征编码,查表得到按键的顺序编码。
;-----------------------------------------------------
KEY_IN:  
           MOV  P1,#0F0H         ;置列线为0,行线为1
           MOV  A,P1
           ANL  A,#0F0H
           MOV  B,A
           MOV  P1,#0FH          ;置列线为1,行线为0
           MOV  A,P1
           ANL  A,#0FH
           ORL  A,B              ;高四位与低四位重新组合
           CJNE  A,#0FFH,KEY_IN1     ;0FFH为末按键
           RET
KEY_IN1:  
           MOV  B,A
           MOV  DPTR,#KEYTABLE
           MOV  R3,#0FFH
KEY_IN2:   
           INC  R3
           MOV  A,R3
           MOVC  A,@A+DPTR
           CJNE  A,B,KEY_IN3
           MOV  A,R3             ;找到,取顺序码
           RET
KEY_IN3:  
           CJNE  A,#0FFH,KEY_IN2    ;末完,继续查
           RET                      ;0FFH为结束码
;特征编码与顺序编码的对应关系
KEYTABLE:      
    DB  0EEH,0EDH,0EBH,0E7H,0DEH     ;0,1,2,3,4,  顺序码
    DB  0DDH,0DBH,0D7H,0BEH,0BDH    ;5,6,7,8,9,
    DB  0BBH,0B7H,07EH,07DH,07BH     ;A,B,C,D,E,
    DB  077H,0FFH      ;F,   0FF为结束码
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

9
 
ADDR_KEY         EQU 8040H       ;键盘片选地址
KEY_TMP          EQU 70H         ;键值暂存单元
;********************************************
;键盘数码显示器测试程序
LEDDATA   EQU   P1.0    ;数码管显示 74LS164 的数据线
LEDCLK    EQU   P1.1    ;数码管显示 74LS164 的时钟线
LEDBUF1   EQU   30H     ;显示缓冲区,对应数码管L4
LEDBUF2   EQU  31H     ;显示缓冲区,对应数码管L3
LEDBUF3   EQU  32H     ;显示缓冲区,对应数码管L2
LEDBUF4   EQU  33H     ;显示缓冲区,对应数码管L1
;主程序***************************************************
ORG  0000H
    LJMP   MAIN
ORG  0030H
MAIN:  LCALL   CLEARDISP  ;清除显示器上的显示内容
start:  LCALL   KEY
    CJNE A,#0FFH,DISPA
     SJMP start
DISPA:  MOV     LEDBUF1 ,  A     ;显示"A中键代码"
        MOV     LEDBUF2 ,  #12H
  MOV     LEDBUF3 ,  #12H
        MOV     LEDBUF4 ,  #12H
     LCALL   DISPNUMBER     ;调用显示程序   
        AJMP    start
;子程序**************************************************
;清除显示器显示的内容
CLEARDISP:     
MOV     R0,#04H
CLEARDISP_0:   
MOV     A, #0FFH
       LCALL  SENDDATA
      DJNZ    R0,CLEARDISP_0   
   RET
;**********************************************************
;发送数据    :发送的数据在ACC中
SENDDATA:
PUSH   01H
     CPL   A
      MOV     R1 ,#08H
SENDDATA_0:   
CLR     C
      RRC   A   
      MOV   LEDDATA,   C     ;移位发送
       CLR     LEDCLK
       SETB    LEDCLK        
        DJNZ    R1,SENDDATA_0
       POP     01H         
       RET
;键盘行扫描程序*********************************************   
; (1) 功能:有键闭合,键值存在A中,否则A中存入无键闭合
;标志FFH
; (2) 入口参数:无;出口参数:Acc;
;使用寄存器:R2-R7, KEY_TMP, A, DPTR
KEY:  LCALL  KS1       ;检查是否有闭合键
    JNZ    LK1       ;有键合
     LJMP   MK8       ;无
LK1:   LCALL   DL10MS      ;消抖动
LCALL   DL10MS
     LCALL  KS1
     JNZ      LK2
    LJMP   MK8
LK2:    MOV   R3,   #00H  ;列计数器初值00H送R3
MOV   R2,   #0F7H            ;列扫描初值送R2
LK3:    MOV   A,     R2
       MOV   DPTR,  #ADDR_KEY
        MOVX  @DPTR,   A
        MOVX    A,     @DPTR
        ANL      A,    #0F0H
        CJNE    A,   #0F0H,   LK4
        INC     R3                       ;列计数器加1
        MOV    A,    R2                  ;修改列码
        JNB      ACC.0,   MK8            ;列扫描完成否?
       RR      A
        MOV    R2,    A            
      SJMP       LK3
LK4:    JB      ACC.7,    LK5
             MOV    A,     #00H
             ADD    A,     R3
             SJMP      LK9  
LK5:     JB     ACC.6,    LK6
             MOV     A,     #04H
             ADD      A,    R3
              SJMP     LK9
      LK6:      JB     ACC.5,    LK7
              MOV    A,    #08H
              ADD     A,      R3
              SJMP       LK9
      LK7:       JB    ACC.4,     MK8
               MOV     A,      #0CH
              ADD     A,      R3
              SJMP    LK9
      LK9:     MOV    KEY_TMP,    A      ;暂存键值
      LK10:   LCALL     KS1
            JZ        LK11   
             LCALL    DL10MS    ;调用延时
             SJMP      LK10
      LK11:   MOV      A,     KEY_TMP
             SJMP      LK12
      MK8:    MOV     A,     #0FFH
      LK12:    RET
      KS1:   MOV DPTR,#ADDR_KEY  ;键盘接口地址
    MOV    A,#0F0H              ;D3~D0送0000
    MOVX  @DPTR,A               ;列全0送出
            MOVX A,@DPTR             ;读行信息
          ANL    A,#0F0H             ;屏蔽低4位
            ORL    A,#0FH            ; 底4位置1            
            CPL    A                 ;产生A=0为无键按下特征
            RET
;**********************************************************
;显示缓冲区的数字
DISPNUMBER:     MOV    R0,   #LEDBUF1
                               MOV    R1,   #04H
DISPNUMBER_0: MOV     A,    @R0
              MOV  DPTR,   #TABLE   
              MOVC  A,  @A+DPTR  ;得到数字的字型码
                         LCALL   SENDDATA
                         INC R0
                         DJNZ    R1 , DISPNUMBER_0
                             RET
;***************************************************
;延时程序
DL10MS: MOV   R5,  #100
DELAY1: MOV   R6,  #100
       DJNZ   R6,  $
     DJNZ    R5, DELAY1
            
RET
;**********************************************************
;串行显示码格式:|e       |d       |c      |dp     |b       |a          |f        |g
;                 7        6        5       4       3        2           1         0
TABLE: DB      011H         ;0的显示码
DB      0D7H         ;1的显示码
DB      032H         ;2的显示码
DB      092H         ;3的显示码
DB      0D4H          ;4的显示码
DB      098H          ;5的显示码
DB      018H          ;6的显示码
DB      0D3H         ;7的显示码
DB      010H          ;8的显示码
DB      090H          ;9的显示码
        DB      050H          ;A的显示码
        DB      01CH          ;B的显示码
        DB      039H         ;C的显示码
        DB      016H         ;D的显示码
        DB      038H          ;E的显示码
        DB      078H          ;F的显示码
        DB      0FEH         ;-的显示码
        DB      070H          ;P的显示码
        DB      0FFH         ;全熄的显示码
      END
此帖出自单片机论坛
 
 
 

回复

633

帖子

0

TA的资源

裸片初长成(中级)

10
 
KEY: LCALL KS                           ;调用检测按键子程序
     JNZ K1                             ;有键按下继续
     LCALL DELAY2                       ;无键按下调用延时去抖动程序
     AJMP KEY                           ;返回继续检测有无按键按下
K1:  LCALL DELAY2
     LCALL DELAY2                       ;有键按下继续延时去抖动
     LCALL KS                           ;再一次调用检测按键程序
     JNZ K2                             ;确认有按下进行下一步
     AJMP KEY                           ;无键按下返回继续检测
K2: MOV R2,#0EFH                    ;将扫描值送入 R2暂存
     MOV R4,#00H                        ;将第一列的列值00H送入R4暂存,R4用于存放列值。
K3: MOV P1,R2                       ;将R2的值送入P1口
L6: JB P1.0,L1                      ;P1.0等于1跳转到L1
     MOV A,#00H                         ;将第一行的行值00H送入ACC
     AJMP LK                            ;跳转到键值处理程序
L1: JB P1.1,L2                      ;P1.1等于1跳转到L2
     MOV A,#04H                         ;将第二行的行值送入ACC
     AJMP LK                            ;跳转到键值理程序进行键值处理
L2: JB P1.2,L3                          ;P1.2等于1跳转到L3
     MOV A,#08H                         ;将第三行的行值送入ACC
     AJMP LK                            ;跳转到键值处理程序
L3: JB P1.3,NEXT                    ;P1.3等于1跳转到NEXT处
     MOV A,#0cH                         ;将第四行的行值送入ACC
LK: ADD A,R4                        ;行值与列值相加后的键值送入A
     PUSH ACC                           ;将A中的值送入堆栈暂存
K4:  LCALL DELAY2                       ;调用延时去抖动程序
     LCALL KS                           ;调用按键检测程序
     JNZ K4                             ;按键没有松开继续返回检测
     POP ACC                            ;将堆栈的值送入ACC
     RET
NEXT:
    INC  R4                             ;将列值加一
    MOV A,R2                            ;将R2的值送入A
    JNB ACC.7,KEY                       ;扫描完成跳至KEY处进行下一回合的扫描
    RL A                                ;扫描未完成将A中的值右移一位进行下一列的扫描
    MOV R2,A                            ;将ACC的值送入R2暂存
    AJMP K3                             ;跳转到K3继续
KS: MOV P1,#0FH                     ;将P1口高四位置0低四位值1
     MOV A,P1                           ;读P1口
     XRL A,#0FH                         ;将A中的值与A中的值相异或
     RET                                ;子程序返回
DELAY2:                                 ;40ms延时去抖动子程序8*FA*2=40ms
      MOV R5,#08H
L7: MOV R6,#0FAH
L8: DJNZ R6,L8
     DJNZ R5,L7
     RET
此帖出自单片机论坛
 
 
 

回复

23

帖子

0

TA的资源

一粒金砂(高级)

11
 
多多回帖,努力赚钱!!!!!!
此帖出自单片机论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

12
 
谢谢分享  == 内容很丰富啊
此帖出自单片机论坛
 
 
 

回复

28

帖子

0

TA的资源

一粒金砂(初级)

13
 
最好有真正实用的程序
此帖出自单片机论坛
 
 
 

回复

2734

帖子

0

TA的资源

裸片初长成(初级)

14
 
程序好长啊!
拿去看看,给楼主顶一个帖子,算是对于楼主给大家做贡献的一个

鼓励吧,嗯嗯,值得值得,希望楼主继续努力啊!加油
此帖出自单片机论坛
 
个人签名我爱电子!
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表