51单片机学习记录——独立按键控制LED

本文详细介绍了使用51单片机通过独立按键控制LED的亮灭、状态切换、二进制显示和移位功能,同时讨论了按键抖动问题及其解决方案。作者通过实际编程和调试过程,分享了遇到的问题与解决方法,适合初学者学习51单片机基础应用。

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

目录

独立按键

今日任务一:独立按键控制LED的亮灭

今日任务二: 独立按键控制LED的状态

今日任务三:独立按键控制LED显示二进制

今日任务四:独立按键控制LED移位

今日所遇到的问题

总结


独立按键

        轻触按键,相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力谭东来实现接通和断开。独立按键模块开发原理图如下,注意P31和P30分别控制的是K1和K2!!

        今天的主要任务就是通过对独立按键进行编程,可以通过轻触按键以达到控制LED的功能。

今日任务一:独立按键控制LED的亮灭

        思路分析:此任务拟使用K1按钮来控制LED,所以我们就需要对P3_1寄存器进行赋值,当P3_1==0时,表示此按键被按下,LED亮,当P3_1!=0时,就表示按键没有被按下,LED灭,意思就是长按灯亮,不按灯灭。所以我们可以通过if语句来作判断,于此同时还需要加上一个while循环将其包裹,以至于可以重复判断,其代码如下所示: 

#include <REGX52.H>
void main()
{
	 while(1)
	 {
	  	if(P3_1==0)
		{
		    P2_0=0;
		}
		else
		{
			P2_0=1;
		}	
	 }
}

任务一还是比较容易实现的。

今日任务二: 独立按键控制LED的状态

        思路分析:有了任务一的基础,我想通过轻触一下来控制LED的状态应该很容易了吧,同样通过if语句就可以实现了,只是需要判断一下K1按键是否被按下即可以及是否松开就可以了,那如何判断按键是否松开了呢?可以通过一个空while语句来实现,如果检测到K1按键一直被按下,就将程序阻断,松开后才能进行下一步操作,由于是控制LED灯的亮灭,每次操作只需要将P_2取反就行,所以就有了以下的代码:

#include <REGX52.H>
void main()
{
	while(1)
	{
		if(P3_1==0)
		{
			while(P3_1==0);//阻断 判断按键有没有松开
			P2_0=~P2_0;
		}

	}
}

下载到板子上面之后,确实实现了我们需要的功能,但是这样真的完美吗?

        下面补充一点按键的抖动的知识:对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动,大概如下图所示:

其抖动时间很短,大概只要5-10ms,所以我们刚刚的我们看到实验现象是正常的,这是因为人眼分辨不出来。需要延时20ms

### 实现 C51 单片机独立按键控制 LED 流水方向变化 以下是基于 C51 单片机实现独立按键控制 LED 流水方向变化的一个示例代码。此代码利用了一个外部按键输入来切换流水的方向。 #### 示例代码 ```c #include <reg52.h> sbit KEY = P3^0; // 定义按键到P3.0引脚 unsigned char dir_flag = 1; // 方向标志位,1表示正向,0表示反向 unsigned char led_data[] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}; // 流水数据数组 void delay(unsigned int time) { unsigned int i, j; for (i = 0; i < time; i++) { for (j = 0; j < 120; j++); // 延时函数 } } void main() { while(1) { if(KEY == 0) { // 检测按键按下 delay(20); // 消抖处理 if(KEY == 0) { dir_flag = !dir_flag; // 切换方向标志位 while(!KEY); // 等待按键释放 } } static unsigned char index = 0; if(dir_flag) { // 正向流动 P1 = led_data[index]; index++; if(index >= sizeof(led_data)) { index = 0; } } else { // 反向流动 P1 = led_data[sizeof(led_data)-index-1]; index++; if(index >= sizeof(led_data)) { index = 0; } } delay(500); // 设置延时时间 } } ``` 上述代码实现了通过一个独立按键改变 LED 流水的流动方向功能[^1]。具体来说: - 使用 `KEY` 引脚作为外部按键输入口。 - 当检测到按键被按下时,程序会切换流水的移动方向,并更新变量 `dir_flag` 的值。 - 如果 `dir_flag` 为 1,则按照正向顺序点亮流水;如果为 0,则按逆序点亮流水。 - 数据存储在数组 `led_data` 中,用于定义每一步流水的状态。 #### 关键点说明 - **消抖处理**:为了防止机械按键因弹跳引起误触发,在检测到按键闭合后加入了一定的时间延迟以确认信号稳定性[^3]。 - **双向循环机制**:通过调整索引计算方式支持两种不同的遍历模式——从前至后或者从后往前访问数组中的元素。 - **硬件配置需求**:需将八个LED分别单片机的P1端口上,并确保电源供电正常以及限流电阻的存在以便保护电路元件安全工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值