蓝桥杯电子类单片机组模块——独立按键(按下与松开)

蓝桥杯单片机组对按键模块的考察不仅仅会涉及到普通的按键扫描,还有可能设计到一些按键的高级用法:按下与松开、长短按等。

现在,我们介绍一下按键“按下与松开”功能的实现方法。

1、要使用独立按键,那么开发板上的J5跳帽必须接到BTN(独立按键)。

2、第二步,大家可以先参考一下独立按键一般作用的代码块:
https://blog.csdn.net/qq_44629819/article/details/104486419
在本次实验中,我们需要将原先的代码做轻微的变动:

static char KEY_STATE=KEY_STATE0; 

将上述代码段(第二十二行)中“KEY_STATE”作为外部变量,也就是将代码移植出去。

Q:这样做有何目的?
A:有益于我们在主函数里读取到按键状态。

3、我们假设有一个这样的赛题片段:

  • 按键按下S4,led1点亮。
  • S4按键松开,led1熄灭。
  • 要求其他按键按下时对led模块无任何影响。

如果大家对led模块不是很熟悉,可以先参考一下led模块显示的代码块:
https://blog.csdn.net/qq_44629819/article/details/104498166

T:在按键状态KEY_STATE=0的情况下,按键松开;在 KEY_STATE=2的情况下,按键按下。在按键松开的条件下,键值为0;在按键按下的一刹那,键值为按键本身后瞬间转为0。

4、如下,附上独立按键松开与按下代码块。

#include "STC15F2K60S2.h"

#define u8 unsigned char 
#define KEY_STATE0 0 //判断按键是否按下
#define KEY_STATE1 1 //按键按下标志
#define KEY_STATE2 2 //判断按键是否松开

#define led_0 0x00
#define led_1 ((0x01)<<(1-1))
#define led_2 ((0x01)<<(2-1))
#define led_3 ((0x01)<<(3-1))
#define led_4 ((0x01)<<(4-1))
#define led_5 ((0x01)<<(5-1))
#define led_6 ((0x01)<<(6-1))
#define led_7 ((0x01)<<(7-1))
#define led_8 ((0x01)<<(8-1))


 u8 code t_display[]={                       //????
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //??



void Timer0Init(void)		//配置定时器0,1ms中断
{
	AUXR |= 0x80;		
	TMOD &= 0xF0;		
	TL0 = 0xCD;		
	TH0 = 0xD4;		
	TF0 = 0;		
	TR0 = 1;		
	ET0=1;
	EA=1;
}

static char KEY_STATE=KEY_STATE0;//改变之后的效果

unsigned char key_scan()
{
		  u8 KEY=0;
	      u8 key_value=0;
	
		P30=1;P31=1;P32=1;P33=1;
		if(P30==0) KEY=7;
		if(P31==0) KEY=6;
		if(P32==0) KEY=5;
		if(P33==0) KEY=4;
		if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1))  KEY=0;
	 
	  switch(KEY_STATE)
		{
				case KEY_STATE0: 
				if(KEY!=0)
				{
				KEY_STATE=KEY_STATE1;
				}
				break;
				
				case KEY_STATE1:  
				switch(KEY)
				{
				case 4: key_value=4;  break;
				case 5: key_value=5;  break;
				case 6: key_value=6;  break;
				case 7: key_value=7;  break;
				}
				KEY_STATE=KEY_STATE2;

				break;
				case KEY_STATE2: 
				if(KEY==0)
				{
				KEY_STATE=KEY_STATE0;
				}


				break;
		}
		return key_value;
	}

bit key_flag;
u8 key_val=0;

bit led_flag;
u8 led_COM[10]={led_0,led_1,led_2,led_3,led_4,led_5,led_6,led_7,led_8};
char led_choose1=0;

void main()
{
	P0=~0X00;P2=0X80;P2=0X00;
	P2=0XA0;P0=0X00;P2=0X00;
	Timer0Init();
			while(1)
			{
				if(led_flag)
				{
					led_flag=0;
					P0=~led_COM[led_choose1];P2=0X80;P2=0X00;
					
				}
				
				
				if(key_flag)
				{
					key_flag=0;
					key_val=key_scan();
					switch(key_val)
					{
				case 4: 	break;		//任务1
				case 5: 	break;      //任务2
				case 6:     break;		//任务3
				case 7:     break;		//任务4
					}
				}
				

					if(KEY_STATE==KEY_STATE2)//先判断是否有按键按下
					{		
							if(key_val==4)//再判断按下的按键是否是S4,注意:因为键值会瞬间改变,所以必须按照这样的顺序才可。
						{	
									if(led_choose1!=1)//防止重复写锁存器
								{
									led_flag=1;led_choose1=1;//led1亮
								}		

											
						}
					}	
					else//此时按键松开
					if(led_choose1!=0)//防止重复写锁存器
					{
					led_flag=1;led_choose1=0;//led1灭
					}
				
			
			
	
			
		}
}

void Timer0()	interrupt 1	//[email protected]
{
		static int key_count=0;
		key_count++;
		if(key_count==10)
		{
			key_count=0;
			key_flag=1;
		}
		

}

5、关于按键的长按与短按等内容以后会提到。

祝大家在蓝桥杯比赛中获得优异的成绩!
——南昌大学 电子183刘昊

发布了5 篇原创文章 · 获赞 4 · 访问量 153

猜你喜欢

转载自blog.csdn.net/qq_44629819/article/details/104505443