单片机学习笔记 —— 按键消抖

  按键是我们学习单片机时一个重要的器件,我们在按下按键时,难免会一位手抖动或者接触不稳定,但如果不消抖,按键按下的瞬间将会产生成百上千次按键有效的结果,最终的现象不可预料,所以有必要进行消抖。

一、消抖原理

原理:使用定时器计时产生中断,只要在一定次数的中断内,按键按下有效的次数达到一定次数,就可以认为按键按下了,此时返回一个按键有效的现象。

例子:比如,我们设置200us产生一个中断,定义两个变量:count_timeskey_pressed_times ,每次中断count_times加一,同时若检测key按键被按下,则key_pressed_times加一。当count_times达到30时,若key_pressed_times>20,则认为按键按下了。
count_times:计算中断次数
key_pressed_times:计算中断时按键按下的次数



二、程序代码

原理图

按键的引脚:KEY1: P3.2、KEY2: P3.3
数码管段选:P0[7…0]
数码管位选:P2[2…0] + P2.3(译码使能)

变量定义

#define uchar unsigned char
#define uint unsigned int

uchar code duanxuan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code weixuan[4]={0x04,0x05,0x06,0x07};

sbit led_sel=P2^3;	//74LH138译码器的使能
sbit key1=P3^2;		//按键key1
sbit key2=P3^3;		//按键key2

uint number;		//显示在数码管上的值
uint flag;			//位选的位置
int count_times,key1_pressed_times,key2_pressed_times;	//消抖中统计次数的量
bit status_P,status_P2;			//按键的钱后两个状态

Init()函数

void Init()
{
	P0M0 = 0XFF;	//设置推挽输出,P3不用设置
	P0M1 = 0X00;
	P2M0 = 0X0F;
	P2M1 = 0X00;
	
	led_sel = 0;	//位选译码器使能有效
	P0 = 0;
	number = 5000;
	count_times = 0;
	key1_pressed_times = 0;
	key2_pressed_times = 0;
	
	status_P = 0;	//默认前后状态都是按下
	status_P2 = 0;
	flag = 0;
	
	TMOD = 0X00;
	EA = 1;
	ET0 = 1;
	TH0 = (65536-200)/256;	//200us一次中断
	TL0 = (65536-200)%256;
	TR0 = 1;
}

中断函数:控制数码管显示、统计中断次数、统计key1和key2被按下的次数

void InterruptTimer0()interrupt 1
{
	// 控制数码管显示
	switch(flag)
	{
		case 0:P0=0;P2=weixuan[flag];P0=duanxuan[number/1000];break;
		case 1:P0=0;P2=weixuan[flag];P0=duanxuan[(number/100)%10];break;
		case 2:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)/10];break;
		case 3:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)%10];break;
	}
	flag++;
	
	// 中断次数 检测key1、key2是否被按下
	count_times++;
	if(key1==0)
		key1_pressed_times++;
	
	if(key2==0)
		key2_pressed_times++;
}

main()函数:每15ms采集一次数据,检测按键是否可以被认为被按下

void main()
{
	Init();
	while(1)
	{
		if(flag==4)		//该判断放在中断函数外面更合适
			flag=0;
		
		if(count_times==30)					//每30*0.2ms检测一次按键
		{
			if(key1_pressed_times>=20){		// 该时间段内,key1按下次数达到2/3
				if(status_P==1){
					status_P=0;
					number++;
				}
			}
			else status_P=1;
			
			if(key2_pressed_times>=20){		// 该时间段内,key2按下次数达到2/3
				if(status_P2==1){
					status_P2=0;
					number--;
				}
			}
			else status_P2=1;
			
			count_times=0;					// 所有次数清零
			key1_pressed_times=0;
			key2_pressed_times=0;
		}
	}
}

延时消抖:另一种消抖的办法,如果某一时刻检测到按键key为低电平(按下),再10us,如果按键还是低电平,则可认为按键按下是有效的。

if( sbtKey1 == 0 )
{
	delay( 10 );                     //ÑÓʱÏû¶¶
	if( sbtKey1 == 0 )
	{
		xxx;
	}
}

以上就是关于按键消抖的内容啦~



第五篇单片机学习笔记完结,cheers ! 🍻

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值