LED对电压也是有要求的,二极管都有导通电压,LED的供电电压如果没有达到这个导通电压值,
LED无法点亮,当LED导通时,电流才开始流过LED,且电流越大,亮度越强(但不能超过最大作电流)。
(1)OA 段。这是正向死区。UA 为开启LED发光的电压。
(2)AB 段。这是工作区。在这一区段, 一般是随着电压增加电流也跟着增加, 发光亮度也跟着增大。
(3)OC 段。这是反向死区,发光二极管加反向电压是不发光的(不工作),但有反向电流。这个反向电流通常很小,一般在几微安之内。
(4)CD 段。这是反向击穿区,LED的反向电压一般不要超过10V,最大不得超过 15V,最大反向电压。超过这个电压,就会出现反向击穿,导致发光二极管报废。
STC89C52开发板上LED模块电路如下:
查看开发板原理图LED D1指示灯对应的是引脚是P2_0,所以只需要给P2_0输出一个低电平就能使D1亮。
#include
sbit LED = P2^0;//将P2.0定义为LED
void main()
{
LED = 0;//点亮LED1
while(1)
{}
}
LED已经点亮,想要它出现闪烁就是使LED一亮一灭,只需循环让 D1 指示灯先亮一会后熄灭,使
这个状态持续下去。但是要想使我们人眼想要观察到需要设置一定的延时,利用人眼的余晖效应。
#include
sbit LED = P2^0;
typedef unsigned int u16;//对系统默认数据类型进行重命名
typedef unsigned char u8;
void Delay(u16 ten) //延迟函数
{
while(ten--);
}
void main()
{
while(1)
{
LED = 0; //点亮
Delay(50000);//大约延迟450ms
LED = 1; //熄灭
Delay(50000);
}
}
LED流水灯之前我记录过一次,这次想在记录一次就当复习了。要实现 LED 流水灯,只需循环
让 D1-D8 指示灯逐个点亮。要实现循环点亮,最容易想到的方法:点亮 D1 且把 D2-D8 熄灭,延
时一段时间后再点亮 D2 且把 D1、 D3-D8 熄灭,延时一段时间后再点亮 D3 且把 D1-D2、D4-D8
熄灭,如此循环下去,IO 口由低往高或者由高往低逐个输出低电平特点。在这里有两种方法实现,一
种是利用二进制逻辑位移使不同引脚低电平,另一种是利用库函数intrins.h中的位移函数。
这种是最笨的方法,依次让每一个LED逐次亮灭。
#include
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
sbit LED7 = P2^6;
sbit LED8 = P2^7;
typedef unsigned int u16;
void Delay(u16 ten)
{
while(ten--);
}
void main()
{
while(1)
{
//通过高低电平
LED1 = 0;
Delay(50000);
LED1 = 1;
Delay(50000);
LED2 = 0;
Delay(50000);
LED2 = 1;
Delay(50000);
LED3 = 0;
Delay(50000);
LED3 = 1;
Delay(50000);
LED4 = 0;
Delay(50000);
LED4 = 1;
Delay(50000);
LED5 = 0;
Delay(50000);
LED5 = 1;
Delay(50000);
LED6 = 0;
Delay(50000);
LED6 = 1;
Delay(50000);
LED7 = 0;
Delay(50000);
LED7 = 1;
Delay(50000);
LED8 = 0;
Delay(50000);
LED8 = 1;
Delay(50000);
}
}
通过位移来实现亮灭
#include
#define LED_PORT P2;
typedef unsigned int u16;
typedef unsigned char u8;
void Delay(u16 ten)
{
while(ten--);
}
void main()
{
u8 i;
while(1)
{
//通过位移实现
for(i=0;i<8;i++)
{
P2 = ~(0x80>>i); //1000 0000 -->0000 0001然后取反
Delay(50000);
}
for(i=0;i<8;i++)
{
P2 = ~(0x01<1000 0000然后取反
Delay(50000);
}
}
}
通过库函数intrins.h实现
#include
#include "intrins.h"
#define LED_PORT P2;
typedef unsigned int u16;
typedef unsigned char u8;
void Delay(u16 ten)
{
while(ten--);
}
void main()
{
u8 i;
P2 = 0xFE;
while(1)
{
for(i=0;i<7;i++)//移动的是0的位置
{
P2 = _crol_(P2,1);//左移
Delay(50000);
}
for(i=0;i<7;i++)
{
P2 = _cror_(P2,1);//右移
Delay(50000);
}
for(i=0;i<8;i++)//移动的是1的位置
{
P2 = ~(_cror_(0x01,i));//右移
Delay(50000);
}
for(i=0;i<8;i++)
{
P2 = ~(_crol_(0x80,i));//左移
Delay(50000);
}
}
}
使用逻辑左移高位移出(舍弃),低位的空位补0,最高位丢失,最低位补0。使用逻辑右移低位移出
(舍弃),高位的空位补0,最高位补0,最低位丢失。类似数据结构的队列一样,前面走后面来的补
上。而使用左移函数(循环左移)_crol_(移动对象,左移的位数)如果是左移,那么最高位就被移到
最低位了,次高位变为最高位。右移函数和左移函数类似。类似一个循环队列。
#include
#include "intrins.h"
#define LED_PORT P2;
typedef unsigned int u16;
typedef unsigned char u8;
void Delay(u16 ten)
{
while(ten--);
}
void main()
{
u8 i;
P2 = 0xFE;
while(1)
{
for(i=0;i<7;i++)//0的位置变动
{
P2 = _crol_(P2,1);
Delay(50000);
}
for(i=0;i<7;i++)
{
P2 = _cror_(P2,1);
Delay(50000);
}
}
}
刚开始P2 = 0xFE; 对应二进制 1111 1110,最低位为0,因此最开始的 D1 指示灯会点亮。循环七次
的原因是在进入 main 开始,就已经将 LED_PORT 端口设置了一次状态,即让 D1 点亮,并且我
们是想让 LED 从左至右依次点亮,然后继续又从右至左依次点亮。
初始状态:LED_PORT=1111 1110
i=0:LED_PORT=1111 1101
i=1:LED_PORT=1111 1011
i=2:LED_PORT=1111 0111
i=3:LED_PORT=1110 1111
i=4:LED_PORT=1101 1111
i=5:LED_PORT=1011 1111
i=6:LED_PORT=0111 1111
i=7:LED_PORT=1111 1110
如上如有错误,谢谢指正。