1.亮度变化原因
呼吸灯的亮度并不是因为电压在变化,是脉宽调制后小单位时间内亮灭的占比变化,称为PWM。
2.PWM函数的设置
PWM函数需要一个double参数percent,用于表示亮占比,即1-占空比。在一小段时间内(影响参数1),这里设置为10ms,P1置0后,延时10*percent,置1后延时10*(1-percent)。
3.main函数调至脉宽
使用一个double类型的参数brightNess作为percent的实参,下面设置算法(影响参数2)
(1)在死循环中,使用递增递减循环,让brightNess从低到高再从高到低。
需要考量一次执行完后循环的次数(影响参数3),即i(此处是1~100)。
(2)使用math.h的函数sin,用sin(i*3.1415926/100)赋值给brightNess,也是介于0~1之间变化。
4.三个影响参数
参数1:一个亮灭周期的总时长
太大会出现明显的亮灭闪烁,太小则在整个变化周期中显得过小,分辨不及。
参数2:算法的不同
使用正弦函数,总体亮度使用积分可以算出,平均亮度为2/PI;而线性循环的平均亮度为0.5,较小。假设亮度小于1/3人眼视为暗,那么正弦函数暗的时间占比会小于1/3,人眼会觉得没有完全暗下来。
参数3:一个周期的PWM次数
和参数1一起影响周期长度,如果次数过多,会影响整体的亮度变化的流畅性。
#include <reg52.h>
#include <intrins.h>
#include <math.h>
#define uint unsigned int
#define uchar unsigned char
sbit LED1=P1^1;
double brightNess;
void delay(uint ms)
{
uint x,y;
for(x=ms;x>0;x--)
for(y=114;y>0;y--);
}
void PWM(double percent)
{
LED1=0x00;
delay(10*percent);
LED1=0xff;
delay(10*(1-percent));
}
void main()
{
while(1)
{
double i;
for(i=0;i<=100;i++){
brightNess=i/100;
PWM(brightNess);
}
for(i=100;i>=0;i--){
brightNess=i/100;
PWM(brightNess);
}
}
}