2017-02-16 2 views
0

J'essaie d'augmenter la luminosité d'une LED en utilisant PWM avec Timer0 sur le ATMega164PA. Après l'exécution de mon code ci-dessous la LED reste juste émise et ne varie pas sa luminosité.PWM avec ATMega164PA

S'il vous plaît jeter un oeil à mon code et me dire s'il y a quelque chose que je fais mal:

#include <avr/io.h> 
#include <util/delay.h> 
#include <avr/interrupt.h> 

int dutycycle = 0; // Variable for dutycycle 

/********************************************** MAIN ****************************************************/ 
int main(void) 
{ 
    DDRB |= (1 << PB3); // Make pins output and OC0A pin for PWM 

    TCCR0A |= (1 << COM0A1) | (1<<WGM01) | (1<<WGM00); // Clear OC0A on comare match and set OC0A at BOTTOM 

    TIMSK0 |= (1<<TOIE0); // Overflow Interrupt Enabled 

    TCNT0 = 0; // Set Counter Value Register for comparison with OCR0A 

    OCR0A = (dutycycle/100) * 255; // Set duty cycle ON period 

    sei();  // Enable global interrupts 

    TCCR0B |= (1 << CS00); // Prescale of 1 - start timer 

    while (1) 
    { 
     _delay_ms(500); 

     dutycycle += 10;  // increase duty cycle by 10% every 500ms 

     if (dutycycle > 100) // if duty cycle is greater than 100% set to 0 
     { 
      dutycycle = 0; 
     } 
    } 
} 

ISR(TIMER0_OVF_vect) 
{ 
    OCR0A = (dutycycle/100) * 255; // Set duty cycle ON period 
} 

Répondre

3

Je ne suis pas sûr de la logique de votre approche, mais je peux voir un problème évident que vous cause des difficultés.

La division entière ne produit pas de fraction. Au lieu de cela, il arrondit le résultat à l'entier le plus proche. Cela signifie que dutycycle/100 sera presque toujours 0, puisque vous vous assurez que dutycycle <= 100. Alors OCR0A est presque toujours 0. La seule exception est quand dutycycle est exactement 100, qui fixe OCR0A à 255.

Une façon de contourner cela est d'utiliser OCR0A = dutycycle * 255/100; à la place. Je ne sais pas si cela va régler tous les problèmes, juste le premier que je vois.

+0

J'essaie d'augmenter le facteur de marche de 10% jusqu'à ce qu'il atteigne 100%. Lorsque cela se produit, je veux remettre la valeur du cycle de service à 0 et répéter. Je n'obtiens une sortie que lorsque je change la valeur entière en haut de mon code, il semble que le calcul à l'intérieur de la ligne principale est ignoré et OCR0A est juste assigné à l'entier du cycle de service. J'ai fait le changement que vous avez suggéré mais toujours pas de chance :( – LoneCoder