• 9.17键盘的操作


    键盘的应用和分类:

    键盘分为编码键盘和非编码键盘,键盘上闭合键的识别是由专门的硬件编码器实现,并产生键编码号或者是键值的成为编码键盘,如计算机的键盘

    靠软件编程来识别的称为非编码键盘;

    在单片机组成的各种系统中,用的最多的是非编码键盘,也有用到编码键盘的

    非编码键盘又有独立键盘和矩阵键盘。

     要先像键盘里面先写1;在读取操作

    示例代码:

    #include<reg52.h>
    #define uint unsigned int 
    #define uchar unsigned char
    
    sbit ld1 = P1^0;
    sbit key1 = P3^4;
    sbit dula = P2^6;
    sbit wela = P2^7;
    uchar num;
    uchar code table[]={0x3f,0x06,0x5b,0x4f,
                        0x66,0x6d,0x7d,0x07,
                        0x7f,0x6f,0x77,0x7c,
                        0x39,0x5e,0x79,0x71};
    void display(num);
    main()
    {
        P3 = 0xff;
        while(1)
        {
            display(num);
            if(key1==0)
            {
                ld1 = 0;
                num++;
                if(num==10)
                    num = 0;
                 while(key1!=1);//松手检测 
                
            }
            else 
                ld1 = 1;
        }
            
    }
    void display(num)
    {    
        wela  = 1;
        P0 = 0xfe;
        wela = 0;
    
        P0 = 0x0;
    
        dula = 1;
        P0 = table[num];
        dula = 0;
        
        dula = 1;//关灯操作
        P0 = 0x0;
        dula = 0;
    
        
    }
    View Code 
    

     这个程序看上去无懈可击,但是在实际过程中,有一个相当大打bug,那就是,你按住键盘的时候,数码管不显示数字,这不是很坑爹,所以,位选信号是开始就要打开的正确的代码是

    #include<reg52.h>
    #define uint unsigned int 
    #define uchar unsigned char
    
    sbit ld1 = P1^0;
    sbit key1 = P3^4;
    sbit dula = P2^6;
    sbit wela = P2^7;
    uchar num;
    uchar code table[]={0x3f,0x06,0x5b,0x4f,
    					0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,
    					0x39,0x5e,0x79,0x71};
    void display(num);
    main()
    {
    	P3 = 0xff;
    	wela = 1;
    	P0 = 0xfe;//打开位选线
    	wela = 0;
    
    	while(1)
    	{
    	
    		if(key1==0)
    		{
    			ld1 = 0;
    			num++;
    			if(num==10)
    				num = 0;
    			 while(key1!=1);//松手检测 
    			
    		}
    		else 
    			ld1 = 1;
    
    		dula = 1;
    		P0 = table[num];//在循环中不断送入段选 
    		dula = 0;
    	}
    		
    }
    

    去抖:由于按键接触的时候会出现抖动,所以,要进行去抖操作

    去抖有硬件消抖和软件消抖

    硬件消抖要用专门的硬件消抖电路,导致外部电路复杂,在单片机中用不着

    软件消抖,一般是延时5毫秒检测

    #include<reg52.h>
    #define uint unsigned int 
    #define uchar unsigned char
    
    sbit ld1 = P1^0;
    sbit key1 = P3^4;
    sbit dula = P2^6;
    sbit wela = P2^7;
    uchar num;
    uchar code table[]={0x3f,0x06,0x5b,0x4f,
    					0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,
    					0x39,0x5e,0x79,0x71};
    
    void delay(uint x);
    main()
    {
    	P3 = 0xff;
    	wela = 1;
    	P0 = 0xfe;//打开位选线
    	wela = 0;
    
    	while(1)
    	{
    	
    		if(key1==0)
    		{
    			delay(10);//延时十毫秒
    			if(key1 == 0)//确实按下去了
    			{	
    				ld1 = 0;
    				num++;
    				if(num==10)
    					num = 0;
    			 	while(key1!=1);//松手检测 
    			 	delay(10);		//检测是否松手
    				while(!key1);
    			}
    			
    		}
    		else 
    			ld1 = 1;
    
    		dula = 1;
    		P0 = table[num];//在循环中不断送入段选 
    		dula = 0;
    	}
    		
    }
    
    void delay(uint x)
    {
    	uint y,z;
    	for(y=x;y>0;y--)
    		for(z=110;z>0;z--);
    }
    

    矩阵键盘:无论是矩阵键盘还是独立键盘,单片机检测其是否被按下去的依据都是一样的,也就是检测该键盘对应的I/O口是否为低电平,独立键盘有一段固定是低电平,单片机写程序时检测比较方便,电路时矩阵键盘的两端都与单片机deI/O口相连,因此在检测时,先送入一列为低电平,其余的全部为高电平,此时我们确定了列数,然后立即轮流检测一次各行是否有低电平,检测到某一行为低电平(这是我们有确定了行数),着我们便可确定是哪一行哪一列的按键被按下去。

    示例代码:

    #include<reg52.h>
    sbit wela =P2^6;
    sbit dula = P2^7;
    #define uchar unsigned char
    #define uint unsigned int 
    
    void delay(uint z);
    uchar num,num1,temp;
    uchar keyscan();
    uchar code table[]={0x3f,0x06,0x5b,0x4f,
    					0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,
    					0x39,0x5e,0x79,0x71,0x0};
    					
    main()
    {
    	wela = 1;
    	P0 = 0x0;
    	wela = 0;
    	
    	while(1)
    	{
    		num1 = keyscan();
    		dula =1;
    		P0 = table[num1];
    		dula = 0;
    		}
    }
    
    void delay(uint z)
    {
    	uint x,y;
    	for(x=z;x>0;x--)
    		for(y=110;y>0;y--);	
    }
    
    
    uchar keyscan()
    {
    	P3 = 0xfe;//1111 1110
    		temp = P3;
    		temp = temp&0xf0;//11110000
    		while(temp!=0xf0)//如果有键摁下
    		{
    			delay(5);//再次检测P3口
    			temp = P3;
    			temp = temp&0xf0;
    			while(temp!=0xf0)
    			{
    				temp = P3;	
    				switch(temp)
    				{
    					case 0x7e:num = 1;
    						break;
    					case 0xbe:num = 2;
    						break;
    					case 0xde:num = 3;
    						break;
    					case 0xee:num = 4;
    						break;
    					
    				}
    				while(temp!=0xf0)//松手检测
    				{
    					temp = P3;
    					temp = temp&0xf0;
    				}
    			
    			}
    		}
    
    		
    		P3 = 0xfd;//1111 1101
    		temp = P3;
    		temp = temp&0xf0;//11110000
    		while(temp!=0xf0)//如果有键摁下
    		{
    			delay(5);//再次检测P3口
    			temp = P3;
    			temp = temp&0xf0;
    			while(temp!=0xf0)
    			{
    				temp = P3;	
    				switch(temp)
    				{
    					case 0x7d:num = 5;
    						break;
    					case 0xbd:num = 6;
    						break;
    					case 0xdd:num = 7;
    						break;
    					case 0xed:num = 8;
    						break;
    					
    				}
    				while(temp!=0xf0)//松手检测
    				{
    					temp = P3;
    					temp = temp&0xf0;
    				}
    		
    			}
    		}
    
    
    
    		P3 = 0xfb;//1111 1011
    		temp = P3;
    		temp = temp&0xf0;//11110000
    		while(temp!=0xf0)//如果有键摁下
    		{
    			delay(5);//再次检测P3口
    			temp = P3;
    			temp = temp&0xf0;
    			while(temp!=0xf0)
    			{
    				temp = P3;	
    				switch(temp)
    				{
    					case 0x7b:num = 9;
    						break;
    					case 0xbb:num = 10;
    						break;
    					case 0xdb:num = 11;
    						break;
    					case 0xeb:num = 12;
    						break;
    					
    				}
    				while(temp!=0xf0)//松手检测
    				{
    					temp = P3;
    					temp = temp&0xf0;
    				}
    	
    			}
    		}
    
    		P3 = 0xf7;//1111 0111
    		temp = P3;
    		temp = temp&0xf0;//11110000
    		while(temp!=0xf0)//如果有键摁下
    		{
    			delay(5);//再次检测P3口
    			temp = P3;
    			temp = temp&0xf0;
    			while(temp!=0xf0)
    			{
    				temp = P3;	
    				switch(temp)
    				{
    					case 0x77:num = 13;
    						break;
    					case 0xb7:num = 14;
    						break;
    					case 0xd7:num = 15;
    						break;
    					case 0xe7:num = 16;
    						break;
    					
    				}
    				while(temp!=0xf0)//松手检测
    				{
    					temp = P3;
    					temp = temp&0xf0;
    				}
    	
    			}
    		}
    		
    		return num;
    
    }
    

     按键操作的数字有规律,第一行为0xfe,那么其次的数是7bde,加上e,0x7e,0xbe,0xde,0xee

               第二行是0xfd,那么其次的数是7bde,加上d,0x7d,0xbd,0xdd,0xed

               第三行是0xfb,那么其次的数是7bde,加上b,0x7b,0xbb,0xdb,0xeb,

               第四行是0xf7,那么其次的数是7bde,加上7,0x77,0xb7,0xd7,,0xe7

    版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3327186.html

  • 相关阅读:
    自定义博客园样式
    Serilog 记录日志
    1 Python命令行参数(脚本神器)
    原创powershell脚本:通过远程桌面3389黑名单,阻止黑客ip
    在win中,给powershell客户端,搭建sshd服务器。
    分享我编写的powershell脚本:ssh-copy-id.ps1
    猪懂傻改之《powershell 代码规范》
    为啥没有操作系统托管的队列池?没有托管的账户?
    powershell脚本:你的文件已经被黑客篡改.ps1
    巧用linux版powershell,管理linux下docker的image,container
  • 原文地址:https://www.cnblogs.com/fengdashen/p/3327186.html
Copyright © 2020-2023  润新知