×
单片机 > 单片机程序设计 > 详情

PWM --呼吸灯

发布时间:2020-08-27 发布时间:
|

呼吸灯最早见于苹果的电脑,近年来,在各种手机上也频频出现。


呼吸灯是很简单的东西,用一片 555,搭成一个多谐振荡器,再用 RC 电路滤成锯齿波,再驱动 LED 就可以了。

LED 在锯齿波的控制下,逐渐的由亮到暗、再由暗到明的周期性变化,看起来就好像是在呼吸。

555 电路,调整起来比较困难,不如使用单片机来制成呼吸灯,可控性较强。


用单片机来制作呼吸灯,电路很简单,也不过就是在单片机的引脚上,连接一个 LED 和一个电阻而已。

只是呼吸灯需要用 PWM 波形来驱动,编程时,稍稍麻烦一点。


在上一篇博文中,做而论道已经介绍了使用按键来调整占空比的参数,进而控制 LED 亮度的方法。

现在,不再用人工调整了,而是让单片机周期性、自动的调整占空比参数,这就可以使 LED 的亮度出现周期性的变化。


这种方法,做而论道在几年前就用实际的硬件电路实现了。


近来,在网上看见有人提问,但是也没有看到正面回答。再广泛的查了查,一直也没有看到有像样的程序。


其实,呼吸灯,算不上什么难题,用 PROTEUS 仿真,也能弄出来,程序也是很简单的,比流水灯,也多不上十余句。


先看看下面的电路与波形,在图中,暂时把 LED 断开了,在限流电阻的位置上,用一个大电容接地。


这时,电容、电阻,就构成了一个积分电路,它可以对单片机输出的矩形波进行滤波。

看看图中的波形,是不是滤成了一个近似的正弦波 ?



调整一下分辨率,这下看清了吧。



矩形波的占空比不变,滤波后的电压就是恒定值,占空比增大,电压就上升,反之就下降。



把 LED 接通后,LED 中的电流,就是近似正弦函数的规律,LED 亮度变化,就像是在呼吸。


调整一下电阻、电容的数值,LED 外接的电源,也可以用 6V 试试,看看效果如何。


制作实际的电路,图中的大电容可以省略,利用人眼视觉的暂留效应,就相当于进行了积分滤波,就能看到呼吸灯的现象。

制成硬件电路后,其效果要比软件仿真要稳定的多。


;=========================================

;驱动呼吸灯的程序,用汇编语言编程。全部程序如下:

;=========================================

N_T0    DATA  30H      ;T0的中断次数

N_20ms  DATA  31H

P_WT    DATA  32H      ;脉冲宽度Pulse width


HX_LED  BIT   P1.0     ;输出接口

HX_DIR  BIT   20H.0    ;亮度递增、递减的状态位


    ORG   0000H

    JMP   START

    ORG   000BH

    JMP   T0_INT


    ORG   0030H

START:

    MOV   TH0, #220    ;1250us@11.0592MHz, T0定时方式0

    SETB  TR0

    MOV   IE, #82H

    

    MOV   N_20ms, #10

    MOV   N_T0, #16

    MOV   P_WT, #1


    SJMP  $            ;此处可以写任意的主程序

;-----------------------------------------

T0_INT:                ;1.25ms中断一次

    MOV   TH0, #220    ;220: 1250us@11.0592MHz

    PUSH  PSW

    PUSH  ACC

;-----------------------下面输出PWM波形---

    DJNZ  N_T0, T0_1   ;中断次数减一

    MOV   N_T0, #16    ;为0就重设, T=16*1.25ms=20ms

    CLR   HX_LED       ;每到20ms就输出0

    DEC   N_20ms

    JMP   T0_2

T0_1:

    MOV   A, N_T0      ;当前中断次数1~16

    DEC   A

    CJNE  A, P_WT, $ + 3 ;减去脉宽度值0~15

    JNC   T0_2         ;大于等于就不用变

    SETB  HX_LED       ;小于就输出1

;-----------------------下面修改脉宽参数--

T0_2:

    MOV   A, N_20ms

    JNZ   T0_END       ;不到0.2s不用修改

    MOV   N_20ms, #10  ;10 * 20ms = 200ms

    JNB   HX_DIR, JIA  ;转去递增

;----------------------

    DJNZ  P_WT, T0_END ;P_WT减, 非零退出

    JMP   TURN         ;为零就去改为递增

;----------------------

JIA:

    INC   P_WT         ;P_WT加

    MOV   A, P_WT

    CJNE  A, #15, T0_END ;不到15就退出

TURN:

    CPL   HX_DIR       ;到了0或15就改变方向


;---定时修改脉宽,只不过上面这十条指令而已。执行起来,也不过就是十几个微秒。

;---这十条就是呼吸灯所需要用的程序,是不是很简单 ?

;----------------------

T0_END:                ;退出定时中断

    POP   ACC

    POP   PSW

    RETI

;-----------------------------------------

END

;=========================================




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项