速通51单片机————点亮LED与控制LED

本章将介绍LED的点亮操作,以及如何用按键控制LED。

由于是速通,并不是傻瓜式教学,故具体的文件操作与烧录过程就不一一展示了,注重具体的代码实现与原理,具体过程请看下面给出的视频链接,看过一次操作即可。

前置知识为:C语言基础(这个很重要),以及数电的进制转换基础,以及:自备51单片机(博主的单片机为共阳连接)以及对应的软件,详细请看B站视频: 1-2 开发工具介绍及软件安装_哔哩哔哩_bilibili

下面简单介绍一下数电的进制转换基础(二进制与十六进制的相互转换)

前置知识(数电进制转换与共阳连接及共阴连接)

进制转换

由于在计算机中都是采用二进制,而在代码中我们需要写入十六进制,故我们只需要二进制与十六进制相互转换的关系即可,其中二进制的四位从左到右依次对应十六进制的8 4 2 1,例如1101就是8+4+1=13。

共阳连接

共阳连接即对应着:

0------灯亮

1------灯灭

共阴连接

共阴连接即对应着:

0------灯灭

1------灯亮

一、点亮第一个LED灯

在本章中使用的51单片机中共有8个灯,对应着两组二进制,而51单片机中的P2端口则对应着八个灯,通过两组二进制来控制,但是实际上是用两个十六进制的数,

如下:该情况就对应着LED灯间隔亮暗

cpp 复制代码
#include <REGX52.H>

void main()
{
	P2=0xAA;//1010 1010
	
}

二、令LED灯闪烁

只需要让一个灯在01之间来回循环即可,但是在语句之间执行速度很快,所以需要delay延迟,在stc-isp中会有延迟时间函数可以自动生成,这里直接就拿来用就好。

cpp 复制代码
#include <REGX52.H>
#include <INTRINS.H>

void Delay500ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 205;
	k = 187;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{

	while(1)
	{
		P2=0xFE;//1111 1110
		Delay500ms();
		P2=0xFF;//1111 1111
		Delay500ms();		
	}
}

三、使LED灯流水线式闪烁

这个本质是和上面一样的,通过输入给P2不同的进制,加上循环,从而达到不同的灯流水线式的闪烁,可以看下面代码的注释,0代表亮,1代表灭

cpp 复制代码
#include <REGX52.H>
#include <INTRINS.H>

void Delay500ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 205;
	k = 187;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
	while(1)
	{
		P2=0xFE;//1111 1110
		Delay500ms();
		P2=0xFD;//1111 1101
		Delay500ms();
		P2=0xFB;//1111 1011
		Delay500ms();
		P2=0xF7;//1111 0111
		Delay500ms();
		P2=0xEF;//1110 1111
		Delay500ms();
		P2=0xDF;//1101 1111
		Delay500ms();
		P2=0xBF;//1011 1111
		Delay500ms();
		P2=0x7F;//0111 1111
		Delay500ms();		
	}
}

我们不能一直依靠软件生成的延迟函数来固定延迟

可以尝试生成1毫秒的延迟代码,通过构造形参的方式,传入我们需要循环的次数,例如x次,那么就会循环x*1毫秒

cpp 复制代码
#include <REGX52.H>
#include <stdio.h>



void Delay1ms(unsigned int x)		//@12.000MHz
{
	unsigned char i, j;
	
	while(x)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		x -= 1;
	}
}

void main()
{
	while(1)
	{
		P2=0xFE;//1111 1110
		Delay1ms(100);
		P2=0xFD;//1111 1101
		Delay1ms(100);
		P2=0xFB;//1111 1011
		Delay1ms(100);
		P2=0xF7;//1111 0111
		Delay1ms(100);
		P2=0xEF;//1110 1111
		Delay1ms(100);
		P2=0xDF;//1101 1111
		Delay1ms(100);
		P2=0xBF;//1011 1111
		Delay1ms(100);
		P2=0x7F;//0111 1111
		Delay1ms(100);		
	}
}

四、使用独立按键控制LED灯

P3_1为第一个独立按键的按钮,按下则代表为0,松开则代表为1,此时我们只需要判断好按钮的状态,从而进入条件使灯亮暗即可。

控制LED灯亮灭

cpp 复制代码
#include <REGX52.H>

void main()
{
	while(1)
	{
		if(P3_1 == 0)//按下按键
		{
			P2_0 = 0;//亮
		}
		else
		{
			P2_0 = 1;//否则为暗
		}
	}
}

控制LED灯状态

按下按钮之后,让灯亮或者灯灭,我们需要利用按位取反的性质,单独对某个灯的状态按位取反,就能实现对某个灯的亮暗操作了,我们知道P2对应着八个灯,那么P2_0则对应着其中一个灯,我们就单独控制这个就好。

在物理世界中,按键按下时由于会有微小弹性,所以按下之后的短暂时间内会有回弹,此时如果不控制这段时间的话就会出现按下之后会有多次瞬间闪烁,那么我们就需要在按下之后消除掉这短暂的时间,也就是delay一下,再执行接下来的语句。当然,在松开之后同样需要消除一下短暂的时间

cpp 复制代码
#include <REGX52.H>

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


void main()
{
	while(1)
	{
		if(P3_1 == 0)//当按下按钮
		{
			Delay(20);//消除短暂时间
			while(P3_1 == 0);//如果一直按着还没松开则一直循环不动
			Delay(20);//松开后,消除短暂时间
			//此时完成一次按下松开的操作
			P2_0 =~ P2_0;//灯亮或者灯灭
		}
	}
}

控制LED灯显示二进制

首先要知道,我们让P2每加一,那么就会从0000000->00000001,此时自身取反就成了11111110,那么就是第一颗灯亮了,我们就按照这个就能控制LED灯显示二进制即可,那么步骤就是检测到按下抬起按键一次。为了方便起见,我们就不直接控制P2,我们另设一个char变量来传给P2。

cpp 复制代码
#include <REGX52.H>

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

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

void main()
{
	unsigned char LEDNum = 0;//传给P2的参数
	while(1)
	{	
		if(P3_1 == 0)
		{
			Delay(20);
			while(P3_1 == 0);
			Delay(20);
			
			LEDNum++;
			P2 =~ LEDNum;
		}
	}
}

控制LED灯移位

利用LEDNum的计数来操控变量00000001**(0x01)**左移或者右移的位数

左移:令LEDNum++,一旦≥8,则复位0,然后进行左移LEDNum位。

右移:令LEDNum--,一旦≤0,则复位7,然后进行右移LEDNum位。

当移动完成后,再按位取反赋值给P2即可完成操作。

由于char变量是无符号,所以在判断右移的情况有稍微不同,具体如下代码所示

cpp 复制代码
#include <REGX52.H>

void Delay(unsigned int xms)		//@12.000MHz
{
	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);
			
			/*LEDNum--;
			if(LEDNum < 0)
			{
				LEDNum = 7;
			}*/
			
			if(LEDNum <= 0)
			{
				LEDNum = 7;
			}
			else
			{
				LEDNum--;
			}
			P2 =~ (0x01 << LEDNum);
		}
	}
}
相关推荐
梁朝辉2 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者3 小时前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间4 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious4 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng8 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计9 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
KaifuZeng1 天前
通信与接口协议面试一、基本概念
嵌入式硬件·通信与接口协议
wuyk5551 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机
☆cwlulu1 天前
调试排查工具介绍(gdb、strace、Valgrind等)
开发语言·c++·嵌入式硬件·ubuntu
lzqrzpt1 天前
LED驱动电源选型标准与工程应用技术要点解析
python·单片机·嵌入式硬件·物联网