首页  /  单片机教程  /  按键猜想  /  

按键猜想

点击打开在线编译器,边学边练

当然按键的功能不是像前两讲的代码这么单调,前两讲的代码是认识到程序中寄存器位的值是可以受外部电路影响而改变的。这一讲我们要做的就是根据前两讲的知识不断探索按键的一些规律和原理。

 

1.状态图

可能我们理想中的按键过程图如下

按键5


那我们不妨在这种猜想下用代码测试看看是什么效果。

首先要测试的是我们自己快速按下按键后就松开,上图的“按键按下时P2.7的状态”持续的时间到底是多长,我们就用流水灯的方式来查看按下之后迅速松开,小灯会跳到哪里显示。

 

2.代码及分析

#include <reg52.h> 
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;
 
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()
{  
    unsigned char i=1;
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
  
    ADDR2 = 1;//**************************
    ADDR1 = 1;//让三八译码器的IO6输出低电平
    ADDR0 = 0;//**************************
    
    P2 = 0xF7;//让K4能具备有被拉低的条件先
    P0 = 0xFE;//先点亮最右端的小灯

    while(1)
    {    
        if(KEY4==0)
        {
            delay_ms(10);
            P0=~(0x01<<i);                       
            i++;
            if(i>=8)i=0;
        }
    }
}

笔者在此程序下做实验,即使手速再怎么快地按下K4马上松开,可在这段时间里点亮的LED2跳到了LED5点亮,也就是说按键在物理上的导通时间超过了30ms。

后面i绝对大于3,因为LED5亮,所以有“P0=0xF7;”推出“ ~(0x01<<3)”,然后再有“i++;”,i绝对大于3。

按键6


这也就不难解释上一讲的“按键&数码管”的代码原理了,按照我们平时按键的手速,可以看到下面的现象

按键7


我们只是简单的一个按键动作,实验现象里从1阶段的状态一下子来到了4阶段,而在2,3阶段一闪而过(当然手速不同,可能也会在另一个阶段处停留),我们再看一下程序的部分代码

while(1)
{    
    P0=0xFF;
    switch(i)
    {
        case 0: IO0_OUT();P0=LedChar[0];break;    
        case 1: IO0_OUT();P0=LedChar[1];break;    
        case 2: IO0_OUT();P0=LedChar[2];break;    
        case 3: IO0_OUT();P0=LedChar[3];break;    
        case 4: IO1_OUT();P0=LedChar[3];break;   
        case 5: IO2_OUT();P0=LedChar[3];break;      
        case 6: IO3_OUT();P0=LedChar[3];break;    
        case 7: IO4_OUT();P0=LedChar[3];break;    
        case 8: IO5_OUT();P0=LedChar[3];break;    
        case 9: IO5_OUT();P0=LedChar[4];break;    
        case 10:IO5_OUT();P0=LedChar[5];break;   
        case 11:IO5_OUT();P0=LedChar[0];break;   
        case 12:IO4_OUT();P0=LedChar[0];break;    
        case 13:IO3_OUT();P0=LedChar[0];break;   
        case 14:IO2_OUT();P0=LedChar[0];break;  
        case 15:IO1_OUT();P0=LedChar[0];break;
    }
    if(KEY4==0)i++;
    if(i>=16)i=0;//让i在0~15之间变化
    delay_ms(30);
}

1阶段一下子来到4阶段,那么i肯定是因为按键的动作,被加了3次等于3才会在4阶段处停留,而在按键按下的动作中i自加一次之后都需要经过“delay_ms(30);”,可想而知,P2.7在按键动作中被拉低的持续时间就有60~90ms。

按键8


因为我们有了“delay_ms(30);”才会看到2,3阶段有亮度的持续短时间显示,之前叫大家按着K4不放,看到的是数码管在循环做跑马灯,i在K4按下不放中KEY4一直等于0所以i一直从0~15不停的改变,加上延时部分,6个数码管上的16段灯就看起来像流水灯一样在跑了。讲解到这里我们已经对按键的原理和代码操作有一定的了解了。


本文固定URL:https://www.dotcpp.com/course/201

上一课:按键&蜂鸣器&数码管 下一课:按键用法
第一章 单片机入门
第二章 LED
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)