51单片机独立按键控制流水灯方向及状态(利用中断)

前言

在此篇文章中,默认读者已经掌握 51单片机定时器中断初始化以及使用 独立按键的读取等的基本使用方法,以下内容仅为对此的应用,若还未掌握,则可以在学习过后(可以参考B站江协视频)再来学习本篇文章。
文末附有主函数源码以及讲解

先展示结果

51单片机独立按键控制流水灯方向及状态(利用中断)

对现象进行简单说明

再次使用上篇文章内容说明现象,四个独立按键从左至右依次为S1,S2,S3,S4
在简单的流水灯基础上,S1使流水灯向左,S2使流水灯向右,S3使流水灯停止,S4使流水灯继续暂停前方向

观前提示

在芯片中,所有的逻辑判断与赋值包括之后使用的goto语句跳转运行时间都是极快的,若你在阅读内容的过程中出现疑惑,可以好好的想想这句话,或许能帮到你

利用中断

首先,流水灯肯定需要某种时间间隔来实现,以目前的知识,仅有Delay()函数和定时器中断。 而本次打算使用按键来改变流水灯的方向及状态,可在使用Delay()函数时,芯片会被占用,无法及时响应对按键的读取和处理(当按下并松开按键完成一次点击时,若函数在Delay函数中延时则会使程序忽略此次输入)。 而使用中断则可以在主函数的循环中不断读取按键状态,转而在中断函数中实现流水灯,以及判断按键来实现目的结果。

goto函数

程序中使用的goto函数可能某些读者并不常用,故在此做简单补充,若已掌握可跳过此部分。

goto label;       label: xxx;

…   ​​​​​​​           或     …

label: xxx;         goto label;

其中label只是一个标记,其可以是任意一个有效的标识符,当程序执行到goto语句时,它会立即跳转到label所指定的位置,并从该位置开始执行代码。

以下为main函数部分

#include <REGX52.H>
#include <INTRINS.H>
#include "Timer0.h"
#include "Key.h"
unsigned char KeyNum,LEDMode=1;
void main()
{
	Timer0_Init();
	P2=0XFE;
	while(1)
	{
		KeyNum=Key();
		switch(KeyNum)
		{
			case 1:
				LEDMode=0;break;
			case 2:
				LEDMode=1;break;
			case 3:
				LEDMode=2;break;
			case 4:
				LEDMode=3;break;
			default:
				break;
		}
	}
}

void T0Routine() interrupt 1
{
	static unsigned char Pre,T0Count=0;
	T0Count++;
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0x4C;				//设置定时初始值
	if(T0Count>=10)
	{
		T0Count=0;
		a:switch(LEDMode)
		{
			case 0:
				P2=_cror_(P2,1);Pre=LEDMode;break;
			case 1:
				P2=_crol_(P2,1);Pre=LEDMode;break;
			case 2:
				break;
			case 3:
				LEDMode=Pre;goto a;
		}
	
	}


}

内容讲解

经过初始化和点亮第一颗LED灯,就进入了主函数(声明的全局变量会在之后讲解)

main函数
1:首先读取独立按键,相对应将KeyNum附为1、2、3、4,若没有按按键,Key()函数的返回值为零
2:之后进入switch语句,KeyNum相对应给LEDMode四种情况。若未按按键,则KeyNum为0,故退出switch语句又重新进入while(1)的循环

中断函数
正式介绍前需先讲解一下_crol_和_cror_函数(l和r为left和right)。 它们都需要两个参数,第一个为被操作对象,第二个为位移动的位数。 在本文中分别为 P2 和 1 。 即 将P2向左(右)位移一位,与<<和>>的区别我将用一个例子解释,若使用_crol_(向左)时,当P2=0111 1111之后再左移时会为1111 1110。更详细的讲解读者可自行学习,本文不过多解释

本人的51单片机频率为11.0952,则给定时器赋赋值,以及if(T0Count>=10)结果为每500ms进入一次中断。   进入中断后判断LEDMode的值
按S1时 LEDMode为0,对应结果则P2右移,即向0(亮灯位)向低位移动,在本人的板子上表现为左移(若您的板子与我相反可以自行做简单调整)。
按S2时 与上同理,故略过。
按S3时 LEDMode为2,即执行空语句,即P2不进行位移,在单片机上表示为停止
按S4时 LEDMode为3,将Pre的值(即暂停前的LEDMode)赋给LEDMode,并通过goto语句再次回到switch()语句前(使用goto语句而不是退出等待下一次中断,可使当流水灯运行时按下S4并不改变流水灯的原有频率)

后记

以上即为所有讲解,因作者水平有限和时间原因,有些部分可能讲解的并不清晰,若有疑问可私信问我,若需要源码,也可将全部源码发送。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值