C51学习

文章介绍了如何使用C语言编程实现开关按键控制灯的逻辑,包括基本的按键状态检测、两灯控制和通过软件消抖技术处理按键抖动问题。还讨论了如何优化代码结构以提高实时性和使用标志位管理状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查询法按键控制灯

在这里插入图片描述
当SW1被按下时,KEY1接通GND表现为低电平,值为0
当SW1未被按下时,KEY1接5V表现为高电平,值为1
在这里插入图片描述
查询电路图发现KEY1接在P2.1口

#include "reg52.h"

sbit key1 = P2^1;
sbit led1 = P3^7;
sbit led2 = P3^6;


void main()
{
		while(1){
			if(key1 == 0){	//当SW1被按下时,KEY1接通GND表现为低电平,值为0
				led1=0;
				led2=0;
			}else{
				led1=1;
				led2=1;
			}
		}
}

通过上述代码实现,按下SW1两盏灯亮松开后两盏灯灭的效果。
如果要实现按下SW1灯亮,按下SW1灯灭的效果只需进行简单的修改即可,代码如下:

#include "reg52.h"

sbit key1 = P2^1;
sbit key2 = P2^0;
sbit led1 = P3^7;
sbit led2 = P3^6;


void main()
{
		while(1){
			if(key1 == 0){	//当SW1被按下时,KEY1接通GND表现为低电平,值为0
				led1=0;
				led2=0;
			}
			if(key2 == 0){	//当SW2被按下时,KEY2表现为0
				led1=1;
				led2=1;
			}
		}
}

按键的软件消抖

什么叫消抖?
为了防止硬件老化后,导致板子一抖动就点亮灯或者出现按键松动的情况,因此需要对抖动现象就行消除操作,因为抖动发生的速度很快,因此只需要延迟一段时间,进行判断即可,这就是软件消抖

#include "reg52.h"
#include <intrins.h>

sbit key1 = P2^1;
sbit key2 = P2^0;
sbit led1 = P3^7;
sbit led2 = P3^6;

void Delay20ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 216;
	k = 35;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
		while(1){
			if(key1 == 0){	//当SW1被按下时,KEY1接通GND表现为低电平,值为0
				//第一次被按下,不知道时抖动还是人为的,延迟50ms再判断,实现软件消抖
				Delay20ms();
				if(key1 == 0){
					led1=0;
					led2=0;
				}	
			}
			if(key2 == 0){	//当SW2被按下时,KEY2表现为0
				Delay20ms();
				if(key2 == 0){
					led1=1;
					led2=1;
				}
			}
		}
}
 

IO口状态翻转

如果想要实现,每按一次按钮使小灯状态发生改变的效果,只需要利用!取反字符进行操作即可:

#include "reg52.h"
#include <intrins.h>

sbit key1 = P2^1;
sbit key2 = P2^0;
sbit led1 = P3^7;
sbit led2 = P3^6;

void Delay20ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 216;
	k = 35;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
		led1 = 1;
		led2 = 1;
		while(1){
			if(key1 == 0){	//当SW1被按下时,KEY1接通GND表现为低电平,值为0
				//第一次被按下,不知道时抖动还是人为的,延迟50ms再判断,实现软件消抖
				Delay20ms();
				if(key1 == 0){
					led1 = !led1;
					led2 = !led2;
				}	
			}
			if(key2 == 0){	//当SW2被按下时,KEY2表现为0
				Delay20ms();
				if(key2 == 0){
					led1 = !led1;
					led2 = !led2;
				}
			}
		}
}

此时实现按一次按键灯的状态就会发生变化,且长按会持续间隔20ms闪烁。
在代码量较大的情况下或者对于实时性要求较高的业务流程中,使用标志位来替代0/1会更好,规范化处理:

#include "reg52.h"
#include <intrins.h>

#define OFF_STATUS 1
#define ON_STATUS 0

sbit key1 = P2^1;
sbit key2 = P2^0;
sbit led1 = P3^7;
sbit led2 = P3^6;

void Delay20ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 216;
	k = 35;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
		int ledMark = OFF_STATUS;
		led1 = 1;
		led2 = 1;
		while(1){
			if(key1 == 0){	//当SW1被按下时,KEY1接通GND表现为低电平,值为0
				//第一次被按下,不知道时抖动还是人为的,延迟50ms再判断,实现软件消抖
				Delay20ms();
				if(key1 == 0){
					ledMark = ON_STATUS;
				}	
			}
			if(key2 == 0){	//当SW2被按下时,KEY2表现为0
				Delay20ms();
				if(key2 == 0){
					ledMark = OFF_STATUS;
				}
			}
			if(ledMark == OFF_STATUS){
				led1 = 1;
				led2 = 1;
			}else{
				led1 = 0;
				led2 = 0;
			}
		}
}
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值