Dotcpp  >  编程教程  >  定时器  >  呼吸灯

呼吸灯

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

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;

效果图如下

双定时器呼吸灯实现1

······

双定时器呼吸灯实现2


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

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

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