在上一讲的代码中我们可以不用写“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);
    }
}
点赞(1)

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

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

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

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

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

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

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

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

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