非阻塞式读取矩阵按键:保姆教程

本文详细介绍了如何在51单片机上实现非阻塞式读取按键,包括基本读取、延迟消抖、标志位处理、计数法,以及扩展到矩阵按键的方法。通过连续进阶的方法解决了按键抖动和资源占用问题,适合新手和进阶者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

非阻塞式读取矩阵按键

这个教程是在电协培训新生的一点点心得,旨在解决许多人学习单片机,对按键的一个困惑:按键的非阻塞式消抖。如何在不消耗很多时间的情况下,有效地消抖,具有非常实际的意义。

本文就把一个循序渐进的对按键处理的理解记录下来,方便大家学习,由于本人已投入半导体器件的学习,很久没有接触数字电路,如有错误,还请读者指出。

本文注重方法的连续演化,遵循事物的发展规律,如需要计数式非阻塞矩阵按键读取方法,直接翻到最后即可,最后我将给出本文所讲的所有代码,屏蔽掉,稍加修改端口可以在51单片机上实现,体会每种方法的利弊,和更好的方法的思想。

另外我将给出一个应用,证明非阻塞,特征次数可变的按键检测的优势。

1、按键的基本读取

请添加图片描述

如上图,是单片机常用的两种开关,其内部结构,由于弹性金属触点的接触,进而触发了两个引脚的开路和短路。

请添加图片描述

独立按键的检测原理:

从单片机核心板的原理图上可以看到,在按键未按下时,KEY是断开的,单片机IO口通过限流电阻与VCC相连,则IO口处于被拉高的状态。

按键被按下时,则KEY接通,电阻右端为理想的0V状态,IO口接在电阻右端,处于被拉低的状态。

单片机通过读这些引脚状态就能够判断按键处于什么状态。

根据这个思想,代码如下:

void main(void)
{
   
    while (1)
    {
   
        if (key0 == 0)
        {
   
            led = !led;
        }
    }
}

2、delay延时消抖:解决抖动问题

上面的代码,效果不好?那一定是按键消抖的问题

请添加图片描述

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

那么,如何消抖呢?

一种是硬件消抖,用电容导走信号的高频分量,也就是抖动部分。

请添加图片描述

另一种就是软件消抖:

void main(void)
{
   
    while (1)
    {
   
        if (!key0)
        {
   
            delay_ms(10);
            if (!key0)
            {
   
                led = !led;
                //while (!key0);
            }
        }
    }
}

这种方法也有弊端,不用while卡住,那么按住按键,则每次都会进入循环,大多数应用情景,我们都希望按一次按键,单片机做一次响应,用了while,那么主循环就会卡在这里不能往下进行,这对于大多数情况下都是致命的,应该尽量避免。

3、标志位:解决单次按下难题

这种方法基于上面提到的问题做了改进,主要思想是定义一个变量,储存按键的状态,只有在弹起状态的时候按下,才算做一次有效按下,在else if中更新为按键弹起状态。

void main(void)
{
   
    unsigned char key0_stat;
    while (1)
    {
   
        if (key0_stat == 1 && key0 == 0)
        {
   
            delay_ms(10);
            key0_stat = 0;
            led = !led;
        }
        else if (key0_stat == 0 && key0 == 1) key0_stat = 1;
    }
}

4、 计数:解决阻塞问题

上一种方法已经能用,但是远远称不上好用,为什么?因为那个10ms的延时,我们说延时的目的是为了避开那个我们处理不了的抖动过程,但是延时必然有弊端,尤其是这种延时这么长时间,什么事都不干,无论从系统实时性角度,还是资源利用率角度,都是不能允许存在的。那么有没有别的方法避免呢?

请添加图片描述

上面的图,展示了按键从按下到松开,单片机以较高频率采集IO口状态的过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值