按键&蜂鸣器&数码管

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

在上一讲的代码中我们可以不用写“sbit GND = P2^3;”,像宋老师那样直接在开头“P2 = 0xF7;”仅让P2.3输出0其他输出1即可,这样P2.7就有被拉低的条件了。


1.趁热打铁

沿袭上一讲的功能,我们新学的按键知识需要结合所学过的无源蜂鸣器硬件一起捣鼓玩玩。同上一讲的代码功能一样,这次用的是无源蜂鸣器,按键按下时,蜂鸣器就响,松开不按时就不响。

 

2.分析

我们先缕缕思路,显然无源蜂鸣器要想鸣叫,就不能像“LED2=KEY4;”这样赋值的方式。我们已经知道,在P2.3输出低电平的情况下,K4按下的时候程序中KEY4就等于0,松开不按时KEY4等于1。

这里可以在主函数中的死循环里用“if(KEY4==0)”来一直等待K4被按下,于是KEY4的值等于0才能进入if语句的大括号里去执行程序。不按下时“KEY4等于1”也就进入不了里面去执行程序了,CPU只能空循环不做任何事。

那这个if 语句的大括号里的内容大家也就明白需要做什么事了

#include <reg52.h> 
sbit BEEP  = P1^6;
sbit KEY4  = P2^7;

void main()
{  
    unsigned int i;
    P2 = 0xF7;//让K4能具备有被拉低的条件先
    
    while(1)
    {
        if(KEY4==0)
        {
            BEEP=!BEEP;
            for(i=0;i<25;i++);//不同时间的延时鸣叫的音调不同
        }
    }   
}

如果按键一直按着不放,那这个代码跟第二章第二讲里的例程可以说是一模一样了。

 

3.巩固

小灯和无源蜂鸣器都上场了,数码管也不能一边愣着吧,这里笔者给大家提供一段代码,自行下载进去后按着K4不放,观察现象然后尝试解析代码的原理,能力有限分析不出来也不必担心,继续往下学先。

#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;
unsigned char code LedChar[6]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};//a,b,c,d,e,f段单独亮的真值表

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 IO0_OUT()
{ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;}
void IO1_OUT()
{ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;}
void IO2_OUT()
{ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;}
void IO3_OUT()
{ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;}
void IO4_OUT()
{ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;}
void IO5_OUT()
{ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;}

void main()
{  
    unsigned char i=0;
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
    P2 = 0xF7;//让K4能具备有被拉低的条件先

    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;
        delay_ms(30);
    }
}

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

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