单片机按键扫描_单片机 扫描按键 - CSDN
精华内容
参与话题
  • 单片机——按键扫描

    万次阅读 2018-08-30 11:42:08
    按键扫描,我想应该是比较简单的单片机应用了,但是有时候看起来简单的东西反而不好写。 本文拿大部分人觉得简单的按键扫描聊聊我工作至今对于软件结构的理解。嗯,对的,是结构,不是架构,暂时不敢提架构这个词。...

    按键扫描,我想应该是比较简单的单片机应用了,但是有时候看起来简单的东西反而不好写。

    本文拿大部分人觉得简单的按键扫描聊聊我工作至今对于软件结构的理解。嗯,对的,是结构,不是架构,暂时不敢提架构这个词。

    按键扫描,我当时入门的时候是看的郭天祥的51单片机入门的,视频里面讲的是循环扫描io引脚,一旦有电平变化就利用软件延时消抖,模拟延时就是让单片机空转,什么也不做,等待个几十毫秒之后再检测一次如果电平没有变化就认为按键按下。这种方法也能实现按键检测,好处是简单,缺点是占用太多的软件资源,CPU空转这一点我觉得挺不好的。

    下面说说我个人对于一个按键检测的代码理解。

    按键检测需要做什么事情呢?一个是按键按下的这个物理事件的检测,一个是按下时候的消抖。能想到这两个已经可以写一段代码来实现功能了。

     

    #define DEBOUNCE 10//延时消抖时间
    uint8 key_scan( uint8 keycur )
    {
    	static uint8 KeyLast = KEY_NULL; 	
    	static uint8 KeyCountdowm = 0; 	
    	uint8 keyret = KEY_NULL;   	    
    
    	if(  keycur != KEY_NULL )	//如果检测到按键按下,开始进行延时消抖			
    	{
    		if( KeyLast == keycur  || KEY_NULL == KeyLast)				
    		{
    			KeyCountdowm++;				
    		}
    	}
    	else
    	{
    		if( KeyCountdowm >= DEBOUNCE)//按键抬起
    		{
    			keyret = KeyLast;
    		}
    		else
    		{
    		        keyret = KEY_NULL;
    		}
    
    		KeyCountdowm = 0;
    	}
    	
    	KeyLast = keycur;//按键备份值更新
    
    	return keyret;
    }

    上面是一个简单的按键扫描函数,函数需要放置在一个10ms的定时函数里面,注意是定时函数不是定时中断函数,需要传递按键信息,这个信息可以是从通信函数获取的,也可以是直接读取IO端口获得,返回一个消抖过后的键值,键值不做逻辑判断。

     

    然后我们来聊聊这个消抖函数,这个消抖函数只实现了一个功能,按下消抖,那如果使用环境或者硬件设计缺陷,导致抬起的时候也有抖动呢?所以需要添加抬起消抖。

    下面对函数进行优化一下

     

    #define DEBOUNCE 10//延时消抖时间
    uint8 key_scan( uint8 keycur )
    {
    	static uint8 KeyLast = 0; 	
    	static uint8 KeyCountdowm = 0; 	
    	static uint8 KeyCountup = 0; 	
    	unsigned uint8 keyret = 0;   	  
    
    	keyret = KEY_NULL;
    	if(  keycur != KEY_NULL )				
    	{
    		if( KeyLast == keycur || KEY_NULL == KeyLast)			
    		{
    			KeyCountdowm++;			
    			KeyCountup = 0;
    		}
    	}
    	else
    	{
    		KeyCountup++;	
    
    		if( KeyCountup > 1 ) 
    		{
    			KeyCountup = 0;	
    
    			if( KeyCountdowm >= DEBOUNCE )
    			{
    				keyret = KeyLast;
    				KeyCountdowm = 0;
    			}
    		}
    	}
    	
    	KeyLast = keycur;	
    	return keyret;
    }

    添加了20ms的抬起消抖,这段代码添加了两个消抖检测,一个是在抬起的时候有20ms的消抖,一个是在按键按下过程的一个过程消抖。

    上面的代码实现的是抬起有效,那么如果需要做到按下有效呢?

    #define DEBOUNCE 10//延时消抖时间
    uint8 key_scan( uint8 keycur )
    {
    	static uint8 KeyLast = 0; 	
    	static uint8 KeyCountdowm = 0; 	
    	static uint8 KeyCountup = 0; 	
    	unsigned uint8 keyret = 0;   	  
    
    	keyret = KEY_NULL;
    	if(  keycur != KEY_NULL )				
    	{
    		if( KeyLast == keycur || KEY_NULL == KeyLast)			
    		{
    			KeyCountdowm++;			
    			KeyCountup = 0;
    			
    			if( KeyCountdowm >= DEBOUNCE )
    			{
    				keyret = KeyLast;
    			}
    		}
    	}
    	else
    	{
    		KeyCountup++;	
    
    		if( KeyCountup > 1 ) 
    		{
    			KeyCountup = 0;	
    			KeyCountdowm = 0;
    		}
    	}
    	
    	KeyLast = keycur;	
    	return keyret;
    }

    挪动按键的延时检测判断语句,在按下超过延时消抖时间的时候,返回按键按下值。

     

    然后一个简单按键检测函数就实现了,下面再给这个函数添加长按键判断和连续按键。

    #define DEBOUNCE 10//延时消抖时间
    #define LONGPRESS 100//长按键判断函数
    uint16 key_scan( uint8 keycur )
    {
    	static uint8 KeyLast = 0; 	
    	static uint8 KeyCountdowm = 0; 	
    	static uint8 KeyCountup = 0; 	
    	unsigned uint16 keyret = 0;   	  
    
    	keyret = KEY_NULL;
    	if(  keycur != KEY_NULL )				
    	{
    		if( KeyLast == keycur || KEY_NULL == KeyLast)			
    		{
    			KeyCountdowm++;			
    			KeyCountup = 0;
    			
    			if( KeyCountdowm >= DEBOUNCE && KeyCountdowm < LONGPRESS)//短按键判断
    			{
    				keyret = KeyLast;
    			}
    			else if( KeyCountdowm == LONGPRESS )//长按键判断				
    			{
    				keyret = KeyLast;	
    				keyret |= 0x0100;		
    			}
    			else if(KeyCountdowm > LONGPRESS+DEBOUNCE)//连续按键判断
    			{
    				KeyCountdowm -= DEBOUNCE;
    				keyret = KeyLast;	
    				keyret |= 0x0200;	
    			}
    		}
    	}
    	else
    	{
    		KeyCountup++;	
    
    		if( KeyCountup > 1 ) 
    		{
    			KeyCountup = 0;	
    			KeyCountdowm = 0;
    		}
    	}
    	
    	KeyLast = keycur;	
    	return keyret;
    }

     

    当有多个设备的时候,可以将静态局部变量修改为结构体指针的形式,如下

    type struct key
    {
    	uint8 Last;
    	uint8 CountDowm;
    	uint8 CountUp;
    }KEY_TYPE;
    
    #define DEBOUNCE 10//延时消抖时间
    #define LONGPRESS 100//长按键判断函数
    
    uint16 key_scan( KEY_TYPE *Key ,uint8 keycur)
    {	
    	unsigned uint16 keyret = 0;   	  
    
    	keyret = KEY_NULL;
    	if(  keycur != KEY_NULL )				
    	{
    		if( Key->Last == keycur || KEY_NULL == Key->Last)			
    		{
    			Key->CountDowm++;			
    			Key->CountUp = 0;
    			
    			if( Key->CountDowm >= DEBOUNCE && Key->CountDowm < LONGPRESS)//短按键判断
    			{
    				keyret = KeyLast;
    			}
    			else if( Key->CountDowm == LONGPRESS )//长按键判断				
    			{
    				keyret = Key->KeyLast;	
    				keyret |= 0x0100;		
    			}
    			else if(KeyCKey->CountDowmountdowm > LONGPRESS+DEBOUNCE)//连续按键判断
    			{
    				Key->CountDowm -= DEBOUNCE;
    				keyret = Key->KeyLast;	
    				keyret |= 0x0200;	
    			}
    		}
    	}
    	else
    	{
    		Key->CountUp++;	
    
    		if( Key->CountUp > 1 ) 
    		{
    			Key->CountUp = 0;	
    			Key->CountDowm = 0;
    		}
    	}
    	
    	Key->KeyLast = keycur;	
    	return keyret;
    }

     

    最后说说这个功能的实现,按键检测分为三个部分,一个是按键获取函数,一个是消抖,一个是按键筛选函数,先把代码贴上来。

    type struct key
    {
    	uint8 Last;
    	uint8 CountDowm;
    	uint8 CountUp;
    }KEY_TYPE;
    
    #define DEBOUNCE 10//延时消抖时间
    #define LONGPRESS 100//长按键判断函数
    /*
    * description: 按键消抖函数
    * intput:按键结构体,键值
    * output:键值
    * 
    */
    uint16 key_scan( KEY_TYPE *Key ,uint8 keycur)
    {
    	unsigned uint16 keyret = 0;   	  
    
    	keyret = KEY_NULL;
    	if(  keycur != KEY_NULL )				
    	{
    		if( Key->Last == keycur || KEY_NULL == Key->Last)			
    		{
    			Key->CountDowm++;			
    			Key->CountUp = 0;
    			
    			if( Key->CountDowm >= DEBOUNCE && Key->CountDowm < LONGPRESS)//短按键判断
    			{
    				keyret = KeyLast;
    			}
    			else if( Key->CountDowm == LONGPRESS )//长按键判断				
    			{
    				keyret = Key->KeyLast;	
    				keyret |= 0x0100;		
    			}
    			else if(KeyCKey->CountDowmountdowm > LONGPRESS+DEBOUNCE)//连续按键判断
    			{
    				Key->CountDowm -= DEBOUNCE;
    				keyret = Key->KeyLast;	
    				keyret |= 0x0200;	
    			}
    		}
    	}
    	else
    	{
    		Key->CountUp++;	
    
    		if( Key->CountUp > 1 ) 
    		{
    			Key->CountUp = 0;	
    			Key->CountDowm = 0;
    		}
    	}
    	
    	Key->KeyLast = keycur;	
    	return keyret;
    }
    
    /*
    * description: 获取按键的函数
    * intput:none
    * output:键值
    * 
    */
    uint8 GetKeyValue(void)
    {
    	uint8 ret=NULL;
    	/*
    	这个部分的代码需要自己实现,这里可以从通信函数如iic,spi获得键值,也可以从gpio端口获得键值
    	*/
    	return ret;
    }
    
    
    #define KEY_NULL 0
    #define KEY_UP 1
    #define KEY_DOWN 2
    #define KEY_ON 3
    #define KEY_UP_L 4
    #define KEY_DOEN_L 5
    #define KEY_ON_L 6
    /*
    * description: 筛选按键的函数,只筛选需要的键值
    * intput:键值
    * output:键值
    * 
    */
    uint8 GetKeyValue(uint8 key)
    {
    	uint8 ret=KEYNULL;
    	switch(key)
    	{
    		0x01:
    		{
    			ret = KEY_UP;
    		}
    			break;
    		0x0101:
    		{
    			ret = KEY_UP_L;
    		}
    			break;
    		default:
    			break;
    	}
    	
    	return ret;
    }
    
    

     

    函数的三个部分的按键获取函数部分需要自己去编写,不同的键值来源不同,我试过从IIC中读取键值,也试过从GPIO中读取键值。

    然后是消抖函数,消抖函数需要如果有多个按键来源的话需要定义多个结构体,如果只有一个键值来源可以替换成静态局部变量版的函数。

    分成三个部分的好处是,函数间各干各事情,互不影响,更容易读,我在接手别人的代码时候,如果涉及到按键部分出现问题的话,一般先问上一个维护的人做没做过程消抖,如果回答说有做,好的,接着问怎么做的,一般把对方的过程消抖搞懂了,基本就懂了按键这部分的代码。如果对方说没有做或者很茫然的看着我,好吧,我会直接把对方的这部分代码删掉,重写。

     

    写于2017年7月30日 一个没有空调的夏天

    深圳

    展开全文
  • 51单片机按键扫描

    2020-07-21 10:00:07
    比行列扫描简单点,代码更短,之需要一次数据反转(2次的数据输入输出)就可以定位按键
  • 单片机按键扫描实验

    2020-07-30 23:30:44
    基于单片机按键扫描实验程序,使用的是汇编语言,简单实用
  • 单片机按键扫描

    2019-10-02 15:14:48
    1 /*********************** 2 *检测是否有键按下 ... 5 *可以是矩阵键盘,直接接IO的键盘,亦可为ADC键盘,就算是USB键盘也行 6 * 7 ************************/ 8 uint8_t KeyScan(uint8_t *da) ...
      1 /***********************
      2 *检测是否有键按下
      3 *有返回1  键值 *da
      4 *没有返回0
      5 *可以是矩阵键盘,直接接IO的键盘,亦可为ADC键盘,就算是USB键盘也行
      6 *
      7 ************************/
      8 uint8_t KeyScan(uint8_t *da)
      9 {
     10     if(KEY1==0||KEY2==0||KEY3==0||KEY4==0)
     11     {
     12         if(KEY1==0)   *da=11;
     13         if(KEY2==0)   *da=12;
     14         if(KEY3==0)   *da=13;
     15         if(KEY4==0)   *da=14;
     16         
     17         return 1;
     18     }
     19     return 0;
     20     
     21 }
     22 /*****************************
     23 *扫描按键并返回按下时间
     24 *time = key_insure(&keyValue);
     25 *返回值  键按下的时间  
     26 **key_data 键值
     27 ***************************/
     28 uint16_t key_insure(uint8_t *key_data)
     29 {
     30     uint8_t error;
     31     static uint8_t tp=0,tp1=0,key,key_value=0;
     32     static uint16_t    cnt=0,cnt1=0;
     33     error = KeyScan(&key_value);
     34 
     35     if(tp==0)
     36     {
     37         if(error==1)//检测到第一次按下
     38         {
     39             tp =1;
     40             cnt = 0;/*若要判断长短按,cnt就是这参数,返回cnt就行*/
     41             cnt1 = 0;//
     42         }
     43     }
     44     else
     45     {
     46         if(error==0)
     47         {
     48             if(tp1==0)
     49             {
     50                 tp = 0;//开始新的扫描    
     51             }
     52             else
     53             {
     54 
     55                 if(cnt1<10000)
     56                 {
     57                     cnt1++;
     58                 }
     59             
     60                 if(cnt1>1)//持续松开,
     61                 {
     62                 
     63                     tp = 0;//重新开始扫描按下事件
     64 
     65                     if(key==key_value)
     66                     {
     67                         *key_data = key_value;
     68                         return cnt;
     69                     }
     70                     else 
     71                     {
     72                         return 0;                    
     73                     }
     74                 }
     75 
     76             }
     77         }    
     78         else
     79         {
     80             if(cnt<10000)
     81             {
     82                 cnt++;//
     83             }        
     84             if(cnt==1)//第一次采样   检测到第一次按下后 20ms
     85             {
     86                 key = key_value;
     87             }
     88             else if(cnt==2)//第二次采样  检测到第一次按下后 40ms
     89             {
     90                 if(key == key_value)
     91                 {
     92                     tp1 = 1;    
     93                 }
     94                 else
     95                 {
     96                     tp = 0;//重新开始扫描按下事件
     97                     return 0;
     98                 }
     99             }
    100 //            else if(cnt>3)//这里是支持长按连续输出键值的代码
    101 //            {
    102 //                tp = 0;//重新开始扫描按下事件
    103 //                cnt = 0;/*若要判断长短按,cnt就是这参数,返回cnt就行*/
    104 //                cnt1 = 0;//
    105 //                if(key==key_value)
    106 //                {
    107 //                    return 1;
    108 //                }
    109 //                else 
    110 //                {
    111 //                    return 0;                    
    112 //                }    
    113 //            }            
    114         }
    115     }
    116     return 0;
    117 }    

    转载于:https://www.cnblogs.com/0713tanic/p/6651141.html

    展开全文
  • STC单片机按键扫描程序

    千次阅读 2018-10-17 11:07:39
    STC单片机按键扫描程序 最近在做一个电子秤相关项目,使用STC系列单片机作为主控芯片,项目第一阶段直接使用IAP15W4K58S4驱动两个矩阵键盘,一切调试顺利,在项目即将结束时老板要求使用另一块单片机驱动矩阵键盘,...

    STC单片机按键扫描程序

    最近在做一个电子秤相关项目,使用STC系列单片机作为主控芯片,项目第一阶段直接使用IAP15W4K58S4驱动两个矩阵键盘,一切调试顺利,在项目即将结束时老板要求使用另一块单片机驱动矩阵键盘,读取键值后通过串口传回之前的IAP主控(理由是为了节省从矩阵键盘到主控板之间的长排线的成本,16P+10P);OK ,老板发话了,还能说什么呢,做呗,于是问题出现了。下面先简单介绍矩阵键盘的检测原理,然后说一说一些容易遇到的问题。

    1.先简单介绍下矩阵键盘的扫描原理

    对于N*M的矩阵键盘(N>=M),我们在编写程序的过程中,为提高扫描效率与降低程序的复杂程度,常设计N为列检测,M为行扫描,对应于程序上的检测输入与扫描输出。下图为矩阵键盘的示意图。

    矩阵键盘示意图

    检测原理:在上图示意键盘中,规定竖向为列,即是P10,P11,P12,P13为列检测;P14,P15,P16,P17为行扫描。没有按键按下是,列检测为到电平(一般为准双向IO,弱上拉),行扫描为低电平输出。当按键S5被按下后,P10与P15接通,P10由高电平变为低电平,单片机检测到P10-P13有任何一位被拉低时,认为有按键按下,此时程序应记录下哪一列按键被按下(得到按键的列坐标),然后按序拉高P14-P14,直到P10-P13全为初始状态(高电平),此时拉高的行即为被按下的按键的行坐标。例如:S5被按下后,P10为0,得到列坐标为1,当P15拉高后,P10-P14均为1,得到行坐标为2,最后得到按键坐标为2行1列--S5。其他按键检测原理相同。

    单片机驱动扫描按键原理很简单,但是在实际使用中对不同单片机的配置有要求,配置不当容易检测到错误的键值。一下简要说明几个容易遇到的问题。

    1.现在市面上的单片机IO基本都有4种标准模式(准双向IO、推挽输出、开漏输出、高阻输入)详解见:(https://blog.csdn.net/jbh18401/article/details/76048843)。一般列检测配置为准双向IO,但准双向IO的输出为弱上拉啊,拉电流弱,抗干扰性差,所以在列检测IO外部,应外加上拉电阻(10-100K),一确保按键的稳定性。

    2.在按键扫描的程序中,由于单片机程序执行速度快,在检测按键行坐标时,拉高对应行后应适当延时,等待IO端口稳定后再检测行输入是否改变(程序如下)。若不加入延时,会导致因IO还没来得及完全拉高,列检测程序已经执行完毕,最终导致按键动作检测不到或者误检。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 一个51单片机键盘扫描程序,算法简单有效  发一个51单片机键盘扫描程序,算法简单有效   再给大家分享一个不错按键程序(来自ourdev) /****************************************  键盘_不采用...
    一个51单片机的键盘扫描程序,算法简单有效 


    发一个51单片机的键盘扫描程序,算法简单有效 
                                          再给大家分享一个不错按键程序(来自ourdev)
    /**************************************** 


    键盘_不采用定时器_不延时 


    特点: 
    按键在松手后有效,灵敏度高,消耗资源少,运行效率高 


    独立键盘为:K01=P2^4;K02=P2^5;K03=P2^6;K04=P2^7; 
    矩阵键盘为:行(上到下)_P2.3_P2.2_P2.1_P2.0 
               列(左到右)_P2.7_P2.6_P2.5_P2.4 


    提供的操作函数: 


    //独立键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key 
    extern unsigned char keyboard_self(); 


    //矩阵键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key****检测高四位 
    extern unsigned char keyboard_matrix(); 


    ****************************************/


    .
     


    先看独立键盘(和矩阵键盘的算法一样) 
    ----------------------------------------------------------------------- 
    #include<reg52.h> 
    #include<intrins.h> 


    //独立键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key 
    extern unsigned char keyboard_self() 

            unsigned char num_key=0;//按键号 
            unsigned char temp=0;//用于读取P2线上按键值 
            static unsigned char temp_code=0;//保存按键值 
            static unsigned char num_check=0;//低电平有效次数 
            static unsigned char key_flag=0;//按键有效标识 


            temp=P2&0xF0;//读取P2线数据 


            if(temp!=0xF0)//低电平判断 
            { 
                    num_check++; 
                    if(num_check==10)//连续10次(10ms)低电平有效,则认为按键有效 
                    { 
                            key_flag=1;//使能按键有效标识 
                            temp_code=temp;//保存按键值 
                    } 
            } 
            else//松手时判断 
            { 
                    num_check=0; 


                    if(key_flag==1)//按键有效 
                    { 
                            key_flag=0; 


                            switch(temp_code)//读取按键号 
                            { 
                                    case 0xE0: num_key=1; 
                                               break; 
                                    case 0xD0: num_key=2; 
                                               break; 
                                    case 0xB0: num_key=3; 
                                               break; 
                                    case 0x70: num_key=4; 
                                               break; 
                            } 
                    } 
            } 


            return(num_key); 

     


    现在是矩阵键盘的 
    ----------------------------------------------------------------------- 
    #include<reg52.h> 
    #include<intrins.h>  


    //矩阵键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key****检测高四位 
    extern unsigned char keyboard_matrix() 

            unsigned char num_key=0;//按键号 
            unsigned char temp=0;//读取P2口线数据 
            static unsigned char temp_code=0;//用于保存按键值 
            static unsigned char temp_circle=0xFE;//保存P2线上的循环扫描值 
            static unsigned char num_check=0;//低电平计数 
            static unsigned char key_flag=0;//按键有效标识 


            P2=temp_circle;//0xFX 
            temp=P2;//读取P2口线数据 
            if(temp!=temp_circle)//有按键动作 
            { 
                    num_check++;//低电平计数|逢低电平加1 
                    if(num_check==10)//连续10次(10ms)低电平有效 
                    { 
                            key_flag=1;//按键有效标识置1 
                            temp_code=temp;//保存按键值 
                    } 
            } 
            else//松手OR无按键动作,此时应该改变扫描线 
            { 
                    num_check=0; 
                    if(key_flag==1)//按键有效判断 
                    { 
                            key_flag=0; 
                            switch(temp_code)//读取按键号 
                            { 
                                    //P2^0线 
                                    case 0xEE: num_key=1; 
                                               break; 
                                    case 0xDE: num_key=2; 
                                               break; 
                                    case 0xBE: num_key=3; 
                                               break; 
                                    case 0x7E: num_key=4; 
                                               break; 
                                    //P2^1线 
                                    case 0xED: num_key=5; 
                                               break; 
                                    case 0xDD: num_key=6; 
                                               break; 
                                    case 0xBD: num_key=7; 
                                               break; 
                                    case 0x7D: num_key=8; 
                                               break; 
                                    //P2^2线 
                                    case 0xEB: num_key=9; 
                                               break; 
                                    case 0xDB: num_key=10; 
                                               break; 
                                    case 0xBB: num_key=11; 
                                               break; 
                                    case 0x7B: num_key=12; 
                                               break; 
                                    //P2^3线 
                                    case 0xE7: num_key=13; 
                                               break; 
                                    case 0xD7: num_key=14; 
                                               break; 
                                    case 0xB7: num_key=15; 
                                               break; 
                                    case 0x77: num_key=16; 
                                               break; 
                            } 
                    } 
                    temp_circle=_crol_(temp_circle,1);//改变扫描线 
                    if(temp_circle==0xEF) 
                    { 
                            temp_circle=0xFE; 
                    } 
            } 
            return(num_key);//返回按键号 



    /************************************************************************* 


    未按键时,扫描线一直变化。 
    长按键时,扫描线不变化,使得该行按键变成了独立按键,这样的扫描效率极高。 
    如当按下P2.0线上的某个键时,程序将扫描到这个键,而后扫描线不变化, 
    当键盘程序连续10次进入时检测到10次按键有效,直到松手后扫描线才变化 


    *************************************************************************/


    http://bbs.elecfans.com/jishu_184831_1_1.html


    展开全文
  • 蓝桥杯单片机独立按键扫描程序

    千次阅读 2019-05-25 22:40:24
    最近自己在做单片机的东西,准备参加比赛,偶然发现了独立按键的神助攻——三行搞定独立按键,看到网上很多描述的不清晰,自己又花时间整理了一下,话不多说先上代码: void Key_Read(void) { ReadData=KeyPort...
  • 单片机按键扫描函数

    2020-01-16 14:02:27
    按键扫描(支持连续按) 检测按键IO口的高低电平 u8 KEY_Scan(void) { if(KEY按下) { delay_ms(10);//延时10-20ms 消蚪 if(KEY确实按下) { return KEY_Value; } return 无效值; } } 按键扫描(不...
  • 单片机检测按键原理

    万次阅读 2018-03-25 12:40:26
    首先说一下独立键盘检测,在单片机外围电路中 ,通常用到的按键都是机械弹性开关,当开关闭合时,线路导通,开关断开时,线路断开。单片机检测按键的原理:按键的一端接地,另一端与单片机的某个I/O口相连,开始先给...
  • 矩阵键盘扫描原理详解——单片机

    万次阅读 多人点赞 2016-04-07 20:12:00
    矩阵键盘扫描原理详解根据原理图 键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电...
  • 一、基本知识  1.按键分类与输入原理 ...在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。当所设置的功能键或数字键按下时
  • 51单片机之矩阵键盘

    千次阅读 2019-05-16 21:28:15
    独立键盘单片机连接时,每一个按键都需要单片机的一个I/O口若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源。单片机系统中I/O口资源往往比较宝贵,当用到多个按键时为了节省I/O口口线,我们引入...
  • 前面提到了独立按键扫描方法(延时,消抖的方法),可见这种方法很大程度上可以实现按键的准确扫描。但是仔细一看,可以发现,它有一个缺点——存在while语句的松手检测! 试想,倘若我们一直按着按键不松手,那...
  • 单片机按键设计的四个方案

    万次阅读 2019-01-12 16:10:51
    单片机系统里,按键是常见的输入设备,在本文将介绍几种按键硬件、软件设计方面的技巧。一般的在按键的设计上,一般有四种方案:一是GPIO口直接检测单个按键,如图1.1所示;二是按键较多则使用矩阵键盘,如图1.2所...
  • 矩阵键盘的中断模式

    千次阅读 2017-03-29 22:53:23
    矩阵键盘扫描会占用MCU大量的时间,为了节约时间使程序运行更加流畅,一般实用中断方式进行矩阵键盘的扫描工作。 上图中从上往下前8个管脚连接单片机的8个I/O,最后一个连接单片机的外部中断管脚,用来触发中断。
  • 单片机常用按键电路

    千次阅读 2017-06-16 09:07:42
    单片机组成的小系统中,有的需要人机交互功能,按键是最常见的输入方式。 最常见的按键电路大致有,一对一的直接连接和动态扫描的矩阵式连接两种。 1. 一对一的直接连接 左右两个电路作用一样,区别是左边...
  • 而现在介绍的按键扫描法是“快速识别”方法(以独立按键为例,因为矩阵键盘扫描与独立按键类似)。 首先附上按键的原理图: 用跳帽连接排针 J5 的2脚与3脚,将键盘设置为独立按键(只有S4~S7有效)。此时,S4~S7...
  • 51单片机入门教程(4)——按键控制

    万次阅读 多人点赞 2018-11-25 18:29:13
    按键输入一、独立按键1.1 独立按键的原理1.2 独立按键的仿真电路1.3 按键消抖二、矩阵键盘2.1 矩阵键盘原理2.2 矩阵键盘扫描原理矩阵键盘扫描程序 单片机与外界的信息交互主要有两大类,输入信息和输出信息。 之前的...
  • 51单片机--矩阵键盘

    千次阅读 2017-04-20 12:58:04
    这次我接着上次的说,讲一下 复合按键和 矩阵键盘。 先说矩阵键盘,因为我写的组合键代码是在矩阵键盘的基础上写的,当然在独立按键上写组合键更简单一些。所以当你矩阵键盘的组合键会写的时候,你在独立...
  • 关注【电子开发圈】微信公众号,一起学习吧!...电子DIY、Arduino、51单片机、STM32单片机、FPGA…… 电子百科、开发技术、职业经验、趣味知识、科技头条、设备拆机…… 点击链接,免费下载100G+电子设计学习资料! ...
1 2 3 4 5 ... 20
收藏数 4,033
精华内容 1,613
关键字:

单片机按键扫描