1.前讲回顾

在上一讲的代码里如果我们按下按键一直不松手,则灯会一直闪烁。这是因为“稳定接触状态”一直保持着长时间的低电平,所以程序的二次“if(KEY4==0)”判断一直满足条件就会在“LED2=0;”和“LED2=1;”之间来回切换,再加上50ms延时才会保持亮一段时间灭一段时间所体现的LED闪烁。

 

2.支持连按概念

这种按键模式就叫做“支持连按”,所谓支持连按即我们使用遥控器放大电视的音量时只需按住“+”键不放,屏幕上的音量值在一直累加,松手后就停止累加了,这种就叫做按键支持连按功能。

 

3.不支持连按概念

另一种按键模式叫做“不支持连按”,例如我们用的电磁炉上的“+”键,按下不松手时数值只加一次就不加了,只有松手后再按才会进行数值的第二次累加。两种按键模式在单片机开发中都会经常使用。

 

4.不支持连按的分析

我们需要思考的是,即使“稳定接触状态”的时间再怎么长,我们只能执行一次功能代码。

那么我们可以猜测,IO端口检测到按键按下然后执行完功能程序之后,下一个语句就写:如果IO端口还是保持着低电平(不松手状态),那程序就不往下执行了,让程序在这里“停止”,只有IO端口变成高电平(已松手)才允许“放行”程序去运行。

我们知道按键抖动的时间少于10ms,所以在满足第一次“if(KEY4==0)”判断的时候只做“delay_ms(10);”的延时左右,过了这段时间就是“稳定接触状态”了,于是再去二次判断“if(KEY4==0)”即可。

 

5.雏形的代码

#include <reg52.h> 
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;
 
sbit LED2  = P0^0;
sbit KEY4  = P2^7;
void delay_ms(unsigned int x)
{
    unsigned int i,j;
    if(x==1000)
    {
        for(i=0;i<19601;i++)//延时1s
        {
            for(j=5;j>0;j--);
        }
    }
    else while(x--)for(j=115;j>0;j--);
}

void main()
{  
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
  
    ADDR2 = 1;//**************************
    ADDR1 = 1;//让三八译码器的IO6输出低电平
    ADDR0 = 0;//**************************
    P2 = 0xF7;//让K4能具备有被拉低的条件先
    
    while(1)
    {    
        if(KEY4==0)
        {
            delay_ms(10);//等待抖动过去
            if(KEY4==0)  //二次判断
            {
                LED2=!LED2;
                while(KEY4==0);//如果IO端口还是保持着低电平,此时也就是没有松手,那括号里的条件满足,程序一直在循环这条语句,
                               //所以程序停止不往下执行了,直到KEY4变为1,也就是按键松手了,while里面的条件不成立才退出这个循环,放行了程序
            }
        }
    }
}

可以发现无论我们的按下手速有多快或多慢,“ LED2=!LED2;”只能被执行一次而已。这样就像按电磁炉上的按键一样,一次只能切换一回灯的亮灭,即使不松手也不会出现灯的闪烁,这就是不支持连按的代码书写方式,不过这样的代码还是存在缺陷,我们下一讲再解说。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)