LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: CBX em 19 de Maio de 2011, 17:37

Título: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 17:37
boas

estou a tentar diminuir a luminosidade de um led com fast PWM num attiny25, o que acontece é que o led nunca chega a apagar completamente quando o a instrução deixa de ser verdadeira, alguém me sabe dizer onde é que está o erro?

Código: [Seleccione]
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
OCR0A = 255;
TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
TCCR0B = (1<<CS01);
DDRB |= (1<<PB0);

while(OCR0A > 0)
{
_delay_ms(10);
OCR0A--;
}
}

Título: Re: duvida em fast PWM
Enviado por: msr em 19 de Maio de 2011, 18:24
Quando a condição deixa de ser verdadeira (OCR0A > 0) pões logo o PWM ao máximo (OCR0A = 255;), nem sequer existe o delay de 10ms. Isto porque quando ele sai do ciclo while o MCU faz um reset e volta a correr o programa.

Experimenta por um while(1); a seguir ao teu ciclo while para ver se o LED não fica permanentemente apagado.

De qualquer das maneiras valores baixos (proximos de zero) do duty cycle já deveriam dar para ver o LED apagado...

Título: Re: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 18:33
não, neste caso quando a condição deixa de ser verdadeira pára, se a condição for while(OCR0A >= 0) é que reinicia...

de qualquer maneira já testei o código seguinte e é igual, não desliga completamente:

Código: [Seleccione]
while(1)
{
OCR0A = 0;
}

tenho que ir ler melhor a datasheet para ver se é algum register mal definido...
Título: Re: duvida em fast PWM
Enviado por: msr em 19 de Maio de 2011, 18:40
Nos PICs quando o programa atinge o fim do código é feito reset automaticamente. Nos AVRs não?

Mas realmente se lhe pões OCR0A=0; deveria desligar...
Tens o ânodo do LED ligado directamente à saída do PWM ou estás usar algum transistor como switch?
Título: Re: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 18:42
apenas uma resistência para limitar a corrente, 1k, era o que tinha à mão...

se o loop for infinito é claro que reinicia, mas neste caso não é...
Título: Re: duvida em fast PWM
Enviado por: senso em 19 de Maio de 2011, 18:43
Não, o gcc quando detecta o fim do main, entra num loop infinito com as interrupções desligadas, porque um micro-controlador não tem para onde retornar, logo fica num ciclo infinito para não ficar a fazer resets para sempre.
Isso é porque >0 é 1, logo ainda dá impulsos.
Título: Re: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 18:52
então porque é que quando eu substituo o loop por isto:

Código: [Seleccione]
while(1)
{
OCR0A = 0;
}

retirando "OCR0A = 255;" do inicio do programa o resultado é exactamente o mesmo?
Título: Re: duvida em fast PWM
Enviado por: senso em 19 de Maio de 2011, 18:56
Pode ser por a resistência ser muito elevada, mas já vou ver se o código está certo.
Tens o programador ligado á placa?
O PB0 é o MOSI do ISP.
Título: Re: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 19:38
sim é o MOSI, também já tinha pensado nisso, mas mesmo desligando o programador fica igual

alterei a resistência para 470r, é igual...

entretanto vou testar com um mega328...
Título: Re: duvida em fast PWM
Enviado por: senso em 19 de Maio de 2011, 19:45
Experimenta baixar o clock do pwm, só porque sim.
Título: Re: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 20:42
fica igual  ::)

por ex:
Código: [Seleccione]
TCCR0B |= (1<<CS01); // Fcpu/64
Título: Re: duvida em fast PWM
Enviado por: GnGz em 19 de Maio de 2011, 21:13
fica igual  ::)

por ex:
Código: [Seleccione]
TCCR0B |= (1<<CS01); // Fcpu/64

Quando está 1 no CS01 não é fcpu/8 ?
Título: Re: duvida em fast PWM
Enviado por: CBX em 19 de Maio de 2011, 21:26
sim é, copiei o errado, mas também não interessa o problema não é dai  ???

o correcto seria ((1 << CS10) | (1 << CS11));
Título: Re: duvida em fast PWM
Enviado por: GnGz em 19 de Maio de 2011, 21:33
Sim
Título: Re: duvida em fast PWM
Enviado por: CBX em 25 de Maio de 2011, 18:57
boas

lembrei-me de testar o código com umas modificações no timer1 só porque sim e, bem funciona como deve:

Código: [Seleccione]
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
OCR1A = 255;
DDRB |= (1<<PB1);
TCCR1 |= ((1<<PWM1A) | (1<<COM1A1) | (1<<CS01));

while(OCR1A>0)
{
_delay_ms(10);
OCR1A--;
}
}

só não consigo perceber é porque é que não funciona no, PB0, timer0  ???

obrigado a todos...