实验要求:
使用一个独立按键控制一颗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