单片机键盘实验_单片机矩阵键盘显示实验 - CSDN
  • 51单片机c语言4x4矩阵键盘实验详细操作
  • 51单片机开发板程序_4x4矩阵键盘实验C
  • 单片机AT89C51键盘扫描识别实验

    千次阅读 2015-07-15 09:49:49
    设计一个4X4的矩阵键盘键盘的号码0~15,要求编写出一个键盘输入扫描程序,要求单片机能根据键盘排列顺序,能将按下去键盘号正确识别出来,并采用两个数码管分别键盘号码的个位和十位。

          设计一个4X4的矩阵键盘,键盘的号码0~15,要求编写出一个键盘输入扫描程序,要求单片机能根据键盘排列顺序,能将按下去键盘号正确识别出来,并采用两个数码管分别键盘号码的个位和十位。

    实验参考电路图如下:


    参考代码:

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    sbit P14=P1^4;      
    sbit P15=P1^5;     
    sbit P16=P1^6;      
    sbit P17=P1^7;      
    unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};    //数字0~9的段码
    unsigned char keyval;  
     
    /**************************************************************
    函数功能:数码管动态扫描延时
    **************************************************************/
    void led_delay(void)     
     {
       unsigned char j;
    for(j=0;j<200;j++)
    ;
      }
    
    
    /**************************************************************
    函数功能:按键值的数码管显示子程序
    **************************************************************/
     void display(unsigned char k)
    {
       P2=0xbf;            
       P0=Tab[k/10];       
       led_delay();       
       P2=0x7f;            
       P0=Tab[k%10];      
    led_delay();         
     }
    
    
    /**************************************************************
    函数功能:软件延时子程序
    **************************************************************/
     void delay20ms(void)   
    {
       unsigned char i,j;
    for(i=0;i<100;i++)
    for(j=0;j<60;j++)
               ;
     }
    
    
    
    
    /**************************************************************
    函数功能:主函数
    **************************************************************/ 
     void main(void)
     {
       EA=1;                  
    ET0=1;                          
    TMOD=0x01;            
    TH0=(65536-500)/256;  
    TL0=(65536-500)%256;  
    TR0=1;                
    keyval=0x00;         
      
    while(1)               
    {
     display(keyval);  
    }
    
    
    }
    
    
    /**************************************************************
    函数功能:定时器0的中断服务子程序,进行键盘扫描,判断键位
    **************************************************************/ 
      void time0_interserve(void) interrupt 1 using 1   
      {
         TR0=0;                 
         P1=0xf0;                
     if((P1&0xf0)!=0xf0)      
        delay20ms();           
     if((P1&0xf0)!=0xf0)      
       {
          P1=0xfe;            
          if(P14==0)       
                 keyval=1;           
               if(P15==0)            
                 keyval=2;           
               if(P16==0)             
                 keyval=3;          
               if(P17==0)           
                 keyval=4;           
    
    
               P1=0xfd;             
         if(P14==0)       
                 keyval=5;         
               if(P15==0)         
                 keyval=6;       
               if(P16==0)     
                 keyval=7;        
               if(P17==0)    
                 keyval=8;  
    
               P1=0xfb;      
       if(P14==0)     
                 keyval=9;   
               if(P15==0)      
                 keyval=10;    
               if(P16==0)    
                 keyval=11;       
               if(P17==0)        
                 keyval=12;   
        
               P1=0xf7;     
       if(P14==0)         
                 keyval=13;          
               if(P15==0)           
                 keyval=14;         
               if(P16==0)         
                 keyval=15;        
               if(P17==0)          
                 keyval=16;        
           }
         TR0=1;                   
         TH0=(65536-500)/256;  
    TL0=(65536-500)%256;   
     }

    修改实验电路图和实验程序和设计电路,改成静态显示


    调试后的程序代码:

    #include<reg51.h>   //包含51单片机寄存器定义的头文件
    sbit P14=P1^4;      
    sbit P15=P1^5;     
    sbit P16=P1^6;      
    sbit P17=P1^7;      
    unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};    //数字0~9的段码
    unsigned char keyval;  
     
    /**************************************************************
    函数功能:数码管动态扫描延时
    **************************************************************/
    void led_delay(void)     
     {
       unsigned char j;
    for(j=0;j<200;j++)
    ;
      }
    
    
    /**************************************************************
    函数功能:按键值的数码管显示子程序
    **************************************************************/
     void display(unsigned char k)
    {
            
            
       //P2=0x3f;         ///   
    P0=Tab[k/10];  
         P3=Tab[k%10];      
        led_delay();         
     }
    
    
    
    
    /**************************************************************
    函数功能:软件延时子程序
    **************************************************************/
     void delay20ms(void)   
    {
       unsigned char i,j;
    for(i=0;i<100;i++)
    for(j=0;j<60;j++)
               ;
     }
    
    
    
    
    /**************************************************************
    函数功能:主函数
    **************************************************************/ 
     void main(void)
     {
       EA=1;                  
    ET0=1;                          
    TMOD=0x01;            
    TH0=(65536-500)/256;  
    TL0=(65536-500)%256;  
    TR0=1;                
    keyval=0x00;         
      
    while(1)               
    {
     display(keyval);  
    }
    
    
    }
    
    
    
    
    /**************************************************************
    函数功能:定时器0的中断服务子程序,进行键盘扫描,判断键位
    **************************************************************/ 
    
    
      void time0_interserve(void) interrupt 1 using 1   
      {
         TR0=0;                 
         P1=0xf0;                
     if((P1&0xf0)!=0xf0)      
        delay20ms();           
     if((P1&0xf0)!=0xf0)      
       {
          P1=0xfe;            
          if(P14==0)       
                 keyval=1;           
               if(P15==0)            
                 keyval=2;           
               if(P16==0)             
                 keyval=3;          
               if(P17==0)           
                 keyval=4;           
    
    
               P1=0xfd;             
         if(P14==0)       
                 keyval=5;         
               if(P15==0)         
                 keyval=6;       
               if(P16==0)     
                 keyval=7;        
               if(P17==0)    
                 keyval=8;  
    
               P1=0xfb;      
       if(P14==0)     
                 keyval=9;   
               if(P15==0)      
                 keyval=10;    
               if(P16==0)    
                 keyval=11;       
               if(P17==0)        
                 keyval=12;       
               P1=0xf7;     
       if(P14==0)         
                 keyval=13;          
               if(P15==0)           
                 keyval=14;         
               if(P16==0)         
                 keyval=15;        
               if(P17==0)          
                 keyval=16;        
           }
         TR0=1;                   
         TH0=(65536-500)/256;  
     TL0=(65536-500)%256;   
     }
    


    展开全文
  • 单片机】编码键盘实验

    千次阅读 2007-12-01 10:38:00
    实 验 报 告 第 页专业___软件学院___ 班级__4__ 学号__123012005158__ 实验日期: 2007 年 11 月 12 日 报告退发 (订正 、 重做) 课程 单片机程序设计 实验

    实 验 报 告

                                                

    专业___软件学院___  班级__4__  学号__123012005158__  

    实验日期:     2007    11    12       报告退发 (订正 重做)             

    课程       单片机程序设计         实验名称      编码键盘实验             

    一、实验目的

    掌握编码键盘的原理和使用方法

     

    二、实验环境

        PC,51,KC

     

    三、实验内容、步骤和结果分析

      编写键盘扫描程序,按下KEY1的时候LED显示1, 按下KEY2的时候LED显示2,……….

    程序如下:

           org 0000h

           ajmp main

           org 0013h

           ajmp intr1

    main:      mov a,#0ffh

           mov p1,a

           mov ie,#84h

           setb it1

           setb tr0        

            setb et0        

            setb ea

           mov p0,#00h

           mov p1,#0ffh

           ;mov p1,#0fh

           sjmp $

     

    intr1:       mov p1,#0fh

           mov a,p1 ;取出p1

           anl a,#0fh       ;屏蔽高四位

           jnb acc.0,k0    ;判断p1.0~p1.4中哪个键被按下

           jnb acc.1,k1

           jnb acc.2,k2

           jnb acc.3,k3

     

     

     

    exit: ;setb ea

           reti

    k0:   ;ajmp KEY0

           mov r3,#00h   ;0按下

           ajmp setrow    ;跳转到计算行号

    k1:   mov r3,#01h   ;1

           ajmp setrow

    k2:   mov r3,#02h   ;2

           ajmp setrow

    k3:   mov r3,#03h   ;3

           ajmp setrow

     

    setrow:   mov p1,#0f0h ;p1重新复制

           mov a,p1

           anl a,#0f0h     ;屏蔽低4

           jnb acc.4,row0       ;计算行号

           jnb acc.5,row1

           jnb acc.6,row2

           jnb acc.7,row3

          

    row0:      mov r4,#00h   ;0

           ajmp getr

    row1:      mov r4,#01h   ;1

           ajmp getr

    row2:      mov r4,#02h

           ajmp getr

    row3:      mov r4,#03h

           ajmp getr

     

    getr: mov a,#00h    ;计算键值

           mov a,r4

           rl a          ;4倍数计算

           rl a

           add a,r3   ;4*R4+R3

           mov r5,a

           cjne r5,#00h,key1;判断键值

           mov a,#02h    ;0,显示,下同

             mov p2,a

           mov a,#3fh

           mov p0,a

           ajmp exit

    key1:      cjne r5,#01h,key2

           mov a,#02h

             mov p2,a

           mov a,#06h

           mov p0,a

           ajmp exit

    key2:      cjne r5,#02h,key3

           mov a,#02h

             mov p2,a

           mov a,#5bh

           mov p0,a

           ajmp exit       

    key3:      cjne r5,#03h,key4

           mov a,#02h

             mov p2,a

           mov a,#4fh

           mov p0,a

           ajmp exit

    key4:      cjne r5,#04h,key5

           mov a,#02h

             mov p2,a

           mov a,#66h

           mov p0,a

           ajmp exit

    key5:      cjne r5,#05h,key6

           mov a,#02h

             mov p2,a

           mov a,#6dh

           mov p0,a

           ajmp exit

    key6:      cjne r5,#06h,key7

           mov a,#02h

             mov p2,a

           mov a,#7dh

           mov p0,a

           ajmp exit

    key7:      cjne r5,#07h,key8

           mov a,#02h

             mov p2,a

           mov a,#07h

           mov p0,a

           ajmp exit

    key8:      cjne r5,#08h,key9

           mov a,#02h

             mov p2,a

           mov a,#7fh

           mov p0,a

           ajmp exit

    key9:      cjne r5,#09h,key10

           mov a,#02h

             mov p2,a

           mov a,#6fh

           mov p0,a

           ajmp exit

    key10:     cjne r5,#0ah,key11

           mov a,#02h

             mov p2,a

           mov a,#77h

           mov p0,a

           ajmp exit

    key11:     cjne r5,#0bh,key12

           mov a,#02h

             mov p2,a

           mov a,#7ch

           mov p0,a

           ajmp exit

    key12:     cjne r5,#0ch,key13

           mov a,#02h

             mov p2,a

           mov a,#39h

           mov p0,a

           ajmp exit

    key13:     cjne r5,#0dh,key14

           mov a,#02h

             mov p2,a

           mov a,#5eh

           mov p0,a

           ajmp exit

    key14:     cjne r5,#0eh,key15

           mov a,#02h

             mov p2,a

           mov a,#79h

           mov p0,a

           ajmp exit

    key15:    

           mov a,#02h

             mov p2,a

           mov a,#71h

           mov p0,a

           ajmp exit

           end

     

        实验成功,能在51板上通过按键让电子数码管进行显示相应的数字

    四、讨论

    本次实验主要了解了在51板上的工作原理,在对其电路图进行了一定的了解之后使程序编写显得比较明了.起先实现了每一列可以按键,但是不懂如何进行移位来判断,这个问题思考了很久,后来通过对p0端口赋不同的值,取出各自的数字并进行计算才得以实现.

    本实验完成,了解了键盘的外部中断的工作原理.

     

     

     

     

     
    展开全文
  • 实验五 矩阵键盘 一、实验目的 1、掌握矩阵键盘的硬件电路原理和软件编程方法;2、掌握利用数码管显示矩阵键盘键值的编程方法。二、实验说明 本实验提供了一个4X4小键盘,开始先将4行置一,4列置零,判断是否有键...

    实验五 矩阵键盘

    一、实验目的

    1、掌握矩阵键盘的硬件电路原理和软件编程方法;
    2、掌握利用数码管显示矩阵键盘键值的编程方法。
    二、实验说明

    本实验提供了一个4X4小键盘,开始先将4行置一,4列置零,判断是否有键按下,如果有键按下,则逐列判断。键值判断方法:行*4+列,在有键按下后,要有一定的延时,防止键盘抖动。

    三、实验内容及步骤
    内容:
    程序功能按下矩阵键盘单元键盘,静态显示单元数码管显示对应数字。
    步骤:
    1、根据硬件连接电路,编写程序并编译生成*.hex文件;
    2、打开实验箱电源;
    3、参照STC12C5A60S2下载说明中STC_ISP软件使用说明,向单片机中下载程序;
    4、通过排线,将单片机最小系统单元的P2口的0-7与矩阵键盘单元的J0701的0-7一一对应相,通过信号线将单片机最小系统单元的P1.0、P1.1、P1.2分别与静态显示单元的SER、SRCLK、RCLK相连;
    5、打开静态显示单元开关;
    6、观察静态显示单元的LED1106数码管显示情况,若显示结果不正确,请修改该程序,重复以上操作。

      1 DAT BIT P1.0
      2   SRCLK BIT P1.1
      3   RCLK BIT P1.2
      4   ORG 00H
      5 LJMP MAIN
      6 ORG 0080H
      7 MAIN:
      8  MOV SP,#50H
      9  MOV 30H,#10H ;键值存放在30H单元中 
     10 SLOOP:
     11  ACALL JTXS     
     12  ACALL DELAY
     13  ACALL KEYSCAN
     14  SJMP SLOOP
     15 KEYSCAN:
     16   MOV R0,#00H
     17 LOOP:
     18   MOV P2,#0F0H ;将列清零 
     19   MOV A,P2
     20   CJNE A,#0F0H,KEY1     ;判断是否有键按下 
     21   LJMP  LOOP
     22 KEY1:
     23   ACALL DELAY      ;延时去抖动 
     24   MOV P2,#0F0H
     25   NOP
     26   NOP
     27   MOV A,P2
     28   CJNE A,#0F0H,KEY2       ;判断键值 
     29   LJMP  LOOP
     30 KEY2:
     31   MOV 31H,#0FEH    ;将第一列置一 
     32   MOV A,31H
     33 HANG:
     34   MOV P2,A
     35   MOV 31H,A
     36   MOV B,R0    ;代表第几行 
     37   ACALL LIE
     38   INC R0
     39   MOV A,31H
     40   RL A
     41   CJNE R0,#04H,HANG
     42   RET
     43 LIE:  ;判断列值 
     44   MOV A,P2
     45   ANL A,#0F0H
     46   CJNE A,#0E0H,K2
     47   MOV 32H,#00  ;第一列 
     48   SJMP JIE
     49 K2:
     50   CJNE A,#0D0H,K3
     51   MOV 32H,#01     ;第二列 
     52   SJMP JIE
     53 K3:
     54   CJNE A,#0B0H,K4
     55   MOV 32H,#02      ;第三列 
     56   SJMP JIE  
     57 K4:
     58   CJNE A,#70H,LEND
     59   MOV 32H,#03
     60   SJMP JIE            ;第四列 
     61 JIE:
     62   MOV A,#04H   ;行*4+列 
     63   MUL AB
     64   MOV B,32H
     65   ADD A,B
     66   MOV 30H,A
     67 LEND:
     68   RET
     69   ;静态显示 
     70 JTXS:
     71   MOV 31H,#10H
     72   MOV 32H,#10H 
     73   MOV 33H,#10H
     74   MOV 34H,#10H
     75   MOV 35H,#10H
     76 CHANGE:
     77   MOV R2,#06H
     78   MOV DPTR,#TABLE
     79   MOV R0,#30H
     80   MOV R1,#40H
     81 LOOP3:
     82   MOV A,@R0
     83   MOVC A,@A+DPTR
     84   MOV @R1,A
     85   INC R0
     86   INC R1
     87   DJNZ R2,LOOP3
     88 ZYXS:
     89   MOV R2,#06H
     90   MOV R1,#08H
     91   MOV R0,#40H
     92 LOOP2:
     93   MOV A,@R0
     94   MOV R1,#08H
     95 LOOP1:
     96   CLR SRCLK
     97   RLC A 
     98   MOV DAT,C
     99   NOP;
    100   SETB SRCLK
    101   DJNZ R1,LOOP1
    102   INC R0
    103   DJNZ R2,LOOP2
    104   CLR RCLK
    105   NOP;
    106   NOP;
    107   NOP;
    108   SETB RCLK
    109   RET
    110 TABLE:
    111   DB 3FH,06H,5BH,4FH,66H,6DH
    112   DB 7DH,07H,7FH,6FH,77H,7CH
    113   DB 39H,5EH,79H,71H,00H
    114 DELAY:
    115   MOV R1,#20H
    116 DELAY1:
    117   MOV R2,#00H
    118 DELAY2:
    119   DJNZ R2,DELAY2
    120   DJNZ R1,DELAY1
    121   RET
    122   END
    汇编写法

     

     1 #include <reg51.h>
     2 #include <intrins.h>
     3 unsigned char buf1[6] = { 16,16,16,16,16,16 };
     4 unsigned char buf2[6];
     5 unsigned char code table[] = { 0x3F,0x06,0x5B,0x4F,
     6                                0x66,0x6D,0x7D,0x07,
     7                                0x7F,0x6F,0x77,0x7C,
     8                                0x39,0x5E,0x79,0x71,
     9                                0x00 };
    10 sbit ser = P1 ^ 0 ;
    11 sbit srclk = P1 ^ 1 ;
    12 sbit rclk = P1 ^ 2;
    13 void main( void ){
    14     unsigned char i,j,temp1, temp2;
    15     unsigned char row,k,l,keyvalue = 0x10;
    16     TMOD = 0x01 ; 
    17     TH0 = 0xCA;
    18     TL0 = 0x0B;
    19     TR0 = 0 ;
    20     TF0 = 0 ;
    21     while ( 1 ) {
    22          P2 = 0xF0;
    23         if( P2 != 0xF0 ){
    24              TMOD = 0x01 ;
    25             TH0 = 0xCA;
    26             TL0 = 0x0B;
    27             TF0 = 0 ;
    28             TR0 = 1 ;
    29             while ( TF0 == 0 );
    30             TF0 = 0 ;
    31             TR0 = 0 ;    //延迟 15ms 左右,关闭定时器
    32             if( P2!= 0xF0 )
    33             {
    34                 k = 0xFE;
    35                 row = 0;
    36                 for ( l = 0 ; l < 4 ; l++ )
    37                 {
    38                      P2 = k ; 
    39                     if( ( P2 & 0xF0 ) == 0xE0 ) {
    40                          keyvalue = row * 4 + 0 ; 
    41                     }else if ( (P2&0xF0) == 0xD0 ) {
    42                          keyvalue = row * 4 + 1 ;
    43                     }else if ( (P2&0xF0) == 0xB0 ) {
    44                          keyvalue = row * 4 + 2 ;
    45                     }else if ( (P2&0xF0) == 0x70 ) {
    46                          keyvalue = row * 4 + 3 ;
    47                     }else {
    48                          row ++ ;
    49                         k = _crol_( k ,1  ) ;
    50                         keyvalue = 16;
    51                     }
    52                     buf1[ 0 ] = keyvalue ;
    53                     if( keyvalue != 16 ) 
    54                     {
    55                         P2 = 0xF0;
    56                         while(P2!=0xf0);
    57                          break;
    58                     }
    59                 }
    60                     
    61             }    
    62         }
    63         srclk = 0 ;
    64         rclk = 0 ;
    65         for ( i = 0 ; i < 6; i++ ) {
    66              buf2[i] = table[buf1[i]];
    67             temp1 = buf2[i];
    68             for( j = 0 ; j < 8 ; j++ ){
    69                  srclk = 0;
    70                 temp2 = ( temp1 & 0x80 );
    71                 if( temp2 ) {
    72                      ser = 1 ;
    73                 }else {
    74                      ser = 0 ;
    75                 }
    76                 srclk = 1 ;
    77                 _nop_();
    78                 temp1 <<= 1 ;
    79                 srclk = 0 ;
    80 
    81             }
    82         }
    83         rclk = 1 ;
    84     }
    85     return ;
    86 }    
    逐列排除法

     

     1 #include <reg51.h>
     2 #include <intrins.h>
     3 unsigned char buf1[6] = { 16,16,16,16,16,16 };
     4 unsigned char buf2[6];
     5 unsigned char code table[] = { 0x3F,0x06,0x5B,0x4F,
     6                                0x66,0x6D,0x7D,0x07,
     7                                0x7F,0x6F,0x77,0x7C,
     8                                0x39,0x5E,0x79,0x71,
     9                                0x00 };
    10 sbit ser = P1 ^ 0 ;
    11 sbit srclk = P1 ^ 1 ;
    12 sbit rclk = P1 ^ 2;
    13 void main( void ){
    14     unsigned char i,j,temp1, temp2, temp ;
    15     unsigned char row,k,l,keyvalue = 0x10;
    16     TMOD = 0x01 ; 
    17     TH0 = 0xCA;
    18     TL0 = 0x0B;
    19     TR0 = 0 ;
    20     TF0 = 0 ;
    21     while ( 1 ) 
    22     
    23     {
    24          P2 = 0xF0;
    25         i=P2;
    26         if( i != 0xF0 ){
    27              TMOD = 0x01 ;
    28             TH0 = 0xCA;
    29             TL0 = 0x0B;
    30             TF0 = 0 ;
    31             TR0 = 1 ;
    32             while ( TF0 == 0 );
    33             TF0 = 0 ;
    34             TR0 = 0 ;    //延迟 15ms 左右,关闭定时器
    35             
    36             if( P2!= 0xF0 )
    37             {
    38                 temp1 = P2 ;
    39                 _nop_();
    40                 _nop_();
    41                 //_nop_();
    42                 P2 = 0x0F;
    43                 temp2 = P2 ;
    44 
    45                 temp = ( temp1 | temp2 );
    46                 
    47                 switch ( temp ) {
    48                      case 0xEE : keyvalue = 0 ; break ; 
    49                     case 0xDE : keyvalue = 1 ; break ;
    50                     case 0xBE : keyvalue = 2 ; break ;
    51                     case 0x7E : keyvalue = 3 ; break ;
    52                     
    53                     case 0xED : keyvalue = 4 ; break ; 
    54                     case 0xDD : keyvalue = 5 ; break ; 
    55                     case 0xBD : keyvalue = 6 ; break ; 
    56                     case 0x7D : keyvalue = 7 ; break ;
    57                 
    58                     case 0xEB : keyvalue = 8 ; break ; 
    59                     case 0xDB : keyvalue = 9 ; break ; 
    60                     case 0xBB : keyvalue = 10; break ; 
    61                     case 0x7B : keyvalue = 11; break ;
    62                     
    63                     case 0xE7 :    keyvalue = 12; break ;
    64                     case 0xD7 :    keyvalue = 13; break ;
    65                     case 0xB7 : keyvalue = 14; break ;
    66                     case 0x77 : keyvalue = 15; break ;
    67                     default : keyvalue = 16 ; 
    68                 }
    69                 buf1[0] = keyvalue;
    70                 P2 = 0xF0; 
    71                 while ( P2 != 0xF0 ) ;
    72             }
    73                 
    74         }
    75         srclk = 0 ;
    76         rclk = 0 ;
    77         for ( i = 0 ; i < 6; i++ ) {
    78              buf2[i] = table[buf1[i]];
    79             temp1 = buf2[i];
    80             for( j = 0 ; j < 8 ; j++ ){
    81                  srclk = 0;
    82                 temp2 = ( temp1 & 0x80 );
    83                 if( temp2 ) {
    84                      ser = 1 ;
    85                 }else {
    86                      ser = 0 ;
    87                 }
    88                 srclk = 1 ;
    89                 _nop_();
    90                 temp1 <<= 1 ;
    91                 srclk = 0 ;
    92 
    93             }
    94         }
    95         rclk = 1 ;
    96     }
    97     return ;
    98 }    
    行列置换法

     

    转载于:https://www.cnblogs.com/Osea/p/11047985.html

    展开全文
  • 按键实验: 目的:通过按键控制其他元器件

    按键实验
    目的:通过按键控制其他元器件
    实验一
    K1~K4控制LED移位
    这里写图片描述

        目的:按下独立按键K1~K4,可分别上下控制连接在P0,P2端口的LED移位显示。
    
    #include<reg51.h>//使用芯片的库函数
    #include<intrins.h>/*intrins.h,函数,C51单片机编程中,使用到空指令_nop_();字符循环移位指令_crol_等时使用。*/
    #define uint unsigned int//define宏定义
    #define uchar unsigned char
    
    void DelayMS(uint x)//延时函数,不同的芯片由于频率不同而不同
    {
        uchar i;
        while (x--)
            for (i = 0;i < 120;i++);
    }
    
    void Move_LED()//LED灯移动功能
    //P1,按键引脚;P0:左流水灯;P2:右流水灯;
    {
        if ((P1 & 0x10) == 0) P0 = _crol_(P0, 1);
        //左边流水灯向上移动
        else if ((P1 & 0x20) == 0) P0 = _cror_(P0, 1);
        //左边流水灯向下移动
        else if ((P1 & 0x40) == 0) P2 = _crol_(P2, 1);
        //右边流水灯向上移动
        else if ((P1 & 0x80) == 0) P2 = _cror_(P2, 1);
        //右边流水灯向下移动
    }

    实验二
    K1~K4按键状态显示:
    LED1,2和3,4,控制灯的亮灭不同。
    按下K1或K2时,LED1或2亮,松开熄灭。按下K3或K4后释放时,LED3或4 亮,再次按下并释放时熄灭。
    按键状态

    #include<reg51.h>
    #define uchar unsigned char
    #define uint unsigned int 
    
    sbit LED1 = P0 ^ 0;
    sbit LED2 = P0 ^ 1;
    sbit LED3 = P0 ^ 2;
    sbit LED4 = P0 ^ 3;
    
    sbit K1 = P1 ^ 0;
    sbit K2 = P1 ^ 1;
    sbit K3 = P1 ^ 2;
    sbit K4 = P1 ^ 3;
    
    void DelayMS(uint x)
    {
        uchar i;
        while (x--)
            for (i = 0;i < 120;i++);
    }
    
    void main()
    {
    
        P1 = 0xFF;
        P0 = 0xFF;
        while (1)
        {
            LED1 = K1;
            LED2 = K2;
            if (K3 == 0)
            {
                while (K3 == 0);
                LED3 = ~LED3;
    
            }
            if (K4 == 0)
            {
                while (K4 == 0);
                LED4 = ~ LED4;
            }
            DelayMS(10);
        }
    }
    
    void main()
    {
        P1 = 0xFF;
        P0 = 0xFF;
        while (1)
        {
            LED 1 = K1;
    //K1= 1,灯灭;K1 = 0,灯亮
    //LED1,2,由按键直接控制,按键状态即是灯的状态
    //LED3,4,由按键间接控制,按键第一次按下
    
            if (K3 == 0)//按下K3,K3=0
            {
                while (K3 == 0);
    //保持当时灯的状态,等待释放按键;释放按键后,执行下一条指令,即是相反状态
    
                LED3 = ~LED3;
    //实现灯的相反状态,两次按键状态切换
            }
            if (K4 == 0)
            {
                while (K4 == 0)
                    LED4 = ~LED4;
            }
            DelayMS(10);
        }
    }

    重点
    —while(1)和while(1);(有分号)—

        while(1){……}:是让单片机一直执行{……}中内容,**防止程序跑飞**,通常用于主程序主体,确保程序持续执行
        while(1);     :是一条指令,它让单片机停在这个位置,一般用来检测中断,只有cpu收到中断指令,才会跳出while(1),进入中断服务子程序;
        whlie(1)本质是死循环,while(1)中的指令会不断重复执行,除非有中断,while(1);可以看作while(1){//空指令},它执行的是空指令,
        *于是单片机就停在这行代码处*
    

    —按键的高低电平—
    按键的高低电平

        很明显:我们是高电平有效,未按下时,是高电平,为1;当K1=1时,灯是灭的;从P0,P1的引脚初始化也可以看出。
    

    实验三

    K1~K4分组控制LED
    实验内容:在得出键号后分别对LED执行4种不同的操作。
    K1~K4分组控制LED

    #include<reg51.h>
    #define uchar unsigned char
    #define uint unsigned char
    
    void DelayMS(uint x)
    {
        uchar t;
        while (--x)
            for (t = 0;t < 120;t++);
    }
    
    void main()
    {
        uchar k, t, Key_State;//定义变量,以及键盘
        P0 = 0xFF;//初始化P0,P1引脚
        P1 = 0xFF;
    
        while (1)
        {
            t = P1;     //记录P1 初值
            if (t!= 0xFF)//
            {
                DelayMS(10);
                if (t != P1) continue;//再次检查按键
                Key_State = -t >> 4;//取得4位按键值,
                //由模式XXXX1111(X中有一位为0,其他均为1)
                //变为模式0000XXXX(X中有一位为1,其他均为0)
                k = 0;
                //检查1所在的位置,累加获取按键号K
                while (Key_State != 0)
                {
                    k++;
                    Key_State >>= 1;
    
                }
                //根据按键号K进行4种处理
    
    //(当前情况是在循环体内,switch中的指令会多次判断并执行)
    switch (k)
            {
            case 1:if (P0 == 0x00) P0 = 0xFF;//1111 1111
                    P0 <<= 1;//P0左移一位 1111 1110 左移 
                    DelayMS(200);
                    break;
            case 2:P0 = 0xF0;break;//点亮【上面】4只
            case 3:P0 = 0x0F;break;//点亮【下面】4只
            //涉及知识点:共阴极还是阳极,以及引脚对应问题
            case 4:P0 = 0xFF;//关闭所有
            }
    
            }
        }
    }

    重点

    —引脚和值的对应关系(反序)—

    P0口的8个引脚被赋值成1111,1110,就是说只有P0^0口是低电平,其余都是高电平!8个引脚与0xfe的2进制分别对应!
        即是1111,1110的值对应P0的7,6,5,4,3,2,1,0号引脚,不同于我们数数时01234567从左到右的逻辑,这种现象在汇编语言和单片机里很常见
    

    —循环移位和移位(CF的作用有无)—

    循环移位:单片机中的移位运算不同于C语言中的移位之后补零,而是分情况进行大循环和小循环(即是微机原理中的不带进位CF的CRL和带进位CF的ROR 循环移位)常使用_crol_()和_cror_()函数完成。
    

    “`
    移位:>> 右移;<<左移

        本实验则是【未使用】循环移位。故在switch语句中进行
    
    case 1:if (P0 == 0x00) P0 = 0xFF;
    //若灯亮全灭
    P0 <<= 1;
    //(原来是ff 1111 1111 变 1111 1110,亮一个-》亮两个,3个,四个……八个,循环,全灭,也是逐个,从下到上移动。
    

    —共阳极和共阴极(灯该怎么亮?)—

        灯亮取决于高电平还是低电平,由共阳极和共阴极决定。
    共阳极:低电平0亮,(和电源形成电平差,点亮LED灯)
    共阴极:高电平1亮。
    

    后语
    认真做了按键实验,感觉单片机并不简单,需要自己好好努力,认真对待才行,各位大朋友,小朋友加油!(PS:markdown用的还有点无力,下次加油吧)

    展开全文
  • 51单片机入门 - 矩阵键盘行扫描实验

    千次阅读 2020-07-21 23:10:37
    关注【电子开发圈】微信公众号,一起学习吧!...电子DIY、Arduino、51单片机、STM32单片机、FPGA…… 电子百科、开发技术、职业经验、趣味知识、科技头条、设备拆机…… 点击链接,免费下载100G+电子设计学习资料! ...
  • 目的:利用“模块化单片机教学实验平台”,加深对单片机与矩阵键盘的接口电路设计以及程序设计的理解。 任务:1、学习独立式按键的查询识别方法。 2、非编码矩阵键盘的行反转法识别方法。 3、掌握键盘接口的基本...
  • AVR单片机 实验五 矩阵键盘扫描实验 1 实验目的 掌握矩阵式键盘扫描方法与定时器中断原理,以实现多键输入判别及4位数码管显示的应用。 2 实验内容 (1) 实现矩阵式键盘扫描。 (2) 设定定时中断,实现按键除抖动作,...
  • 一、矩阵键盘原理介绍 在之前的文章中,我们介绍过独立按键的使用,独立按键需要每个按键使用一个IO口进行读取,如果按键比较多,对IO资源的占用比较多。 ...
  • 单片机独立式按键实验实例的源代码。里面有具体的解释。
  • 矩阵键盘扫描实验报告

    千次阅读 2016-08-18 09:51:02
    实验名称:矩阵键盘实验一 实验目的:按下16个矩阵键盘依次在数码管上显示1-16的 平方。如按下第一个显示1,第二个显示4...
  • 一个51单片机键盘扫描程序,算法简单有效  发一个51单片机键盘扫描程序,算法简单有效   再给大家分享一个不错按键程序(来自ourdev) /****************************************  键盘_不采用...
  •    本系列共6篇文章,本文作为本系列的六篇文章,介绍实验六 :8255键盘与显示设计,本系列文章基于Dais-52PRO实验箱。 一、实验目的:    掌握8255外接键盘与数码管显示的设计 二、实验设备:    PC计算机一...
  • 独立键盘实验报告

    千次阅读 2016-08-18 09:50:16
    实验名称:独立按键实验实验目的:数码管前三位显示一个跑表,从000到999之间 以1%秒速度运行,当按下一个独立键盘时跑表 停止,松开手后跑表继续。用定时器设计表。 实验备注:按下按键时跑表是停止了,但只...
  • 单片机按键扫描实验

    2020-07-30 23:30:44
    基于单片机按键扫描实验程序,使用的是汇编语言,简单实用
  • 单片机键盘及显示器控制源程序 包括子函数 显示 初始化 //实验目的:熟悉MSSP通信协议。 //当按键RB0按下时,把6个连续的数据写入到6个连续的单元内 //写完成后数码管显示单个0,做为完成标志位 //当按键RB1按下后...
  • 实验键盘扫描显示实验(矩阵键盘) 一、实验要求 在上一个实验的基础上,利用实验仪提供的键盘扫描电路和显示电路,做一个扫描键盘和数码显示实验,把按键输入的键码在八位数码管上显示出来。 实验程序可分成三...
1 2 3 4 5 ... 20
收藏数 2,223
精华内容 889
关键字:

单片机键盘实验