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