首页 资讯 应用 高压 设计 行业 低压 电路图 关于

单片机

旗下栏目: PLC 嵌入式 单片机 DCS

单片机IO口利用PWM脉宽调制实现LED灯的渐亮渐灭

单片机 | 发布时间:2018-10-19 | 人气: | #评论# | 本文关键字:单片机,PWM,脉宽调制,IO
摘要:硬件说明: AT89S52,晶振11.0592MHz。P3.6为一个LED背光板,等于0时发光。 P0.0为一个按键,按下时为0。 *****************************************************************************/ 程序思路说明: LED背光板的渐亮

硬件说明:
AT89S52,晶振11.0592MHz。P3.6为一个LED背光板,等于0时发光。
P0.0为一个按键,按下时为0。
*****************************************************************************/
程序思路说明:
LED背光板的渐亮渐灭实际上就是LED的亮度等级由低到高(渐亮)再由高到低(渐灭)的过程,那么首先要通过PWM脉宽调制实现LED显示不同的亮度等级。(脉宽调制的基本原理怎么实现不同的亮度等级呢?假设在某个长度的周期(一个适当的时间长度)内如果LED的管脚一直输出0(我这里输出0时LED背光板点亮),那么很显然LED肯定是最亮的;相反如果一直输出1,那LED肯定是最暗的(也就是不亮)。如果在这个周期内管脚输出的是脉冲波(10101010;)那么LED的亮度就只有最亮时的一半,或者说如果前一半时间是高电平后一半时间是低电平,那LED的亮度也是最亮的一半,这是由于LED的余晖效应,但这个时间必须恰当,不然LED就不是亮而是闪烁。下面这段代码即可实现LED显示在某个亮度等级:
void timer0(void) interrupt 1 using 2 

static uchar counter=0; //中断次数计数器变量
TH0=V_TH0; //恢复定时器初始值
TL0=V_TL0;
counter++; 
if (counter<=(ZKB1)) //当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整 
{LED3=0;} 
else 
{LED3=1;}
if (counter==100)
{counter=0;}
}
那么现在我们就可以依次变换LED的亮度等级,从而实现LED的渐亮渐灭了。若上面的定时器中断是0.1ms触发一次、ZKB1=20,那么整个周期为0.1ms*100=10ms,LED3为低脉冲的时间
长度为20*0.1ms=2ms,显示亮度为最亮的20%。如果我们把100个不同的亮度等级挨个显示一遍就出现了由暗到亮的渐亮过程或渐灭过程。那么我们就在每当counter==100的时候,ZKB1++就行了(由暗到亮)。上面的程序第24行{}内加入ZKB1++;,并在第25行加入if (ZKB1==100) ZKB1=0; 语句即可。这样看到的效果是LED由暗变亮然后又有暗变亮。现在我们再加入由亮变暗。新增一个变量ZKB2,counter==100时ZKB2++,当ZKB2<=100时ZKB1=ZKB2,实现有暗变亮;当100<ZKB2<=200时ZKB1=200-ZKB2,实现由亮变暗;当200<ZKB2<=400时ZKB1=0,LED保持熄灭。从时间上来说,每一个亮度等级耗时10ms,那么渐亮耗时1s,渐灭耗时1s,熄灭保持2s,然后开始下一个周期。这里我还加了一个flag0变量,作用是当K0按下时使LED停止发光。

对上面的这段话再做一次解释:
1、ZKB1决定了LED3应该显示多亮(ZKB1的值为0-99,即把亮度分为100个等级)
2、ZKB2的值决定了现在应该选择哪个亮度等级(ZKB2的值为0—399),实际上ZKB2相当于X轴(时间),而ZKB1相当于Y轴(亮度)。ZKB2从0到99时LED3渐亮(ZKB1从0到99),当ZKB2从100到199时LED3渐灭(ZKB1从99回到0),当ZKB2从200到399时LED3熄灭(ZKB1=0),这样整个过程就是LED3渐亮—渐灭—熄灭,然后重复。
******************************************************************************/
#include <REG52.H> 
#define uchar unsigned char

#define V_TH0 0xff //定时器0初值
#define V_TL0 0xa3

sbit LED3=P3^6; ///背光片接口
sbit K0=P0^0;

unsigned char ZKB1,ZKB2; 
bit flag0;

/*————————-定时器初始化———————————–*/ 
void init_sys(void)

TMOD=0x01; //定时器0工作在方式1
TH0=V_TH0; //定时周期为0.1ms
TL0=V_TL0; 
TR0=1; 
ET0=1; 
EA=1; 
}

/*———————–定时器0中断函数———————————*/ 
void timer0(void) interrupt 1 using 2 

static uchar counter=0; //中断次数计数器变量 
TH0=V_TH0; //恢复定时器初始值 
TL0=V_TL0;
if (flag0==1)

counter++; 
if (counter>=100) 
{
counter=0;
ZKB2++;
if (ZKB2<=100) //占空比变化部分
{ ZKB1=ZKB2;}
else if (ZKB2<=200)
{ ZKB1=200-ZKB2;}
else
{ ZKB1=0;}

if (counter<=(ZKB1)) //当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整
LED3=0; 
else 
LED3=1;
if (ZKB2>399) ZKB2=1;
}
else 

LED3=1;

}

/*——————————主函数————————————-*/
void main (void) 

init_sys(); 
while(1) 

P0=0xff;
flag0=K0; 


/***************************************************************************
小结:这里定时器的定时长度需要根据具体情况作出适当调节
****************************************************************************/

责任编辑:单片机
首页 | 电气资讯 | 应用技术 | 高压电器 | 电气设计 | 行业应用 | 低压电器 | 电路图 | 关于我们 | 版权声明

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版 原创声明:本站大部分内容为原创,转载请注明电气自动化网转载;部分内容来源网络,如侵犯您的权益请发送邮件到[email protected]联系我们删除。