首页  /  单片机教程  /  呼吸灯  /  

呼吸灯

点击打开在线编译器,边学边练

1.双定时器呼吸灯实现

呼吸灯的实现原理就是让小灯的IO端口在一段时间里PWM由大到小变化的占空比输出,接着又由小到大的占空比输出,小灯显示效果就是时亮时暗地交替闪烁。

首先我们用定时器0定时0.1ms,全局变量pwm在其中断函数里执行简单的从0到99的循环自加,这样周期就是10ms。

假如主函数里我们这样执行

if(pwm<90)P0=0xFF;
else P0=0x00;

那么IO端口输出的一直是周期为10ms占空比为90%的波形,这样8盏小灯一直是处于较暗的显示状态不变,要想实现呼吸灯,就要不停改变PWM波形的占空比。

所以我们使用定时器1来做间隔10ms地改变占空比,我们再定义一个全局变量highval,这个变量每隔10ms就会在定时器1中断函数中实现加1或者减1,加到99时又从99减回到0,减回到0又从0开始加到99的这样循环过程,大家回去研究左右往复循环流水灯的代码就会明白都是一样的思路。

然后主函数这样执行

if(pwm<highval)P0=0xFF;//highval每隔10ms就会变化加1或者减1
else P0=0x00;

效果图如下

定时器17

······

定时器18


2.代码

#include <reg52.h> 
#include <function.h> //详见第六章第8讲
#include <timer.h>

u8 pwm=0,highval=99;
void main()
{   
    LED_Init();          //初始化LED硬件模块
    EA = 1;              //闭合总中断开关
    TIM0_Init(100,9);    //定时0.1ms,9是微调使定时时间更精确
    TIM1_Init(10000,10); //定时10ms,10是微调使定时时间更精确

    while(1)
    {   
        if(pwm<highval)P0=0xFF; //highval每隔10ms就会变化加1或者减1
        else P0=0x00; 
    }   
}
 
void TIM0_IRQHandler() interrupt 1
{ 
    TH0 = T0RH;        //重新加载重载值
    TL0 = T0RL;
    pwm++;
    if(pwm>=100)pwm=0; //pwm在0~99之间间隔0.1ms变化,周期就为10ms
}
 
void TIM1_IRQHandler() interrupt 3
{
    static u8 dir;
    TH1 = T1RH;          //重新加载重载值
    TL1 = T1RL;
  
    if(dir==1)highval--; //占空比逐渐减少,小灯逐渐变亮
    if(highval==0)dir=0;
  
    if(dir==0)highval++; //占空比逐渐增加,小灯逐渐变暗
    if(highval>=99)dir=1;
}

本章内容就告一段落了,定时器功能几乎是开发中必不可少的模块,灵活使用会使执行效率更加高效,大家有时想出的一些原创题目多使用定时器来训练,加强对这个工具的利用。


本文固定URL:https://www.dotcpp.com/course/427

第一章 单片机入门
第二章 LED
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)