【51单片机】按键操作(单个灯闪烁&&流水灯)

这篇具有很好参考价值的文章主要介绍了【51单片机】按键操作(单个灯闪烁&&流水灯)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🎊专栏【51单片机】

🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。

🎆音乐分享【如愿】

大一同学小吉,欢迎并且感谢大家指出我的问题🥰

目录

⭐注意

🍔同一个灯 

🏳️‍🌈效果

🏳️‍🌈代码

🏳️‍🌈问题分析

⭐注意

⭐P3_1=0,表示按下按键 

⭐为什么while(P3_1==0);后面要加上分号呢?

⭐两个Delay(20)的作用

⭐P2_0=~P2_0;

🍔不同灯(显示二进制移位)

🏳️‍🌈效果

🏳️‍🌈代码

🏳️‍🌈原因

🍔流水灯(按一下按键,灯亮的位置才会变化)(移位)

🏳️‍🌈效果

🏳️‍🌈代码

🏳️‍🌈解释 

 🍔流水灯(按一下,灯亮的位置自动改变)

🏳️‍🌈效果

🏳️‍🌈代码例子&&解释

main.c 

Timer0.c

🎆为什么主函数没有调用中断函数,但是中断函数为什么会执行呢 

Timer0.h

Key.c

Key.h

Delay.c

Delay.h


 文章来源地址https://www.toymoban.com/news/detail-429705.html

⭐注意

由图片可知,要使用P3口

【51单片机】按键操作(单个灯闪烁&&流水灯)

🍔同一个灯 

🏳️‍🌈效果

led灯闪烁

🏳️‍🌈代码

#include <REGX52.H>

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

	while(xms){
		i = 2;
		j = 239;
		do
		{
				while (--j);
			
		} while (--i);
		xms--;
	}
}

void main()
{
	while(1)
	{
		if(P3_1==0)//按下
		{
			Delay(20);
			while(P3_1==0);//仍然按下
			Delay(20);
			P2_0=~P2_0;
		}
	}
}

着重分析下面的代码

while(1)
    {
        if(P3_1==0)
        {
            Delay(20);
            while(P3_1==0)
            Delay(20);
            P2_0=~P2_0;
        }
    }

🏳️‍🌈问题分析

⭐注意

1.在这个程序里面,最好用类似于P3_1=0的代码,不要用类似于P2=0xFE的代码,因为后者很容易迷糊

(如果是流水灯,可以用P2=0xFE)

2.Delay()函数里面用的是自动延时代码,可以由软件自动生成,如果不明白是怎么肥四,可以参考下面这篇文章

【51单片机】使用STC烧录软件自动生成延时代码_在下 小吉的博客-CSDN博客

⭐P3_1=0,表示按下按键 

为什么while(P3_1==0);后面要加上分号呢?

在观察现象的时候发现,按一次松手,灯亮了再按一次松手,灯灭了

所以,这样子主要是为了一直按着按键的时候,防止灯亮

(而且不能改为P3_1=0,因为这里必须是循环语句或者判断语句)

⭐两个Delay(20)的作用

如图

【51单片机】按键操作(单个灯闪烁&&流水灯)

第一个Delay(20)是作用于前面抖动的部分

第二个Delay(20)是作用于后面抖动的部分(防止松手时影响灯的亮度) 

⭐P2_0=~P2_0;

就是控制LED的开关状态,使其可以闪烁

🍔不同灯(显示二进制移位)

🏳️‍🌈效果

多个led灯亮

🏳️‍🌈代码

#include <REGX52.H>

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

	while(xms){
		i = 2;
		j = 239;
		do
		{
				while (--j);
			
		} while (--i);
		xms--;
	}
}

void main()
{
	unsigned char LEDNum=0;
	while(1)
	{
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			LEDNum++;
			P2=~LEDNum;
		}
	}
}

🏳️‍🌈原因

请看下图

【51单片机】按键操作(单个灯闪烁&&流水灯)

P2=~LEDNum;由于二进制数字的变化,所以会引起灯的变化

🍔流水灯(按一下按键,灯亮的位置才会变化)(移位)

🏳️‍🌈效果

WeChat_20230425133443

🏳️‍🌈代码

#include <REGX52.H>

unsigned char LEDNum;

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

	while(xms){
		i = 2;
		j = 239;
		do
		{
				while (--j);
			
		} while (--i);
		xms--;
	}
}

void main()
{
	
	while(1)
	{
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			
			if(LEDNum>=8) 
				LEDNum=0;
			
			P2=~(0x01<<LEDNum);
			LEDNum++;
				
		}
		
		if(P3_0==0)//多个按键操作
		{
			Delay(20);
			while(P3_0==0);
			Delay(20);
			
			if(LEDNum==0)//反方向的流水灯
				LEDNum=7;
			else
				LEDNum--;
			
			P2=~(0x01<<LEDNum);
		}
	}
}

🏳️‍🌈解释 

首先 led=0x01,而且LEDNum=0,因为 LED 是低电平点亮,所以 (0x01<<LEDNum) 取反 后的结果是 0xFE, 对应二进制数为 1111 1110,即最低位为 0,因此最开始的 D1 指示灯会点亮,然后延时一段时间进入while循环, 由于要实现8个LED从D1->D8 循环点亮,因此可以使用 for 循环语句循环 8 次,每循环一次,点亮的小灯向右 移动一个即 P2 口输出的低电平要左移一位,因此可以使用 P2=~(0x01<<i);语句实现。0x01<<LEDNum 表示每次 LEDNum 增加 1 次,0x01 中的 1 就移动多少位, 因为 1不会让 LED 点亮,需要取反后变为低电平 0 才能点亮,所以最后的结果需要
取反后给 P2 口

 🍔流水灯(按一下,灯亮的位置自动改变)

🏳️‍🌈效果

按键流水灯

🏳️‍🌈代码例子&&解释

main.c 

#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>

unsigned char KeyNum,LEDMode;

void main()
{
	P2=0xFE;
	Timer0Init();
	while(1)
	{
		KeyNum=Key();		//获取独立按键键码
		if(KeyNum!=0)			//如果按键按下
		{
			//if(KeyNum==1)	//如果K1按键按下
			//{
				LEDMode++;	//模式切换
				if(LEDMode>=2)LEDMode=0;
			//}
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;		//T0Count计次,对中断频率进行分频
	if(T0Count>=500)//分频500次,500ms
	{
		T0Count=0;
		if(LEDMode==0)			//模式判断
			P2=_crol_(P2,1);	//LED输出    
			//_crol_循环左移
		if(LEDMode==1)
			P2=_cror_(P2,1);
		  //_cror_循环右移
	}
}

_crol_循环左移

_cror_循环右移 

⭐使用定时器中断的原因(请看图片)

【51单片机】按键操作(单个灯闪烁&&流水灯)

Timer0.c

#include <REGX52.H>

/**
  * @brief  定时器0初始化,1毫秒@12.000MHz
  * @param  无
  * @retval 无
  */
void Timer0Init(void)
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
	PT0=0;
}

/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)
	{
		T0Count=0;
		
	}
}
*/

🎆为什么主函数没有调用中断函数,但是中断函数为什么会执行呢 

当调用Timer0Init()函数时,就会开启定时器0中断,并将中断服务函数的入口地址设置为Timer0_Routine()函数的地址(这个过程涉及到中断向量表的设置,一般由编译器完成)。而每当定时器0中断被触发时,就会跳转到Timer0_Routine()函数执行其中的代码。因此,即使主函数没有显式调用中断函数,中断函数也会被执行。 

上面一段代码不明白的同学可以参考一下这一篇博客

【51单片机】使用STC烧录软件生成定时器的代码以及注意事项_在下小吉.的博客-CSDN博客

Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init(void);

#endif

Key.c

#include <REGX52.H>
#include "Delay.h"

/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
	unsigned char KeyNumber=0;
	
	if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
	if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
	if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
	if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
	
	return KeyNumber;
}

【51单片机】按键操作(单个灯闪烁&&流水灯)

因为图片中的就是P3口

所以最好使用P3口的4个引脚(P3_0~P3_3)

Key.h

#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();

#endif

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

 上面一段代码不明白的同学可以参考一下这篇博客

【51单片机】使用STC烧录软件自动生成延时代码_在下小吉.的博客-CSDN博客

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

🥰如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正🥰  

 

到了这里,关于【51单片机】按键操作(单个灯闪烁&&流水灯)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 在51单片机中使用一个独立按键控制流水灯方向

    用独立按键控制流水灯转向,按下独立按键流水灯向右移动,再按下独立按键流水灯向左移动 此代码用到 逻辑左移:_crol_(移动对象,移动的位数) 逻辑右移:_cror_(移动对象,移动的位数)

    2024年02月07日
    浏览(12)
  • 51单片机入门 - 详解定时器实现按键控制流水灯方向

    操作系统:Windows 10 x84-64 单片机:STC89C52RC 编译器:SDCC 烧录软件:stcgal 1.6 开发板:普中51单片机开发板A2套件(2022) 在 VS Code 中新建项目到烧录的过程: 左侧EIDE图标 - 新建项目 - 空项目 - 8位MCU项目 - 保存文件夹。 更改构建配置: SDCC ;更改烧录配置: stcgal 。 在项目文件

    2024年02月06日
    浏览(10)
  • 【51单片机】独立按键,每个按键不同功能,数码管数值的加减,控制流水灯模式,包含按键消抖,数码显示,流水灯

    【51单片机】独立按键,每个按键不同功能,数码管数值的加减,控制流水灯模式,包含按键消抖,数码显示,流水灯

    实验内容: 利用所学的单片机知识及电路知识编程实现单片机 I/O 口检测按键输入电平。         1.选中 8 位数码管的其中 1 位数码管,当独立按键 1 每按下一次,数码管加一(按下期间加 1),范围为 0—F;         2.选中 8 位数码管的另 1 位数码管,当独立按键 2

    2024年02月06日
    浏览(11)
  • C51单片机按键控制流水灯模式(定时器版本)以及定时器时钟

    C51单片机按键控制流水灯模式(定时器版本)以及定时器时钟

      上篇文章我们学了关于定时器的三大组成部分及许多寄存器的概念问题,这篇文章我们就要开始讲解实操部分。 首先,我们先来看看本文最后写成的代码:      以上三张是代码的主函数,此外,代码中还需用到的独立按键检测代码在下面:  注意:头文件中#ifndef和#def

    2023年04月17日
    浏览(9)
  • 51单片机——一个独立按键控制LED的闪烁和熄灭

    目录 一、要求 二、实现 三、总结 消除按键的机械抖动         当按下按键,LED灯闪烁,再按下,LED熄灭。。。。循环操作。         编译环境:keil4         单片机:STC89c516RD 消除按键的机械抖动         按键的机械抖动会影响单片机对按键按下次数的判断。消除抖动的

    2024年02月07日
    浏览(14)
  • 51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示

    51单片机实验三:数码管显示时钟 按键调节时间时闪烁提示

    功能效果:1.时分秒的动态显示。2.用三个按键实现时分秒的修改,调节的数字闪烁提示。  

    2024年02月11日
    浏览(15)
  • STM32单片机 超入门项目:流水灯(不同闪烁模式和速度)

    STM32单片机 超入门项目:流水灯(不同闪烁模式和速度)

    流水灯通过交替闪烁实现灯光流动的效果,本篇将分析如何采用STM32单片机实现流水灯。 STM32单片机(STM32F103RCT6)、发光二极管 4(我用的是七彩快闪,用红绿蓝LDE自行搭配也可)、1k电阻 4、面包板飞线等自备。 打开STM32CubeMX,选择型号STM32F103RCT6,配置调试器PinoutConfigurati

    2023年04月09日
    浏览(11)
  • 【51单片机】键控流水灯

    设置k3作为启动键,只有先按下k3才能开始控制流水灯,按下k3后LED闪烁提示开始成功。 在按下k3后,其余键即可控制流水灯。其中k1执行从右到左,k2执行从左到右。 按下k4,执行外部中断,立马中止流水灯运行,需重新按下启动键重启。

    2024年02月06日
    浏览(10)
  • 51单片机实现流水灯

    51单片机实现流水灯

    我们之前说过可以控制管脚口电平来控制LED的亮灭,低电平灯亮,高电平灯灭,具体可以看我之前的博客。 P20~P27可以用八位二进制数来表示每一位的电平,第八位是P20,第一位是P27,那么11111110就代表P20亮,其他灭,11101111就代表P24亮,其他灭。流水灯的代码就可以写成这样

    2024年02月11日
    浏览(6)
  • 51单片机入门流水灯

    上次已经实现了LED的点亮了,这篇文章将带大家实现流水灯。 要想实现流水灯首先就得知道什么是延时函数,延时函数的作用就是等待。比如延时一毫秒就是让程序在这里等待一毫秒。延时函数的本质就是执行一些空指令,因为执行指令需要耗费时间,所以执行一定数量的空

    2024年02月04日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包