STC学习:按键消抖计数

程序运行效果说明
按下KEY1,数码管上的示数加1。
按下KEY2,数码管上的示数减1。

程序电路工作原理以及按键抖动原因
在这里插入图片描述
当按键被按下的时候,电路导通接地,I/O口为低电平;当按键未被下时,电路断开,I/O口保持高电平。但一般的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,假如不加以处理,会导致按键被识别为按下多次。为了不产生这种现象而作的措施就是按键消抖。
在这里插入图片描述
消抖的方法
按键消抖分为硬件消抖和软件消抖
1.硬件消抖
在键数较少时可用硬件方法消除抖动。下图所示的RS触发器为常用的硬件去抖。
在这里插入图片描述
图中两个“与非”门构成一个RS触发器。当按键未按下时,输出为0;当键按下时,输出为1。此时即使用按键的机械性能,使按键因弹性抖动而产生瞬时断开(抖动跳开B),只要按键不返回原始状态A,双稳态电路的状态不改变,输出保持为0,不会产生抖动的波形。也就是说,即使B点的电压波形是抖动的,但经双稳态电路之后,其输出为正规的矩形波。这一点通过分析RS触发器的工作过程很容易得到验证。

2.软件消抖
方法1:使用延时
如果按键较多,常用软件方法去抖,即检测出键闭合后执行一个延时程序,5ms~10ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。

方法2:检测多次
可以设定一个检测周期,如果在一个检测周期内,按键被检测为被按下达到了一定的次数,则确认为真正的被按下。

#include "STC15F2K60S2.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//数码管段选信号 从0到9
uchar code duanxuan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管位选信号 显示在第4到7位
uchar code weixuan[4]={0x04,0x05,0x06,0x07};
sbit led_sel=P2^3;//74HC138 的一个使能位
sbit key1=P3^2;//按键k1
sbit key2=P3^3;//按键k2
uint number;//显示在数码管上的值
uint flag;//位选的位置
int count1,count2,count3,count4;//用于消抖计数
bit status_P,status_P2;//记录按键前一状态
void Init()
{//将P0设置成推挽输出 P2的低四位设置成推挽输出 P3不需要设置成推挽输出
	P0M0=0XFF;
	P0M1=0X00;
	P2M0=0X0F;
	P2M1=0X00;
	led_sel=0;
	P0=0;
	number=5000;//初始化number=5000
	count1=0;
	count2=0;
	count3=0;
	count4=0;
	status_P=0;
	status_P2=0;
	flag=0;
	TMOD=0X00;
	EA=1;
	ET0=1;
	TH0=(65536-200)/256;
	TL0=(65536-200)%256;
	TR0=1;
}

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++;
	count1++;
	if(key1==0)
		count2++;
	count3++;
	if(key2==0)
		count4++;
}
void main()
{
	Init();
	while(1)
	{
		if(flag==4)//修正位选位置  可放在中断程序外 放在中断外 效果更好
			flag=0;
		if(count1==30)//消抖大概6ms 总共统计次数 30次
		{
			if(count2>=20)// 如果低电平的有效次数为 2/3 以上
			{
				if(status_P==1)
				{
					status_P=0;
					number++;
				}
			}
			else
				status_P=1;
			count1=0;
			count2=0;
		}
		if(count3==30)//消抖大概6ms 总共统计次数 60次
		{
			if(count4>=20)// 如果低电平的有效次数为 2/3 以上
			{
				if(status_P2==1)
				{
					status_P2=0;
					number--;
				}
			}
			else
				status_P2=1;
			count3=0;
			count4=0;
		}
	}
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布布要成为最负责的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值