【单片机】LED模块和独立按键的使用

发布于:2022-11-11 ⋅ 阅读:(830) ⋅ 点赞:(0)


目录

一、原理介绍

1、LED灯的原理

2、电阻R1的作用

3、为什么D2二极管不用外接电阻?

4、点灯原理

二、点亮一个LED灯

电路分析

写法1:写明P2口每一位的状态

写法2:控制单个引脚

三、LED灯闪烁

代码

四、流水灯

写法1:使用数组

写法2:移位运算符

五、独立按键+点灯

1、独立按键原理

2、按键消抖

3、代码


一、原理介绍

1、LED灯的原理

LED灯称为发光二极管,具有单向导通性。当给D1发光二极管加上正向电压,它的电流方向是从左往右的,通过二极管内的电子与空穴的复合,形成电流释放能量,就可以发出特定颜色的光,释放的能量越多,光的波长就越短,从而使光的颜色不同。

LED自身也有电阻,会分走部分电压,电源所提供的电压必须大于二极管的管压降,二极管才有可能发光。硅管的管压降一般为0.7V,锗管的管压降一般为0.3V。

2、电阻R1的作用

R1电阻的作用是限制电流过大,防止LED电流过大被烧坏。

3、为什么D2二极管不用外接电阻?

D2二级管的正极接在引脚,负极接地,单片机的引脚的输出电流有限,不用考虑电流过大的情况。不过实际上不会采用这种接法,因为单片机输出电流是有限的,这样接无法同时点亮多个LED灯,还可能影响到单片机其他模块的运行,

4、点灯原理

对于D1二极管:当引脚置为0时,两边电压差为5V,那么实际近似电流就I=(5V-二极管管压降)/(R1+二极管电阻),这样二极管就会发光。

对于D2二极管:引脚为1,即可点灯成功。

二、点亮一个LED灯

博主购买的单片机是STC89C52RC,但是商家给的是51单片机的资料,均属于51系列,基本上没啥差别。

看一下原理图和LED模块:

电路分析

首先看LED模块,左侧是电源正极,当引脚输出低电平时,LED灯亮。本次实验我想控制D1亮,其他二极管不亮。

写法1:写明P2口每一位的状态

#include <reg52.h>
void main()
{
	while(1)
	{
		P2=0xFE;//1111 1110
	}
}

D1灯属于二进制的末位,可以用这种16进制的写法。

写法2:控制单个引脚

#include <reg52.h>
sbit LED1=P2^0;
void main()
{
	while(1)
	{
		LED1=0;
	}
}

三、LED灯闪烁

51单片机的晶振为12Mhz,一个时钟周期=1/12us,一个机器周期=12个时钟周期=1us。

单次延迟时间=123*8*1us≈1ms(包含后置加加的时间)

本次使用D1和D2两个LED灯循环闪烁。

代码

#include <reg52.h>
#define uint unsigned int
sbit LED1=P2^0;
sbit LED2=P2^1;
//延时1ms函数
void delay_1ms()
{
	int i=0;
	for(i=0;i<123;i++)
	{
		 
	}
}
//自定义延时时间函数
void delay_ms(uint t)
{
	while(t--)
	{
		delay_1ms();
	}
}
void main()
{
	while(1)
	{
		//交替闪烁
		LED1=0;
		LED2=1;
		//休眠
		delay_ms(1000);
		 
	    //交替闪烁
	    LED1=1;
	    LED2=~LED2;//也可以写成这种取反的方式
	    //休眠
	    delay_ms(1000);
	}
}

四、流水灯

写法1:使用数组

#include <reg52.h>
#define uchar unsigned char
//延时1ms函数
void delay_1ms()
{
	int i=0;
	for(;i<123;++i);
}
 //自定义延时时间函数
void delay_ms(unsigned int t)
{
	while(t--)
	{
		delay_1ms();
	}
}
void main()
{
	uchar arr[8]={0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};
	while(1)
	{
		int i=0;
		for(;i<8;++i)
		{
			P2=arr[i];
			delay_ms(500);
		}
	}
}

将8种LED灯的状态写成16进制,存储在一个数组中,使用循环遍历修改P2引脚的状态,每个LED亮0.5秒,达到流水灯的效果。

写法2:移位运算符

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
void delay_1ms()
{
	int i=0;
	for(;i<123;++i);
}
void delay_ms(unsigned int t)
{
	while(t--)
	{
		delay_1ms();
	}
}
void main()
{
	uchar m=0XFE;
	while(1)
	{
		int i=0;
		for(;i<8;++i)
		{
			P2=m;
			m=_crol_(m,1);//左移库函数
			delay_ms(500);
		}
	}
}

使用库函数的方法点流水灯,当然这个移位也可以自己写: 

void main()
{
	while(1)
	{
        uchar m=0X01;//0000 0001
		int i=0;
        for(;i<8;++i)
        {
            P2=~m;
            m<<=1;
            delay_ms(500);
        }
	}
}

五、独立按键+点灯

1、独立按键原理

独立按键相当于一根导线,未按下时,左侧为高电平,右侧为低电平;一旦按下按键,对应引脚将会检测到低电平。所以独立按键的核心思想就是判断引脚的高低电平。

本次实验按下K1按键,D1亮;按下K2按键,D2亮。

2、按键消抖

机械开关的断开和闭合时,由于机械触点的弹性作用,开关在闭合和断开时不会马上稳定的接通。

以按下按键为例,接通瞬间,引脚接收到的电平是忽高忽低的状态,就好像我们多次按下了按键。所以我们写代码的时候,需要判断的是开关稳定闭合后的引脚电平状态。通过延时函数达到代码消抖的功能。

3、代码

#include <reg52.h>
sbit LED1=P2^0;
sbit LED2=P2^1;
sbit K2=P3^0;
sbit K1=P3^1;
void delay_1ms()
{
	int i=0;
	for(;i<123;++i);
}
void delay_ms(unsigned int t)
{
	while(t--)
	{
		delay_1ms();
	}
}
void main()
{
	while(1)
	{
		if(K1==0)
		{
			delay_ms(20);//延时消抖,防止按键勿扰动(消抖)
			if(K1==0)//如果if仍成立,说明按键确实被按下了
			{
				LED1=0;
				LED2=1;
				while(K1==0);//等待按键弹起
                //while后不用消抖是因为再次进入一个if都会判断抖动,否则需要判断断开的抖动
			}
		}
		if(K2==0)//原理同上
		{
			delay_ms(20);
			if(K2==0)
			{
				LED1=1;
				LED2=0;
				while(K2==0);
			}
		}
	}
}

a7f5e4f44c09738775beaa07a9011c26.gif

本文含有隐藏内容,请 开通VIP 后查看