51单片机如何做渐明渐暗流水灯
RT,就是那种亮度渐变效果的流水灯,有什么算法或者设计思路吗? 脉冲 宽度 调制 到bbs。mydigit。cn找呼吸灯 #include "reg52.h"#include "MacroAndConst.h"
#define LED P0 //定义LED接口
#define LED_ON() LED = 0x00 ;//所有LED亮
#define LED_OFF() LED = 0xff ;//所有LED熄灭
#defineLED_PWM_LIMIT_MAX 99
#defineLED_PWM_LIMIT_MIN 0
static uint8 s_u8TimeCounter = 0 ; //中断计数
static uint8 s_u8LedDirection = 0 ; //LED方向控制 0 :渐亮 1 :渐灭
static int8s_s8LedPWMCounter= 0 ; //LED占空比
void Timer0Init(void)
{
TMOD &= 0xf0 ;
TMOD |= 0x01 ; //定时器0工作方式1
TH0= 0xff ; //定时器初始值(200us中断一次)
TL0=0x47 ;
TR0= 1 ;
ET0= 1 ;
}
void Time0Isr(void) interrupt 1
{
static int8 s_s8PWMCounter = 0;
TH0= 0xff ; //定时器重新赋初值
TL0=0x47 ;
if(++s_u8TimeCounter >= 100) //每20MS调整一下LED的占空比
{
s_u8TimeCounter = 0 ;
//如果是渐亮方向变化,则占空比递增
if((s_s8LedPWMCounter <= LED_PWM_LIMIT_MAX) &&(0 == s_u8LedDirection))
{
s_s8LedPWMCounter++;
if(s_s8LedPWMCounter > LED_PWM_LIMIT_MAX)
{
s_u8LedDirection = 1 ;
s_s8LedPWMCounter =LED_PWM_LIMIT_MAX ;
}
}
//如果是渐暗方向变化,则占空比递渐
if((s_s8LedPWMCounter >= LED_PWM_LIMIT_MIN) &&(1 == s_u8LedDirection))
{
s_s8LedPWMCounter-- ;
if(s_s8LedPWMCounter < LED_PWM_LIMIT_MIN)
{
s_u8LedDirection = 0 ;
s_s8LedPWMCounter =LED_PWM_LIMIT_MIN ;
}
}
s_s8PWMCounter = s_s8LedPWMCounter ;//获取LED的占空比
}
if(s_s8PWMCounter > 0) //占空比大于0,则点亮LED,否则熄灭LED
{
LED_ON() ;
s_s8PWMCounter-- ;
}
else
{
LED_OFF();
}
} MARK 是用的PWM吧 mark. mark. 设两个定时器,定时器1定时周期基本上设定在10ms左右,另一个定时器根据渐变方式逐渐增加和减小定时时间。当定时器1开通时将LED点亮,(在10ms内)定时器2在T1的时间范围内,延长或缩短T2的定时关闭LED时间的长短即可得到LED渐亮或渐暗的效果。这样可做出7彩渐变等很好的效果。 mark mark mark 单个呼吸灯就是PCA配置为输出比较模式。
呼吸流水灯就是将PCA的比较输出端接在数据分配器的DI端,然后8个Q端分别接8个LED,然后A2 A1 A0接MCU的IO做地址,每个地址对应一个变化的PWM占空比,同时每个地址对应占空比错开一定的相位,每次地址轮换后PWM发生一次变化,这样就是呼吸的流水灯了。 查表方式,使用定时器,改变定时器初值即可。 回复【8楼】sun_jinde
-----------------------------------------------------------------------
说的挺明白的。我看懂了。 顶一下 mark 调节的本质就是PWM。MARK! PWM 正在学这个呢 你懂的 回复【3楼】q492240
-----------------------------------------------------------------------
用PWM同延时都可以 /*
学习内容:灵活控制io口输出。
程序效果:下载此程序后会看到8个led渐渐亮起来然后渐渐暗,此效果利用人眼视觉惰性,制造不同的亮度。
任何光色都可以用红、绿、蓝三种光混合出来,所以控制红绿蓝三种led的亮度就制作出无数种颜色。
很多led装饰产品都是由这个简单的程序变化出来的。
*/
#include<reg51.h>
sbit led_k=P1^4;//单片机引脚定义,控制8个LED的开关三极管。请看电路原理图
sbit a1=P1^0;//单片机引脚定义,此引脚控制共阴数码的一个共阴极。请看电路原理图
sbit a2=P1^1;//单片机引脚定义,此引脚控制共阴数码的一个共阴极。请看电路原理图
sbit a3=P1^2;//单片机引脚定义,此引脚控制共阴数码的一个共阴极。请看电路原理图
sbit a4=P1^3;//单片机引脚定义,此引脚控制共阴数码的一个共阴极。请看电路原理图
void delay10us(unsigned int i);/*延时函数*/
main()
{
unsigned int i=0;
led_k=1;/*打开6个led的总开关*/
a1=a2=a3=a4=0;/*关闭数码管,否则数码管会拉低P0口电平,导致流水灯不亮*/
//P0=0X01;
delay10us(10);
while(1)
{
for(i=0;i<500;i++)//渐亮
{
P0=255;// LED亮
delay10us(i);// led亮时间
P0=0; //led灭
delay10us(500-i); //led灭时间
}
for(i=0;i<500;i++)//渐灭。原理与上面的渐亮相同
{
P0=0;
delay10us(i);
P0=255;
delay10us(500-i);
}
}
}
void delay10us(unsigned int i)
{
unsigned int j;
for(;i>0;i--);
// for(j=1;j>0;j--);
}
很不错的资源,学习了 还可以这样啊,厉害,我以为只能DAC呢,Mark! winkle 发表于 2011-1-3 13:38 static/image/common/back.gif
查表方式,使用定时器,改变定时器初值即可。
赞同,想补充的就是,把间距做的越小,呼吸效果越好 还是顶一个吧!!
页:
[1]