51单片机(入门)——独立按钮

一、按钮原理图

独立按钮与矩阵按钮的切换只需与板子上跳帽位置有关 

KBD为独立按钮,而BTN为矩阵按钮。

独立按钮是由s4、s5、s6、s7组成,由于跳帽J5将2、3相连最左端接地,只需控制最右端为高电平即可连通

二、按钮的特性

通常按键所用的开关都是机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动,如图所示。

按键稳定闭合时间长短是由操作人员决定的,通常都会在100ms 以上,刻意快速按的话能达到40-
50ms 左右,很难再低了。
抖动时间是由按键的机械特性决定的,一般都会在10ms以内,为了确保程序对按键的一次闭合或者一次断开只响应一次,必须进行按键的消抖处理!

三、按钮的相关编程(消抖)

例题:

每按下一次s4,数码管上的数字+1

可以根据P33的电平消抖

在while(1)内循环
①读取P33状态;


②如果是0,则等待10ms;再读取P33状态;如果不是1,继续读取P33状态;
如果还是0,确定有按键按下;则执行number+;程序,让数码管数字+1:
如果不是0,则说明是抖动,则不执行任何程序!


③等待按键弹起后,再等待10ms,方可从①再开始执行;
(如果不等待,则在循环内1~3会一直执行,让数字疯狂+1)

方法一:

#include <STC15F2K60S2.H>
#define key_no  0
#define key_down  1
#define key_up  2
unsigned char cnt_key=0;
typedef struct
{
		unsigned char b0:1;
		unsigned char b1:1;
		unsigned char b2:1;
		unsigned char b3:1;
		unsigned char b4:1;
		unsigned char b5:1;
		unsigned char b6:1;
		unsigned char b7:1;
} bits;
typedef union
{
	unsigned char hex;
	bits b;
} HexToBin;
void vDevice_ctrl(unsigned char P0data,unsigned char P2data)
{
	P0=P0data;
	P2=P2data;
	P2=0;
}
void vsystem_init()
{
	vDevice_ctrl(0,0xa0);

}
unsigned char vBTN_read()
{
	static unsigned char key_state=0;
	unsigned char key_io=0,key_val=0;
	key_io=P3&0x0f;
	switch(key_state)
	{
		case key_no:
			if(key_io!=0x0f) key_state=key_down;
		break;
		case key_down:
			if(key_io!=0x0f)
			{
				if(key_io==0x0e)key_val=7;
				else if(key_io==0x0d)key_val=6;
				else if(key_io==0x0b)key_val=5;
				else if(key_io==0x07)key_val=4;
				key_state=key_up;
			}
			else
			{
				key_state=key_no;
			}
		break;
		case key_up:
			if(key_io==0x0f)key_state=key_no;
		break;
	}
	return key_val;
}
unsigned int number=0;
void vBTN()
{
	unsigned char key_val;
	if(cnt_key>=10)
	{
		cnt_key=0;
		key_val=vBTN_read();
		if(key_val==4)number++;
	}
	
}
unsigned char smg_code[10]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char smg_buf[8];
void vsmg()
{
	smg_buf[0]=smg_code[number/100];
	smg_buf[1]=smg_code[number/10%10];
	smg_buf[2]=smg_code[number%10];
	smg_buf[3]=0x00;
	smg_buf[4]=0x00;
	smg_buf[5]=0x00;
	smg_buf[6]=0x00;
	smg_buf[7]=0x00;
}
void vsmg_display()
{
	static unsigned char i=0;
	vDevice_ctrl(0,0xc0);
	vDevice_ctrl(~smg_buf[i],0xe0);
	vDevice_ctrl(0x01<<i,0xc0);
	i=(i+1)%8;
}
void Timer2_Init(void)		//1??@12.000MHz
{
	AUXR |= 0x04;			//?????1T??
	T2L = 0x20;				//???????
	T2H = 0xD1;				//???????
	AUXR |= 0x10;			//???2????
	IE2 |= 0x04;                    //????2??
    EA = 1;

}

void t2int() interrupt 12           //????
{
   cnt_key++;
	vsmg_display();
}

void main()
{
	vsystem_init();
	Timer2_Init();
	while(1)
	{
		vsmg();
		vBTN();
	
	}



}

方法二:

#include <STC15F2K60S2.H>
unsigned char Trg;
unsigned char Cont;
void vBTN_Read_TreeLines()
{
	unsigned char ReadData=P3^0xff;
	Trg=ReadData&(ReadData^Cont);
	Cont=ReadData;
}
unsigned char cnt_key=0;
void vSystem_Init()
{
	vDevice_ctrl(0,0xa0);
}


unsigned char number=0;
void vBTN_process()
{
	if(cnt_key>=10)
	{
		cnt_key=0;
		vBTN_Read_TreeLines();
		if(Trg&0x01)number=number-10;
		if(Trg&0x02)number=number+10;
		if(Trg&0x04)number=number-1;
		if(Trg&0x08)number=number+1;
	
	}
	
}


void vsmg_process()
{
	smg_buf[0]=smg_code[number/100];
	smg_buf[1]=smg_code[number/10%10];
	smg_buf[2]=smg_code[number%10];
	smg_buf[3]=0x00;
	smg_buf[4]=0x00;
	smg_buf[5]=0x00;
	smg_buf[6]=0x00;
	smg_buf[7]=0x00;
}

void main()
{
	vSystem_Init();
	Timer2_Init();
	while(1)
	{
		vsmg_process();
		vBTN_process();
	}
		


}
void t2int() interrupt 12           //????
{
  cnt_key++;
	vsmg_display();
}

四、总结

按钮的使用要注意消抖,可以通过对应的P3口的状态来解决

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值