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
-
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?
#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--;
}
}
-
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...
-
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:
while(1)
{
OCR0A = 0;
}
tenho que ir ler melhor a datasheet para ver se é algum register mal definido...
-
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?
-
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 é...
-
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.
-
então porque é que quando eu substituo o loop por isto:
while(1)
{
OCR0A = 0;
}
retirando "OCR0A = 255;" do inicio do programa o resultado é exactamente o mesmo?
-
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.
-
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...
-
Experimenta baixar o clock do pwm, só porque sim.
-
fica igual ::)
por ex:
TCCR0B |= (1<<CS01); // Fcpu/64
-
fica igual ::)
por ex:
TCCR0B |= (1<<CS01); // Fcpu/64
Quando está 1 no CS01 não é fcpu/8 ?
-
sim é, copiei o errado, mas também não interessa o problema não é dai ???
o correcto seria ((1 << CS10) | (1 << CS11));
-
Sim
-
boas
lembrei-me de testar o código com umas modificações no timer1 só porque sim e, bem funciona como deve:
#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...