⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 读取键盘实验.txt

📁 这是一个读取键盘的程序与c51链接
💻 TXT
字号:

// 单片机键盘程序实验
  应该说键盘输入是单片机外部指令输入的重要途径,因此如何设计键盘以及键盘的工作原理、读键盘的方法、键盘的抗干扰设计等在单电能机系统设计中占有重要地位。这个例子在系统硬件的基础上设计了软件查询程序、软件延时程序(防止干扰),大致讲述了一种查询式键盘的工作原理与读取方式。  
 
; 这是读取键盘的子程序 
; 主要内容为:如何定义位,如何得到按键状态,防止键盘干扰的方法
; 以及如何处理读入的键值 
; 思路:首先在某一引脚输出一个电平,然后读入引脚的电平,如果刚好相反
; 那么可能有按键发生,但是不排除干扰,为了防止干扰,需要软件延时20ms
; 消除干扰,然后,等待用户释放,否则,可能重复的到某种结果,发生意外情况

;汇编语言
**************************************************

     led1 bit p1.0       ;LED 显示位定义
     led2 bit p1.1
     led3 bit p1.2
     led4 bit p1.3
     led5 bit p1.4
     led6 bit p1.5 
     led7 bit p1.6
     led8 bit p1.7 

     s1 bit p0.0        ;数码管位定义 
     s2 bit p0.1
     s3 bit p0.2
     s4 bit p0.3
     s5 bit p0.4 
     s6 bit p0.5
     s7 bit p0.6
     s8 bit p0.7
     
     led_data equ p2      ;数码管显示数据定义
     key1 bit p3.5       ;按键引脚定义
     key2 bit p3.6       ;
     key3 bit p3.7       ;
     key equ 46h        ;按键寄存单元

     org 00h 
     jmp main

     org 030h

   main:mov sp,#30h        ;首先定义
     lcall REST        ;初始化子程序
    lp:lcall pro_key       ;调用键盘查询子程序 
     lcall KEYPR        ;用来显示所查询到的键值 
     jmp lp          ;反复调用,不断查询
   REST:
     mov a,#00h
     mov b,#00h
     mov p0,#0
     mov p1,0ffh        ;
     mov p2,#0      
     mov key,#00h 
     mov p2,#255 
     clr beep 
    RET
   KEYPR:
     mov a,key         ;键值在累加器KEY中
     jz PROEND         ;如果 A= 0,表示没有按键,返回
     cjne a,#1,k1       ;A= 1 ,用户按了第一个键 
     mov a,#1          ;处理 A = 1的情况
     mov dptr,#tab_nu      ;查表
     movc a,@a+dptr
     mov led_data,a       ;显示 "1" 
     setb s1          ;在第一位 
     clr s2          ;其余两位不显示
     clr s3 
     jmp PROEND        ;处理完成,子程序返回 
                  ;以下分别处理KEY = 2,3 的情况
    k1:cjne a,#2,k2
     mov a,#2 
     mov dptr,#tab_nu
     movc a,@a+dptr
     mov led_data,a 
     clr s1
     setb s2 
     clr s3 
     jmp PROEND 
    k2:cjne a,#3, PROEND
     mov a,#3
     mov dptr,#tab_nu 
     movc a,@a+dptr
     mov led_data,a
     clr s1
     clr s2
     setb s3 
  PROEND:ret
  pro_key:             ;键盘查询子程序
      setb key1         ;首先输出高电平,检测低电平的到来
      setb key2         ;不同电路,可能检测方式不一样
      setb key3 
      jb key1,ke1       ;如果用户没有按第一个键,到第下个处理部分,
      mov key,#1        ;表示用户按了第一个键
      lcall delay20ms     ;软件延时,防止干扰
      jmp pro_key       ;重新查询,直到用户释放按键
    ke1:jb key2,ke2       ;处理第二个按键,如果没有到下一个处理部分
      mov key,#2        ;以下和第一个处理单元相似。
      lcall delay20ms
      jmp pro_key 
    ke2:jb key3,ke3  
      mov key,#3
      lcall delay20ms
      jmp pro_key
    ke3:ret
;************ 定时20 ms ************* 
delay20ms: push psw         ;保存原来的寄存器单元
      clr psw.3        ;设置新的寄存器 
      clr psw.4        ;
      mov r0,#2        ;延时参数1
      mov r1,#250       ;延时参数2 
      mov r2,#2        ;延时参数3
    dl1:djnz r0,dl1        ;延时循环1 
      mov r0,#250        ;重新设置循环数据 
    dl2:djnz r1,dl1        ;开始第二道循环
      mov r0,#240       ;
      mov r1,#248       ;
    dl3:djnz r2,dl1       ;第三道循环
      nop           ;修正定时精度 
      pop psw          ;恢复原来的寄存器组
      ret            ;返回 
;*********** end ******************* 

;这是数字显示表格,其中 带小数点的数字比不带小数点的数字大16
; 比如 0 的显示代码为 0;那么 0.的显示代码为 16;如此类推
tab_nu: 
    db 0c0h, 0f9h, 0a4h, 0b0h, 99h , 92h , 82h, 0f8h     ;数字0-7 不带小数点代码
    db 80h , 90h, 88h , 83h , 0c6h, 0a1h, 86h, 8eh      ;数字8-f 不带小数点代码
    db 40h , 79h, 24h , 30h , 19h , 12h , 02h, 78h      ;数字0-7 带小数点代码 
    db 00h , 10h, 08h , 03h , 46h , 21h , 06h, 0eh      ;数字8-f 带小数点代码 
    end             ;告诉编译器本程序到此结束,一定需要加上,否则编译通不过。 



;c语言
**************************************************

//按不同的按键,会显示不同的结果


#include <8051.h>

#define uchar unsigned char

#define key1  P3_4    //键盘定义
#define key2  P3_5
#define key3  P3_6

//****************************************************************************
void delay(uchar times);
void display(uchar disseg,uchar disdata);
uchar keyb();

// 这里定义的是数码管对应的字符字根

code uchar  disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
                        0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
                        0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
// ***************************************************************************
uchar keybuf;

void main()
{
    uchar keym =  0;   //键盘返回结果的缓冲区
    keybuf = 0;
    P1 = 255;          //关闭LED显示
    P0 = 0;            //关闭数码显示
    P2 = 255;          //

  while(1)             //设置一个无限制循环
 {      
        keym = keyb();           //得到按键结果
        if(keym) keybuf = keym;  //如果返回有效的按键结果才保存

        display(keybuf-1,keybuf);   //在相应的位置显示返回的结果
  }
}

//*****************************************************************************
//下面是延时程序。具体的延时时间不能通过表面程序看出,(为什么?)
//如果我们需要一个精密的延时程序,那么我们可以采用内嵌汇编代码的方式
void delay(uchar times)
{
    int t=100;           //延时倍数
    uchar i=times;   
    for(;i!=0;i--)
    {for(;t!=0;t--){}}
}


//这里是显示子程序,入口参数为
// disseg  -> 位选 可选范围 0-7 一共8个数码管
// disdata -> 段选 可选范围 0-31 一个32个字符
//  段选 0-15  16个字符 为 "0"->"F"
//  段选 16-31 16个字符 为 "0."->"F."

void display(uchar disseg,uchar disdata)
{
    uchar dataf;
   if(disseg < 8)          //只有当要显示的位数有效,才显示.否则,不显示
  {
     dataf = 1;
     while(disseg)
     {
         dataf <<= 1;
         disseg--;
      }
	       P0 = dataf;
         P2 = disbuf_u[disdata];
   }
   else{P0=0,P2=255;}  //关闭数码管显示
}

uchar keyb()
{
    uchar key,keytmp;

    key1 = 1;   //将输出线拉高
    key2 = 1;
    key3 = 1;

    key = P3 ;  //读回来
    key = key & 0xf0;           //获得键盘结果
    if(key == 112 ) return 0;   //如果用户没有按键返回 0  
    else
     { 
       keytmp = key;    
       delay(1);              //判断是不是干扰
       key = P3 & 0xf0;
       if (key != keytmp ) return 0;  //是干扰,返回 0
          else                        //不是干扰,等待用户释放按键
            {                
                  do{ 
                      key1 = 1;       //输出拉高
                      key2 = 1;
                      key3 = 1;
                    key = P3 & 0xf0;  //读回来
                    P1_0 = ~P1_0;     //如果用户不释放,闪烁 p1.0 
                   }while(key != 112 );   //等待用户释放 
                    P1_0 = 1;             //用户释放以后,清除p1.0指示灯
                   switch(keytmp)
                      {
                         case 96: return 3;//返回用户按键结果
                         case 80: return 2;
                         case 48: return 1;
                       }         
                  
             }

   
      }
    
    
}
//********************************************* 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -