3-独立按键控制LED

发布时间 2023-12-31 00:48:13作者: Jinx8823

3-1独立按键控制LED亮灭

1.首先知道独立按键的位置是哪几个,独立按键位置如下所示

image-20230530232905329

2.寻找独立按键对应的IO口是哪一个,我们根据开发板原理图进行寻找

独立按键原理图:

image-20230530233149866

对应的是MCU的P3.1,这个对应的有点偏移不要看错了

image-20230530233407633

3.找到对应的IO口之后我们就可以开始编写程序了

首先回顾一下之前的内容,我们之前是用P2的8位来控制8个LED是0或1,这里我们尝试就用1位来精确控制

在这个#include <STC89C5xRC.H> (对应自己的开发板)中我们可以找到单独控制一个LED的变量或者说是寄存器

//这是在头文件中找到的内容
sfr P2   = 0xA0;
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;//这个P27的内容来决定最右边那个LED的亮和灭,默认为1不亮,为0亮
//其他几个分别对应其他几个LED,和up主讲的开发板不太一样

然后我们还要找到控制独立按键的那个变量或者说是寄存器

//头文件中有这样一段内容
sfr P3   = 0xB0;
sbit P30 = P3^0;
sbit P31 = P3^1;//根据原理图,我们知道P31控制的是最左边的独立按键
sbit P32 = P3^2;
sbit P33 = P3^3;
sbit P34 = P3^4;
sbit P35 = P3^5;
sbit P36 = P3^6;
sbit P37 = P3^7;

现在我们就根据P31(也就是最左边那个独立按键)的值来决定LED的亮和灭

#include <STC89C5xRC.H>

void main()
{
	while(1)
	{
		if(P31==0)		//为0表示独立按键按下
		{
			P27=0;		//此时LED亮,P27值为0时才会导通,LED才会亮
		}
		else			
		{
			P27=1;		//否则LED灭
		}	
	}
}

P31,P30一同按下时才亮,也就是左边的两个独立按键

#include <STC89C5xRC.H>

void main()
{
	while(1)
	{
		if(P31==0 && P30==0)//两个独立按键同时按下,LED才亮
		{
			P27=0;//LED亮
		}
		else	
		{
			P27=1;//LED灭
		}	
	}
}

或运算,一个按键按下LED就发光

#include <STC89C5xRC.H>

void main()
{
	while(1)
	{
		if(P31==0 || P30==0)//独立按键按下
		{
			P27=0;//LED亮
		}
		else	
		{
			P27=1;//LED灭
		}	
	}
}

因为switch语句不怎么用,所以也记一下

switch(变量)
{
    case 常量1:语句体1;break;
    case 常量2:语句体2;break;
    (...)
    default:语句体x;break;
}

输入几,就会执行case几

#include <stdio.h>
int main(){
    int a;
    printf("Input integer number:");
    scanf("%d",&a);
    switch(a){
        case 1: printf("Monday\n"); break;
        case 2: printf("Tuesday\n"); break;
        case 3: printf("Wednesday\n"); break;
        case 4: printf("Thursday\n"); break;
        case 5: printf("Friday\n"); break;
        case 6: printf("Saturday\n"); break;
        case 7: printf("Sunday\n"); break;
        default:printf("error\n"); break;
    }
    return 0;
}

3-2独立按键控制LED状态

因为独立按键存在抖动现象,所以需要写个延迟函数取消抖动,一般抖动的时间的在5-10ms,写的抖动函数只要时间比这个长就可以了。

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

#include <STC89C5xRC.H>

void Delay(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
	while(xms)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
		xms--;		
	}
	
}

void main()
{
	while(1)
	{
		if(P31==0)
		{
			Delay(20);//刚开始按下需要消除抖动
			while(P31==0);//如果一直处于按下状态,则LED不响应,如果松开LED就开始响应
			Delay(20);//松开后取消抖动
			P27=~P27;//每一次按下都改变亮灭状态
		}
	}
}

3-3独立按键控制LED显示二进制

由于这个板子对应的LED灯和视频中相反,暂时只能实现从左往右的二进制,暂时无法实现从右往左的二进制

不过逻辑上也已经实现了类似的功能,只是LED的位置相反,所以看起来是从右往左的二进制变化

#include <STC89C5xRC.H>

void Delay(unsigned xms)		//@11.0592MHz
{
	unsigned char i, j;

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

void main()
{
	unsigned char LEDnum=0;
	while(1)
	{
		if(P31==0)
		{
			Delay(20);
			while(P31==0);
			Delay(20);
			
			LEDnum++;//0000 0000->0000 0001->0000 0010......
            //要实现LED灯的亮,要让LED的那一位为0才行,所以加一个取反符号
			P2=~LEDnum;
		}
	}
}

3-4独立按键控制LED移位

首先写出它的二进制顺序:

0000 0001 0x01<<0

0000 0010 0x01<<1

0000 0100 0x01<<2

0000 1000 0x01<<3

......

不断往左移

STC89C52代码:

#include <REGX52.H>
void Delay(unsigned xms)		//@12MHz
{
	unsigned char i, j;

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

unsigned char LEDnum;
void main()
{
	P2=~0x01;
	while(1)
	{
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			
			LEDnum++;
			if(LEDnum>=8) 
				LEDnum=0;
			P2=~(0x01<<LEDnum);
			
		}
		if(P3_0==0)
		{
			Delay(20);
			while(P3_0==0);
			Delay(20);
			
			if(LEDnum==0)
				LEDnum=7;
			else
				LEDnum--;
			P2=~(0x01<<LEDnum);
            /*因为是对0x01进行控制的,所以这里也可以左移,只是左移位数少了,看起来就像是在右移*/
		}
	}
}

STC89C52RC代码:

锻炼自己逆向思维的能力,因为LED灯相反,其实我们应该实现的就是从LED8~LED1一个个左移(看起来是左移,在内部程序中应该是右移)

1000 0000 0x80>>0

0100 0000 0x80>>1

0010 0000 0x80>>2

0001 0000 0x80>>3

......

#include <STC89C5xRC.H>
void Delay(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;

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

unsigned char LEDnum;
void main()
{
	P2=~0x80;//因为LED位置相反,所以要达到视频中的那种效果,要采取右移策略
	while(1)
	{
		if(P31==0)
		{
			Delay(20);
			while(P31==0);
			Delay(20);
			
			LEDnum++;
			if(LEDnum>=8)
				LEDnum=0;
			P2=~(0x80>>LEDnum);
		}
		if(P30==0)
		{
			Delay(20);
			while(P30==0);
			Delay(20);
			
			if(LEDnum==0)
				LEDnum=7;
			else 
				LEDnum--;
			P2=~(0x80>>LEDnum);
			 /*因为是对0x01进行控制的,所以这里也可以左移,
			只是左移位数少了,看起来就像是在右移*/
		}
	}
}