找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 5135|回复: 7
打印 上一主题 下一主题
收起左侧

单片机脉宽调制应用-渐明渐暗的灯

[复制链接]
跳转到指定楼层
楼主
ID:76190 发表于 2015-4-5 16:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PWM(Pulse Width Modulation)是脉冲宽度调制的英文单词的缩写。下面这段话是通信百科中对其的定义:
脉冲宽度调制(PWM)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。脉宽调制是开关型稳压电源中的术语。这是按稳压的控制方式分类的,除了PWM型,还有PFM型和PWM、PFM混合型。脉宽调制式开关型稳压电路是在控制电路输出频率不变的情况下,通过电压反馈调整其占空比,从而达到稳定输出电压的目的。
读起来有点晦涩难懂。其实简单的说来,PWM技术就是通过调整一个周期固定的方波的占空比,来调节输出电压的平均当电压,电流或者功率等被控量。我们可以用一个水龙头来类比,把1S时间分成50等份,即每一个等份20MS。在这20MS时间里如果我们把水龙头水阀一直打开,那么在这20MS里流过的水肯定是最多的,如果我们把水阀打开15MS,剩下的5MS关闭水阀,那么流出的水相比刚才20MS全开肯定要小的多。同样的道理,我们可以通过控制20MS时间里水阀开启的时间的长短来控制流过的水的多少。那么在1S内平均流出的水流量也就可以被控制了。
当我们调整PWM的占空比时,就会引起电压或者电流的改变,LED的明暗状态就会随之发生相应的变化,听起来好像可以通过这种方法来实现我们想要的渐明渐暗的效果。让我们来试一下吧。
大家都知道人眼有一个临界频率,当LED的闪烁频率达到一定的时候,人眼就分辨不出LED是否在闪烁了。就像我们平常看电视一样,看起来画面是连续的,实质不是这个样子,所有连续动作都是一帧帧静止的画面在1S的时间里快速播放出来,譬如每秒24帧的速度播放,由于人眼的视觉暂留效应,看起来画面就是连续的了。同样的道理,为了让我们的LED在变化的过程中,我们感觉不到其在闪烁,可以将其闪烁的频率定在50Hz以上。同时为了看起来明暗过渡的效果更加明显,我们在这里定义其变化范围为0~99(100等分).即最亮的时候其灰度等级为99,为0的时候最暗,也就是熄灭了。
于是乎我们定义PWM的占空比上限为99, 下限定义为0
#define  LED_PWM_LIMIT_MAX    99
#define  LED_PWM_LIMIT_MIN      0

假定我们LED的闪烁频率为50HZ,而亮度变化的范围为0~99共100等分。则每一等分所占用的时间为 1/(50*100)  =  200us 即我们在改变LED的亮灭状态时,应该是在200us整数倍时刻时。在这里我们用单片机的定时器产生200us的中断,同时每20MS调整一次LED的占空比。这样在20MS * 100 = 2S的时间内LED可以从暗逐渐变亮,在下一个2S内可以从亮逐渐变暗,然后不断循环。
由于大部分的内容都可以在中断中完成,因此,我们的大部分代码都在Timer.c这个文件中编写,主函数中除了初始化之外,就是一个空的死循环。






Timer.c内容如下。
#include <reg52.h>
#include "MacroAndConst.h"

#define LED P0            //定义LED接口
#define LED_ON()      LED = 0x00 ;  //所有LED亮
#define LED_OFF()    LED = 0xff ;  //所有LED熄灭

#define  LED_PWM_LIMIT_MAX    99
#define  LED_PWM_LIMIT_MIN      0

static uint8 s_u8TimeCounter = 0 ; //中断计数
static uint8 s_u8LedDirection = 0 ; //LED方向控制 0 :渐亮 1 :渐灭
static int8  s_s8LedPWMCounter  = 0 ; //LED占空比
void Timer0Init(void)
{
    TMOD &= 0xf0 ;
    TMOD |= 0x01 ;     //定时器0工作方式1
    TH0  =     0xff ;     //定时器初始值(200us中断一次)
    TL0  =  0x47 ;
    TR0  = 1 ;
    ET0  = 1 ;
}

void Time0Isr(void) interrupt 1
{     
    static int8 s_s8PWMCounter = 0  ;
    TH0  =     0xff ;           //定时器重新赋初值
    TL0  =  0x47 ;

    if(++s_u8TimeCounter >= 100) //每20MS调整一下LED的占空比
    {
        s_u8TimeCounter = 0 ;
        //如果是渐亮方向变化,则占空比递增
         if((s_s8LedPWMCounter <= LED_PWM_LIMIT_MAX) &&(0 == s_u8LedDirection))
        {
            s_s8LedPWMCounter++  ;
            if(s_s8LedPWMCounter > LED_PWM_LIMIT_MAX)
            {
                s_u8LedDirection = 1 ;
                s_s8LedPWMCounter =  LED_PWM_LIMIT_MAX ;               
            }            
        }
        //如果是渐暗方向变化,则占空比递渐
                if((s_s8LedPWMCounter >= LED_PWM_LIMIT_MIN) &&(1 == s_u8LedDirection))
                                                                                                
        {
            s_s8LedPWMCounter-- ;
            if(s_s8LedPWMCounter < LED_PWM_LIMIT_MIN)
            {
                s_u8LedDirection = 0 ;
                s_s8LedPWMCounter =  LED_PWM_LIMIT_MIN ;               
            }   
        }
        s_s8PWMCounter = s_s8LedPWMCounter ;  //获取LED的占空比
    }

    if(s_s8PWMCounter > 0) //占空比大于0,则点亮LED,否则熄灭LED
    {
        LED_ON() ;
        s_s8PWMCounter-- ;
    }
    else
    {
        LED_OFF();   
    }

}


其实PWM技术在我们实际生活中应用的非常多。比较典型的应用就是控制电机的转速,控制充电电流的大小,等等。而随着技术的发展,也出现了其他类型的PWM技术,如相电压PWM,线电压PWM,SPWM等等,如果有兴趣可以到网上去获取相应资料学习。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

举报

沙发
ID:109460 发表于 2016-3-18 09:28 | 只看该作者
你好,请教下想在20S完成渐变,怎么调时间,我怎么调亮度变化值到0-400总时间怎么和0-100一样
回复

举报

板凳
ID:109460 发表于 2016-3-18 09:28 | 只看该作者
你好,请教下想在20S完成渐变,怎么调时间,我怎么调亮度变化值到0-400总时间怎么和0-100一样
回复

举报

地板
ID:109460 发表于 2016-3-18 09:28 | 只看该作者
你好,请教下想在20S完成渐变,怎么调时间,我怎么调亮度变化值到0-400总时间怎么和0-100一样
回复

举报

5#
ID:109460 发表于 2016-3-18 09:28 | 只看该作者
你好,请教下想在20S完成渐变,怎么调时间,我怎么调亮度变化值到0-400总时间怎么和0-100一样
回复

举报

6#
ID:109460 发表于 2016-3-18 09:29 | 只看该作者
你好,请教下想在20S完成渐变,怎么调时间,我怎么调亮度变化值到0-400总时间怎么和0-100一样
回复

举报

7#
ID:96172 发表于 2016-3-20 12:18 | 只看该作者
你好,请教下想在20S完成渐变,怎么调时间,我怎么调亮度变化值到0-400总时间怎么和0-100一样
回复

举报

8#
ID:540334 发表于 2021-9-26 23:55 来自触屏版 | 只看该作者
变量名太长了,看起来真费劲
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表