×

51单片机笔记 51单片机学习纪实

51单片机学习纪实:5.1-使用独立按键控制LED灯点亮_【基础实验1】

一哥 一哥 发表于2021-12-28 22:11:03 浏览2227 评论0

抢沙发发表评论

实验要求:

使用一个独立按键控制一颗LED灯按下点亮与松开熄灭


实验思路:

1、独立按键K1控制脚接P0.0管脚,重定义P0.0管脚为:KEY1

2、LED灯D1控制脚接P0.2管脚,重定义P0.2管脚为:LED1

3、重定义系统数据类型

4、define宏定义K1按下为:KEY1_PRESS,无按键按下为:KEY_UNPRESS

5、定义一个延时函数delay_10us,一个按键扫描函数key_scan(返回值为unsigned char)


完整代码:

/**************************** 程序信息 ********************************
* 实验名称:使用独立按键控制LED灯点亮
* 文件名称:main.c
* 版    本:V1.00
* 日    期:2021-12-28
* 编    著:gefon
* 说    明:使用普中A7开发版,使用K1按键控制D1灯点亮,松开时熄灭。

****************************** 声明区 ********************************/
#include "reg52.h"  //8051的特殊功能寄存器定义

sbit KEY1=P0^0;  //重定义P0.0管脚为KEY1

sbit LED1=P0^2;  //重定义P0.2管脚为LED1

//重定义系统数据类型
typedef unsigned char U8;
typedef unsigned int U16;

//宏定义独立按键按下的键值
#define KEY1_PRESS     1
#define KEY_UNPRESS     0 

/****************************** 子程序 ********************************
* 函 数 名   :delay_10us
* 函数功能   :延时函数,当传入变量ten_us=1时,约延时10us
* 输    入   :ten_us
* 输    出   :无
***********************************************************************/
void delay_10us(U16 ten_us)
{
    while(ten_us--);
}

/****************************** 子程序 ********************************
* 函 数 名   :key_scan
* 函数功能   :按键扫描函数
* 输    入   :无
* 输    出   :KEY1_PRESS:K1按下
               KEY_UNPRESS:无按键按下    
***********************************************************************/
U8 key_scan()
{
    if(KEY1==0)
    {
        delay_10us(1000);  //按键消抖
        if(KEY1==0)
            return KEY1_PRESS;  //K1按下
    }
    else if(KEY1==1);  //无按键按下
        return KEY_UNPRESS;
}

/****************************** 主程序 ********************************
* 函 数 名   :main
* 函数功能   :主函数
* 输    入   :无
* 输    出   :无
***********************************************************************/
void main()
{
/***************************** 实现方案1 *****************************/
    U8 key=0;
    while(1)
    {
        key=key_scan();
        if(key==KEY1_PRESS)
            LED1=0;
        else if(key==KEY_UNPRESS)
            LED1=1;
    }
/*************** 方案1为模块化,调用key_scan扫描子程序 ***************/

/***************************** 实现方案2 *****************************/
//    while(1)
//    {
//        if(KEY1==0)
//        {
//            delay_10us(1000);  //按键消抖
//            if(KEY1==0)
//                LED1=0;  //点亮D1灯
//        }
//        else if(KEY1==1)
//        {
//            delay_10us(1000);
//            if(KEY1==1)
//                LED1=1;  //熄灭D1灯
//        }
//    }
/*************** 方案2不使用模块化,主函数内直接写代码 ***************/
}


实验分析:

可以看到,主程序区有方案1和方案2两种,两种方案均可实现功能。方案2直接在主函数内写运行代码,不调用按键扫描函数key_scan。方案1调用按键扫描函数key_scan,按键的扫描判定工作交给key_scan。合理的利用模块化程序,有利于后期代码移植。

为何需要给按键消抖?因为按键都是机械式的,在按下和弹开的阶段,波形会有波动。为了使程序不出现误判,需要等待一定的时间,波形稳定后再次来进行判断。才能保证程序出现误判。按键消抖有硬件和软件两种,产品的成本决定是使用硬件还是软件消抖。在一些安全级别较高的产品上,会在硬件消抖的基础上,再加上软件消抖。能更好的保障产品的稳定性。本实验采用软件消抖的方式。

key_scan函数的else if(KEY1==1)语句要加分号”;“,表示语句已经结束了,再接return KEY_PRESS。否则编译时程序会出现警告:并非每个出口路径都返回一个值。

MAIN.C(52): warning C291: not every exit path returns a value


少长咸集

群贤毕至

访客