51单片机从零开始入门教程 第三章(独立按键篇)

本文介绍了如何使用独立按键控制LED灯的亮灭、消除抖动、二进制计数和移位操作,包括原理、代码示例和实际操作步骤。

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

参考教程:[3-1] 独立按键控制LED亮灭_哔哩哔哩_bilibili

一、按键相关知识

1、按键原理

        按键相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现电路的接通和断开。

2、按键抖动

        对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。

二、开发板中的按键模块

        开发板原理图中的独立按键模块显示,按键的一端接地,另一端与寄存器P3相连,按下按键,P3中相应的位被置为0,松开按键,P3中相应的位被置为1,程序可以获取寄存器P3中的状态进行相应的操作

        按键连接的引脚采取的是弱上拉模式,换句话说,当按键不导通时,引脚通过电阻与正电压VCC相连,这时引脚为高电平,当按键导通时,受上拉电阻影响,VCC不能与GND“抗衡”,引脚会受GND影响而处于低电平,不过弱上拉模式的缺点就是高电平驱动能力并不是很好,因为弱上拉电阻的存在会让高电平“并不是那么高”。

三、按键控制LED灯实验

1、独立按键状态控制LED灯状态实验

(1)在main.c文件中输入以下代码,然后点击“编译”。

#include <REGX52.H>

void main()
{
	while(1)
	{
		if(P3_0 == 0)  //P3中的0号位被置为0,检测到按键被按下
			P2_0 = 1;  //单独对P2的0号位进行操作,按下按键时该位对接的LED灯不亮
		else
			P2_0 = 0;  //如果按键未被按下,LED灯常亮
	}
}

(2)按照上一例的操作将生成的.hex文件写进开发板,按动K2按键(K2按键对应P3的0号位)即可观察现象。

2、独立按键控制LED灯状态实验

(1)在main.c文件中输入以下代码,借助延时函数进行按键消抖,然后点击“编译”。

#include <REGX52.H>
#include <INTRINS.H>  //_nop_()需要这个头文件

void Delay(unsigned int xms)		//对借助STC-ISP生成的1ms延时函数进行修改
{
	while(xms)  //让1ms延时函数重复执行xms次
	{
		unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
	xms--;  //smx作为计数器
	}
}

void main()
{
	while(1)
	{
		if(P3_1 == 0)  //如果按下按键
		{
			Delay(20);  //消除按下按键时的抖动
			while(P3_1 == 0); //抖动结束后如果仍未松开开关,LED灯保持原状
			Delay(20);  //松开按键后上面的循环结束,消除松开按键的抖动
			P2_0 = ~P2_0;  //LED灯状态反转
		}
		//每按一次按键,LED灯状态反转一次
	}
}

(2)按照上一例的操作将生成的.hex文件写进开发板,按动K1按键(K1按键对应P3的1号位)即可观察现象。

3、独立按键控制LED进行二进制计数实验

(1)在main.c文件中输入以下代码,借助延时函数进行按键消抖,然后点击“编译”。

#include <REGX52.H>
#include <INTRINS.H>  //_nop_()需要这个头文件

void Delay(unsigned int xms)		//对借助STC-ISP生成的1ms延时函数进行修改
{
	while(xms--)  //让1ms延时函数重复执行xms次
	{
		unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
	}
}

void main()
{
	P2 = 0xFF;  //P2初始化为1111 1111(P2默认的初始状态也是如此)
	
	while(1)
	{
		static unsigned char LEDNum = 0;  //char类型占8位,正好对应P2的8位
		//注:unsigned char LEDNum = 0;可以写在循环体外
		//但是本人的编译器貌似不允许我这么干,所以才使用static关键字在循环体内部定义计数变量
		//加了static关键字后该变量只定义一次,不会重复定义以及重复置为0
		if(P3_1 == 0)  //每按下一次按键,计数值加一
		{
			Delay(20);
			while(P3_1 == 0);
			Delay(20);
			
			LEDNum++;  //使用LEDNum进行计数
			P2 = ~LEDNum;  //因为LED是低电平驱动,所以计数结果取反才符合需求
		}
	}
}

(2)按照上一例的操作将生成的.hex文件写进开发板,按动K1按键(K1按键对应P3的1号位)即可观察现象。

4、独立按键控制LED移位实验

(1)在main.c文件中输入以下代码,然后点击“编译”。

#include <REGX52.H>
#include <INTRINS.H>  //_nop_()需要这个头文件

void Delay(unsigned int xms)
{
	while(xms--)
	{
		unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
	}
}

unsigned char LEDNum = 0;  //定义全局变量并初始化为0

void main()
{
	P2 = 0xFE;  //将P2配置为1111 1110,让第一盏LED灯先亮
	while(1)
	{
		if(P3_1 == 0)  //每按一次K1按键,当前LED灯熄灭,下一个LED灯被点亮
		{
			Delay(20);
			while(P3_1 == 0);
			Delay(20);
			LEDNum++;
			if(LEDNum>=8)  //一轮循环结束,下一个被点亮的LED灯回到第一盏
				LEDNum = 0;
			P2 = ~(0x01 << LEDNum);  //借助左移运算符简化代码(LED是低电平驱动,记得取反)
		}
	}
}

(2)按照上一例的操作将生成的.hex文件写进开发板,按动K1按键(K1按键对应P3的1号位)即可观察现象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zevalin爱灰灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值