实验要求:
使用多个独立按键控制不同LED灯按下点亮,再次按下熄灭LED。
实验思路:
1、独立按键K1-K4控制脚分别接P0.0-P0.3管脚,LED灯D1-D4控制脚分别接P2.7-P2.4管脚
2、宏定义K1-K4按下为:KEY1_PRESS~KEY4_PRESS,无按键按下为:KEY_UNPRESS
3、定义一个延时函数delay_10us,定义一个按键扫描函数key_scan
完整代码:
/**************************** 程序信息 ********************************
* 实验名称:使用多个独立按键控制不同LED点亮与熄灭
* 文件名称:main.c
* 版 本:V1.00
* 日 期:2021-12-29
* 编 著:gefon
* 说 明:使用普中A7开发版,使用独立按键K1-K4控制D1-D4灯按下点亮/熄灭
****************************** 声明区 ********************************/
#include "reg52.h"
//定义独立按键控制脚
sbit KEY1=P0^0;
sbit KEY2=P0^1;
sbit KEY3=P0^2;
sbit KEY4=P0^3;
//定义LED灯控制脚
sbit LED1=P2^7;
sbit LED2=P2^6;
sbit LED3=P2^5;
sbit LED4=P2^4;
//重定义系统数据类型
typedef unsigned char U8;
typedef unsigned int U16;
//宏定义独立按键按下的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
/****************************** 子程序 ********************************
* 函 数 名 :delay_10us
* 函数功能 :延时函数,当传入变量ten_us=1时,约延时10us
* 输 入 :ten_us
* 输 出 :无
***********************************************************************/
void delay_10us(U16 ten_us)
{
while(ten_us--);
}
/****************************** 子程序 ********************************
* 函 数 名 :key_scan
* 函数功能 :按键扫描函数
* 输 入 :mode=0时,单次扫描
mode=1时,连接扫描
* 输 出 :KEY1_PRESS:K1按下
KEY2_PRESS:K2按下
KEY3_PRESS:K3按下
KEY4_PRESS:K4按下
KEY_UNPRESS:无按键按下
***********************************************************************/
U8 key_scan(U8 mode)
{
static U8 keep=1;
if(mode)keep=1;
if(keep==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
{
delay_10us(1000); //按键消抖
keep=0;
if(KEY1==0)
return KEY1_PRESS; //返回K1按下
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}
else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
{
keep=1;
}
return KEY_UNPRESS; //返回无按键按下
}
/****************************** 主程序 ********************************
* 函 数 名 :main
* 函数功能 :主函数
* 输 入 :无
* 输 出 :无
***********************************************************************/
void main()
{
U8 key=0;
while(1)
{
key=key_scan(0);
if(key==KEY1_PRESS)
LED1=!LED1; //点亮和熄灭LED
else if(key==KEY2_PRESS)
LED2=!LED2;
else if(key==KEY3_PRESS)
LED3=!LED3;
else if(key==KEY4_PRESS)
LED4=!LED4;
else if(key==KEY_UNPRESS); //无按键按下
}
}实验分析:
实验要求是按下点亮LED,再次按下熄灭LED。按键扫描函数key_scan有一个输入形参mode。
当mode=0时为单次扫描,如果LED赋值为低电平"0",下一次再按下时依然会赋值为"0",这样就无法做到再次按下时熄灭LED。因此这里LED的赋值为取反LED的状态。当按下点亮LED后,再次按下时会取反LED现在的状态,也就可以熄灭LED了。
当mode=1时为连续扫描,程序会对按键进行持续的扫描,这时按下按键LED会不停的闪烁。当你松开按键时,LED会保存最后一次取反的状态,有可能会是"0",也有可能会是"1"。按本实验的思路是不合适的。但可以通过修改按键按下时的LED赋值和修改无按键按下(KEY_UNPRESS)的语句实现:按下时点亮LED,松开时熄灭LED。修改代码如下:
key=key_scan(1);
if(key==KEY1_PRESS)
LED1=0; //点亮和熄灭LED
else if(key==KEY2_PRESS)
LED2=0;
else if(key==KEY3_PRESS)
LED3=0;
else if(key==KEY4_PRESS)
LED4=0;
else if(key==KEY_UNPRESS) //无按键按下
{LED1=1;LED2=1;LED3=1;LED4=0;}修改以上代码,将按下时LED赋值改为"0",并修改无按键按下(KEY_UNPRESS)时,LED1-LED4都赋值1即可实现按下时点亮LED,松开时熄灭LED。