请教让LED渐亮渐渐灭的程序?
请问那位老大能帮我写个用单片机控制让LED渐渐亮渐渐灭的程序啊? 我提个参考想法,用PWM来实现,PWM输出几档电压来控制LED 的亮度.看行不行. 定时器做PWM输出,不但可以让LED渐亮渐灭,还可以控制LCD背光,令产品档次提升不少,只是要占用一个定时器,划不划得来就要考虑一下了。 我想问一下,用pwm控制的话,加不加积分电路的,如果不加,效果会不会差一点?例如闪烁? 视觉暂留,你看看频率。 点击此处下载armok01105546.rar程序如下,还有防真 楼主指的是一个LED灯的明暗变化。
我晚上传上来! 期待中,再次谢谢各位老大的支持啊 PWM和电阻排控制LED亮度 (菜鸟制作) http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=594314&bbs_page_no=1&bbs_id=1037
-----此内容被alisha于2006-03-07,20:43:06编辑过 楼上的朋友可以把你的电路图上传或发给我吗?yam0000@163.com
期待着。。。。。。。。 不用这么复杂吧。 我想只要控制占空比,就可以达到调节LED 的亮度了。 频率不能太低,调占空比! 占空比调到怎样才可以,我做了一个,还是有很明显的闪烁. 频率高了当然就不闪了,用眼睛来积分! 定时器的时钟源分频系数不要太大,肯定不会闪。 问题不大 这个主要是看你的灯数的多少。实现的方法可以是纯软件或软硬结合的。灯数少30只灯左右使用纯软件方法即可实现。可以形成光影流水的效果。灯多了,必须要软硬结合了。基本的解决方法是产生占空比可调的脉冲串,不论哪种方法,可控制的灯数量多,要管理的参数巨大。基本的思想可分为线性值和权值法(我自己的称呼)两种。两种方法都是对时间的权值做出定义,前者为1,后者为8 4 2 1 .
如果希望计算占空比的频率,可以粗略算一下:人眼的视觉暂留特性为40毫秒,因此,led灯最少,一秒要亮-黑 25次,这样就不会闪,大家想一下荧光灯,它是50次。如果led从最暗到最亮,分成16个档,那么它的占空比最低是1:15,最亮时是15:1,所以这个灯如果持续工作在最暗状态,它的工作频率就是1/40毫秒/16=1/2.5毫秒=400hz。也就是说,当一个定时器每2.5毫秒触发一次时,可以维持led产生16级不同强度的光看上去不闪烁。
实际应用中一般要在100级以上,否则最暗一级发出来的光仍然是比较亮的。我用M8内部振荡字ff做过22个100级的光影流水灯,效果还是可以的。 look
-----此内容被quben于2006-10-24,17:42:46编辑过 #include <avr/io.h>
#include <avr/delay.h>
#define uchar unsigned char
#define uint unsigned int
int main ()
{ uchar pwm=0x00;
TCCR1A=0xb1;
TCCR1B=0x09;
TCNT1=0;
DDRB|=0xf6;
PORTB|=0xf6;
while (1)
{ for (pwm=0;pwm<255;pwm++)
{ _delay_loop_2 (2000);
OCR1A=pwm;
OCR1B=pwm;
}
for (pwm=255;pwm>0;pwm--)
{ _delay_loop_2 (2000);
OCR1A=pwm;
OCR1B=pwm;
}
}
}
能实现LED的渐亮渐灭~~
不知道对楼主有用不,GCC编译 void Huidu(void) /*灰度显示*/
{ uint i,j,k;
for(i=0;i<=255;i++) /*由明到暗,255个灰度等级*/
{ for(k=0;k<=20;k++) /每灰度等级显示时间*/
{ for(j=0;j<=255;j++) /*显示每个灰度等级*/
{ if(j>=i)
{P1=0x00;}/*亮LED*/
else
{P1=0xff;} /*灭LED*/
}
}
}
}
for(i=0;i<=255;i++)/*由暗到明*/
{ for(k=0;k<=20;k++)
{ for(j=0;j<=255;j++)
{ if(j<=i)
{P1=ox00;} /*亮LED*/
else
{P1=0xff;} /*灭LED*/
}
}
} 不就是个简单的灰度占空比显示吗!哪那么麻烦的用那个PMW控制 强人 还没碰到这类问题 下面为一个试验程序,自己玩玩的
#include <io.h>
#include <delay.h>
#define uchar unsigned char
#define uint unsigned int
uchar tab[]={0B11101111,0B11000111,0B10000011,0B00000000};
// Declare your global variables here
void main(void)
{ uint aa;
bit cc;
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0xFF;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=1
PORTD=0x01;
DDRD=0x01;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
while (1)
{
for(aa=2000;aa!=0;aa--)
{
PORTB=tab;
delay_us(25);
PORTB=tab;
delay_us(16);
PORTB=tab;
delay_us(8);
PORTB=tab;
delay_us(1); }
cc=tab&128;
tab<<=1;
if(cc)tab|=1;
cc=tab&128;
tab<<=1;
if(cc)tab|=1;
cc=tab&128;
tab<<=1;
if(cc)tab|=1;
cc=tab&128;
tab<<=1;
if(cc)tab|=1;
// Place your code here
};
} 有现成的东西。 我编过此类程序,要考虑LED的辉光特性和人眼视觉暂留才最好 我想驱动一个半桥电路,两路想关联的PWM 不知道怎么设置?MEGA48芯片。 如果是控制一排LED,每个LED都是单独控制的要怎么控制? 如果是控制一排LED,每个LED都是单独控制的要怎么控制? 10楼的
那幅图真有意思,教教是怎么做出来的? 难得在这里看见个美女——清萤 /*灰度显示*/
和PWM不一样吧!
应该说亮的时间长短! 请问:
如果是用几个窜行移位寄存如74595连起来一排LED中,又是怎样控制其中一个LED的灰度? 以前在C51下写的,或许还有点点价值,60级亮度变化,占空比方式, 队列循环, 代码很乱,嘻嘻
点击此处下载ourdev_177655.zip(文件大小:29K) 并一个大的电解电容啊
呵呵 根据需求,软件编一个PWM或者是用单片机硬件PWM都可以。PWM控制比较省电。滤波可以免了,还省电容。PWM频率不能太低,做到了上K就可以了,不会闪烁。 " 难得在这里看见个美女——清萤 "
太吸引眼球了 哈哈 在LED显示屏里,就是用串行移位芯片将很多LED串起来的,他可以实行每一点的256级变化,我想不明白他的算法是怎样的 大家都是
强人
呵呵
我一周前开始学习,以后少不了要向大家请教! 记号,学习~~~ 好的,我也是初学者,大家多多关照!! 学习了 调节的是数码管的呢?有谁做过这样的啊 用DVD显示屏驱动芯片,1元 这些程序是16单片机吗?
刚入门不太了解,谢谢了!! 我做过温湿度数码管显示,反正单片机的速度足够高,找一定时器,快速扫描,保证所有数码管扫描一遍的时间在人眼不闪烁的速度(10ms以下),例如,设置一个char型计数单元,如果等于0,先把数码管的数据送出到并口,如果等于1,就第一个数码管亮,等于2的时候把数码管1关闭,同时把数码2的数据送到并口上,等于3的时候数码管2亮,以此类推.以上程序在定时器中断中实现,变量每次累加一次.如果变量大于某个数,就直接等于255,则下一个中断,此变量就等于0了,整个显示过程重新开始.
变量变到255的门限(就是每次加一之后,某个数值之后变为255)太小时,循环显示的周期就非常快,数码管的亮度较高,当然可以通过限流电阻控制,如果通过软件控制,就通过设置门限方法,门限越大,则亮度越暗,同时循环的周期越长,因为只有开始的几次计数,数码管亮,后续的数码管不亮,只是变量在累加,所以如果门限值太高了,会造成闪烁(当然把定时器的中断速度提高也可以解决闪烁问题),如果太低就太亮,所以调试的时候选择一个合理门限即可.参考如下.
SIGNAL(SIG_OVERFLOW2)
{
// Reinitialize Timer2's value
TCNT2 = 0xa3; // 重新赋值
// TODO: Add your code here
//sbi(PIND, 0X07);
//sbi(PINB, 0X01);
static unsigned char led_count = 0; // 显示计数变量
switch(led_count)
{
case 0: // 第一个数码管的数据准备,数据显示开始
{
wendu_test = 1;
UDR0 = DIS_DATA1;
break;
}
case 1: // 第一个数码管亮
{
cbi(PORTC, 0);
break;
}
case 2: // 第一个数码管灭,第二个数码管数据准备
{
sbi(PORTC, 0);
UDR0 = DIS_DATA2;
break;
}
case 3: // 第二个数码管亮
{
cbi(PORTC, 1);
break;
}
case 4: // 第二个数码管灭,第三个数码管数据准备
{
sbi(PORTC, 1);
UDR0 = DIS_DATA3;
break;
}
case 5: // 第三个数码管亮
{
cbi(PORTC, 2);
break;
}
case 6: // 第三个数码管灭,第四个数码管数据准备
{
sbi(PORTC, 2);
UDR0 = DIS_DATA4;
break;
}
case 7: // 第四个数码管亮
{
cbi(PORTC, 3);
break;
}
case 8: // 第四个数码管灭,数据显示完毕
{
sbi(PORTC, 3);
wendu_test = 0;
break;
}
default: // 其它时间,判断是否该重新开始显示了,用于控制亮度和避免闪烁
{
if (led_count > 50) // 此0.5ms时钟最小循环要大于15以上
led_count = 255;
}
}
led_count++; // 每次中断累加一次
} 见过美女...嘿嘿.. 你可以利用PWM信号的占空比的变化来实现,用的是LED的余辉效应,而且你可以利用循环自加自减的方法来改变占空比的时间程度,这样就不用专门的定时器,也不会出现肉眼识别的闪动,完全是无极变化,我做过一个,是用在霓虹灯上当的,可行! PWM可以平稳的渐灭??? 很简单嘛!用AVR单片机的PWM在某个管脚上输出,循环地递增或递减地调整PWM的占空比,这样LED就会渐亮渐暗了。 这样能平稳的熄灭吗? 一般在灰度比较低的时候容易出现闪烁. 但频率足够高的话就能平稳地熄灭.
不过人眼看到的LED的亮度与PWM的占空比是非线性的. mark 用快速PWM 什么单片机引脚电平翻转那么快?我用M16跑到33M都不能实现...
以现像来看,再快两倍也不一定行. 谢谢各位了。 up一下,学习了 直接用电感是不是也可以 PWM输出后滤波,再接LED 用一个定时器就可以了.设置全局pwm值.定时10us一级.这样一点都不闪.我做了个rgb灯就是这么做的.很漂亮的. mark 做得都很好! 学习。。。 kankan .看看。^_^ 哪位好心人帮一下,我用的是ATtiny13单片机,要在PB0引脚输出一个PWM的脉冲控制LED的亮度,试了好多次都没成功,谁能编一个这样的程序,好象很少有人用ATtiny13啊,先谢谢了! 呵呵
我的思路也是pwm 是啊,用的就是PWM,最好是快速PWM,但程序不知为什么不工作?代码如下:
请高手帮忙看看有什么地方不对, 我烧到片子上,LED始终是高亮状态,没有亮度上的变化.
#include <iot13v.h>
#include <macros.h>
//#include <avr/delay.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uint tm)
{
uint i;
for(i=0;i<tm;i++)
{
;
}
}
void main ()
{
uchar pwm=0x00;
TCCR0A=0xA3;
TCCR0B=0x09;
TCNT0=0;
PORTB=0xFE;//PB0=0
DDRB=(1<<PB0); //PB0 output
// DDRB|=0xf6;
//PORTB|=0xf6;
while (1)
{
for (pwm=0;pwm<255;pwm++)
{
delay (2000);
OCR0A=pwm;
OCR0B=pwm;
}
for (pwm=255;pwm>0;pwm--)
{
delay(2000);
OCR0A=pwm;
OCR0B=pwm;
}
}
} 没有人懂吗? 以前学51的时候编过脉宽控制LED亮度的,效果不错,只是在点亮和熄灭那一小段时间不好处理!!现在在学习AVR中. 以下程序可实现由暗到亮,至于由亮到暗,自己考虑一下吧,很简单啦。
for(b=0;b<255;b++)
{
for(c=0;c<b;c++)
{
for(d=0;d<=5;d++)
{
IO2CLR = 0xffffffff; /*亮LED*/
}
}
for(e=0;e<255-b;e++)
{
for(f=0;f<=5;f++)
{
IO2SET = 0xffffffff; /*灭LED*/
}
}
}
这是两年前做的程序啦。在c8051f上通过spi控制led实现渐明渐暗,效果还不错。如果哪位朋友在做c8051f的话,我可以提供完整的程序(QQ:115917569)。对了,IO2CLR和IO2SET是lpc2220的寄存器名,因为昨天晚上我在smartarm2200上试了一下,不过效果不如c8051f。
还有:20楼的程序昨天也试过了,没有效果。 PWM控制LED渐亮渐灭,好想法. mark T=20ms,调节占空比OK Q 我也贴一个
.INCLUDE "TN13DEF.INC"
.DEF TMP=R16
.ORG $000
RJMP START
.ORG $00A
START: LDI TMP,$9F
OUT SPL,TMP
SBI DDRB,0 //OC0A引脚设置成输出
LDI TMP,$80
OUT OCR0A,TMP
LDI TMP,$03|$C0 //WGM=3,OCM0A=3
OUT TCCR0A,TMP //快速PWM模式 TOP=$FF
LDI TMP,$01
OUT TCCR0B,TMP //CS2:0 = 1 计数时钟不分频
HERE: RJMP HERE
改变OCR0A的值就可以调节点空比,如果频率太高,可以改变TCCR0B中的CS2-0的值,修改分频系数 那位高手可以请教下用ADC来控制PWM的占空比的程序吗?最好上个程序给我学习学习! 都是很有想法的人 大家都不错 帮顶! 留个号····· 回76楼:
OCR0/1A/1B/2控制占空比.
将ADC的数值关联到以上寄存器中就可以改变占空比. #include "system.h" //引用非标准库的头文件
int main(void)
{
int i,j,k,a1,a2,a3; //定义变量
SFIOR=0X04; //PUD位置位,上拉禁止
PORTA=0x00; //PA口输出低电平,上拉无效
DDRA=0x00; //PA口设为输入
DDRB=0XFF;
PORTB = 0X00;
while (1)
{
for (a1=0;a1<250;a1++)
{
for (a2=0;a2<20;a2++)
{
for (a3=0;a3<200;a3++)
{
if(a3>=a1) {PORTB|=(1<<PORTB3);PORTB&=~(1<<PORTB2);}
else {PORTB&=~(1<<PORTB3);PORTB|=(1<<PORTB2);}
}
}
}
for (a1=0;a1<250;a1++)
{
for (a2=0;a2<20;a2++)
{
for (a3=0;a3<200;a3++)
{
if(a3<=a1) {PORTB|=(1<<PORTB3);PORTB&=~(1<<PORTB2);}
else {PORTB&=~(1<<PORTB3);PORTB|=(1<<PORTB2);}
}
}
}
}
}
以上控制两个IO口。软件模拟的,测试过很好用。这个是最早学习的时候从网上找来的自己修改了一下。M16的芯片 频率太高,二极管是不是就不发光了啊,有没有这个可能? LED亮度的渐变过程,只要单独调亮度,不许要片子上的PWM专用口,只要编写一个加一(或减一)的累加程序即刻,选定累加区域的长度便可以调整不同的辉度等级.(也相当于逐渐的调整亮暗的占空比).
如果不是按阶段跳亮度(尤其同时也需要变化速度)最好是使用两个定时器,一个控制周期,一个控制周期内的占空比就可以了,要变化很多花样时,这是最简单的办法.这样可以随意选择输出管脚和输出路数. mark 我有个想法,用数字电位器做怎么样! 楼上的太。。。了吧。
第一,一般数字电位器电流不大。
第二,一般数字电位器价格不少,大才小用。 谢谢分享 ! mark 谢谢分享 正要用呢 使用定时来做才有意思用延迟 没意思啊 谢谢分享 占空比变化小点,频率高点就可以了吧 mark mark 顶起来! 做个记号 记号 顶 大家太强了,不得不踏一脚
页:
[1]
2