51单片机按键控制LED灯亮灭的N个玩法
1.概述
这篇文章介绍按键的使用,以及通过控制LED灯的小实验,发现按键中存在的问题,然后思考并解决这些问题。达到熟练使用按键控制元器件。
2.搭建硬件环境
1.硬件准备
名称 | 型号 | 数量 |
---|---|---|
单片机 | STC12C2052 | 1 |
LED彩灯 | 无 | 2 |
晶振 | 12MHZ | 1 |
电容 | 30pf | 2 |
电阻 | 100欧姆 | 2 |
面包板 | 无 | 1 |
连接线 | 无 | 5 |
2.电路图原理图
- 1.LED灯正极串联一个100欧姆电阻,接到单片机20号引脚VCC。
- 2.连接线一头连接单片机12号引脚,另一头接按键的一脚。
- 3.按键的另一脚通过连接线接到单片机10号引脚GND
- 4.晶振两个脚分别连接单片机的4号和5号引脚,同时晶振每个引脚串联一个30pf电容接到单片机10号引脚GND
3.实验课题
3.1.按键按下灯亮,松开灯关闭
1.课题描述
课题的目的使用按键来控制LED灯的亮和灭,当按下按键读取到低电平,让灯打开。当送开按键读取到高电平,让灯关闭。
2.实现程序
/*************************************************************
* 程序名: 按键控制LED灯亮灭
* 编写人: bruce
* 硬件支持:TC12C2052 外部12MHZ晶振
* 日 期: 2023-11-14
* 修改日志:
/*************************************************************/
#include<STC12C2052AD.H>
sbit LED = P1^7;
sbit KEY = P1^0;
void main(void){
KEY = 1;
LED = 1;
while(1){
/*
使用if判断语句实现按下按键LED灯亮,
松开按键LED灯灭
*/
/*
if(KEY == 0){
LED = 0;
}else if(KEY == 1){
LED = 1;
}
*/
// 讨巧的方式实现按键控制灯亮灭
LED = KEY;
}
}
3.2.按键轮训控制灯开关
1.课题描述
当按键第一次按下松开后开灯,第二次按下按键松开后关灯。
2.实现程序
/*************************************************************
* 程序名: 第一次按下按键LED灯亮,第二次按下按键LED灯灭,如此循环
* 编写人: bruce
* 硬件支持:TC12C2052 外部12MHZ晶振
* 日 期: 2023-11-14
* 修改日志:
/*************************************************************/
#include<STC12C2052AD.H>
sbit LED = P1^7;
sbit KEY = P1^0;
/*********************************************************************************************
函数名:毫秒级CPU延时函数
调 用:DELAY_MS (?);
参 数:1~65535(参数不可为0)
返回值:无
结 果:占用CPU方式延时与参数数值相同的毫秒时间
备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
/*********************************************************************************************/
void DELAY_MS (unsigned int a){
unsigned int i;
while( --a != 0){
for(i = 0; i < 600; i++);
}
}
void main(void){
KEY = 1;
LED = 1;
while(1){
if(KEY == 0){
/*
DELAY_MS()延时函数的作用是去掉按下按键抖动造成信号不稳定,导致程序失灵。
当按下按键后让程序稍等一会跳过按键抖动时刻,再读取按键状态达到去抖动效果。
*/
DELAY_MS(120);
if(KEY == 0){
//当按键为0时,判断当前灯的状态,并取反。实现轮训控制灯的开关。
if(LED == 0){
LED = 1;
}else{
LED = 0;
}
}
}
}
}
上面的程序虽然实现了按键控制灯的亮灭功能,但是它有两点不完美,需要优化。优化点如下
- 嵌入了三层if判断语句,是程序变得复杂不易阅读。
- 只通过延时决绝按键抖动,偶尔还会出现失灵的情况。
下面的程序对该两点内容做了优化,使程序更加晚上。
/*************************************************************
* 程序名: 第一次按下按键LED灯亮,第二次按下按键LED灯灭,如此循环
* 编写人: bruce
* 硬件支持:TC12C2052 外部12MHZ晶振
* 日 期: 2023-11-14
* 修改日志:
/*************************************************************/
#include<STC12C2052AD.H>
sbit LED = P1^7;
sbit KEY = P1^0;
/*********************************************************************************************
函数名:毫秒级CPU延时函数
调 用:DELAY_MS (?);
参 数:1~65535(参数不可为0)
返回值:无
结 果:占用CPU方式延时与参数数值相同的毫秒时间
备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
/*********************************************************************************************/
void DELAY_MS (unsigned int a){
unsigned int i;
while( --a != 0){
for(i = 0; i < 600; i++);
}
}
void main(void){
KEY = 1;
LED = 1;
while(1){
if(KEY == 0){
/*
DELAY_MS()延时函数的作用是去掉按下按键抖动造成信号不稳定,导致程序失灵。
当按下按键后让程序稍等一会跳过按键抖动时刻,再读取按键状态达到去抖动效果。
*/
DELAY_MS(120);
if(KEY == 0){
//当按键为0时,判断当前灯的状态,并取反。实现轮训控制灯的开关。
LED = ~LED;
//当按键按下没有松开时则一直做空循环,直到松开,while(1)才开始新的一轮循环。增强了按键控制灯的稳定性。
while(KEY == 0);
}
}
}
}