zoukankan      html  css  js  c++  java
  • led呼吸灯

    让led灯的亮度由暗逐渐变亮再由亮逐渐变暗,重复循环,实现类似呼吸灯的效果。

    让光的亮度变化,一般有下面两种调光方式:

    模拟调光:电压保持不变通过改变电路中电阻的大小来改变电路中的电流,达到亮度的变化。

    数字调光:就我们的单片机来说,只能控制引脚输出1或者0。要能改变led灯的亮度,采用改变一个脉冲中输出正向电流的时间占比,来改变led灯的亮度。

    这种通过改变一个频率输出中输出1和0的比例,来控制输出平均电压的方式就叫做脉宽调制(PWN)。有的单片机上面自带了PWN模块,使用的时候只需要设置一些占比的参数就可以实现PWN编制。但stc89c52上面没有这个模块,我们只能通过定时器中断来自己实现。

    用定时器中断实现led灯呼吸原理:

    LED 闪烁频率设计为50Hz, 亮度范围设计为0-99,即占空比从0到100。将50Hz频率的时间20ms等分100份。

    20ms/100得到每份时间为200us。设计定时器200us产生中断,每20ms即100个中断后,改变占空比。即改变输出1和0的比例。

    也就是在20ms内led灯其实闪烁了100次,由于我们人眼对这么高频率的闪烁不敏感,我们宏观的感觉就是这100次闪烁中亮的次数越多就越亮。我们的代码其实是改变了这100次闪烁中亮的占比,在人眼看来就是亮度的变化了。

    代码:

    #include <reg52.h>

    //控制三盏灯

    sbit LED0 = P0^0;

    sbit LED4 = P0^4;

    sbit LED7 = P0^7;

    char LedDutyCycle = 0;

    char PwmDutyCycle = 0;

    char TimerIntCnt = 0; //200us定时器

    char LightDown = 0;

    static int DutyCycle = 0;

    void LedOn();

    void LedOff();

    void TimeInt0() interrupt 1

    {

        TH0 = 0xFF;

        TL0 = 0x56;

        TimerIntCnt++;

      //200us产生一次中断,100个200us即20ms,此时改变占空比

        if(TimerIntCnt > 100)

        {

            TimerIntCnt = 0;

            if(LedDutyCycle <= 99 && LightDown == 0)

            {

                LedDutyCycle++;

                if(LedDutyCycle > 99)

                {

                    LightDown = 1;

                    LedDutyCycle = 99;

                }

        }

        if(LedDutyCycle >= 0 && LightDown == 1)

        {

            LedDutyCycle--;

            if(LedDutyCycle < 0)

            {

                LightDown = 0;

                LedDutyCycle = 0;

            }

        }

        DutyCycle = LedDutyCycle;

    }

    //DutyCycle即20ms中100个等分的高电平部分,即实际有效占空比

    if(DutyCycle > 0)

    {

        LedOn();

        DutyCycle--;

    }

    else

    {

        LedOff();

    }

    }

    //定时器初始化化,模式1 16位, 200us

    void InitTimer0()

    {

        TMOD = 0x01;

        TH0 = 0xFF;

        TL0 = 0x56;

        ET0 = 1;

        EA = 1;

        TR0 = 1;

    }

    //点灯

    void LedOn()

    {

    LED0 = 0;

    LED4 = 0;

    LED7 = 0;

    }

    //关灯

    void LedOff()

    {

    LED0 = 1;

    LED4 = 1;

    LED7 = 1;

    }

    void main()

    {

        InitTimer0();

        while(1) ;

    }

    /** ****************************************************************************** * @file : main.c * @brief * @author : 涛声依旧 * @version : V1.0.0 * @date : 2019-12-12 * Fuction List : 1. ... <version>: <modify staff>: <data>: <description>: 2. ... ****************************************************************************** ** * * COPYRIGHT(c) 2019, 机器鸟 www.qshikong.cn * * 满足以下条件,允许修改或者修改后以源代码和二进制形式重新分发和使用。 * 1. 重新分发源代码必须保留上述版权声明,以及此条件列表 * 和以下免责声明。 * 2. 二进制形式的重新分发必须复制上述版权声明, * 此列表内容和以下免责声明于发行版随附的材料中。 * 3. 机器鸟的名称或其贡献者的名称未经事先特别说明许可,不可用于认可 * 或推广从该产品衍生的产品。 * * 免责声明:本软件只用于教学、学习、测试使用,对于任何直接、间接、偶发、 * 特殊等损害,版权持有人或贡献者在任何情况下均不承担责任。 * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include <reg52.h> /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ //控制三盏灯 sbit LED0 = P0^0; sbit LED4 = P0^4; sbit LED7 = P0^7; char LedDutyCycle = 0; char PwmDutyCycle = 0; char TimerIntCnt = 0; //200us定时器 char LightDown = 0; static int DutyCycle = 0; /* Private function prototypes -----------------------------------------------*/ void LedOn(); void LedOff(); /* Private functions ---------------------------------------------------------*/ /** * @Name TimeInt0 * @brief 定时器处理函数,200us产生中断 * @param : [输入/出] * @retval * @author 涛声依旧 * @Data 2019-12-22 * 1. ... * <modify staff>: * <data> : * <description> : * 2. ... **/ void TimeInt0() interrupt 1 { TH0 = 0xFF; TL0 = 0x56; TimerIntCnt++; //200us产生一次中断,100个200us即20ms,此时改变占空比 if(TimerIntCnt > 100) { TimerIntCnt = 0; if(LedDutyCycle <= 99 && LightDown == 0) { LedDutyCycle++; if(LedDutyCycle > 99) { LightDown = 1; LedDutyCycle = 99; } } if(LedDutyCycle >= 0 && LightDown == 1) { LedDutyCycle--; if(LedDutyCycle < 0) { LightDown = 0; LedDutyCycle = 0; } } DutyCycle = LedDutyCycle; } //DutyCycle即20ms中100个等分的高电平部分,即实际有效占空比 if(DutyCycle > 0) { LedOn(); DutyCycle--; } else { LedOff(); } } //定时器初始化化,模式1 16位, 200us void InitTimer0() { TMOD = 0x01; TH0 = 0xFF; TL0 = 0x56; ET0 = 1; EA = 1; TR0 = 1; } //点灯 void LedOn() { LED0 = 0; LED4 = 0; LED7 = 0; } //关灯 void LedOff() { LED0 = 1; LED4 = 1; LED7 = 1; } void main() { InitTimer0(); while(1) ; }

  • 相关阅读:
    Python入门基础知识点(基础数据类型之字典)
    Python入门基础知识点(基础数据类型之二)
    Python入门基础知识点(基础数据类型)
    Python入门基础知识点(循环语句和编码)
    Python入门基础知识点(基础语法介绍)
    接口继承
    类的继承
    类的组合
    静态属性、类方法、静态方法
    类与对象属性的操作
  • 原文地址:https://www.cnblogs.com/maycpou/p/13603689.html
Copyright © 2011-2022 走看看