Problema rápido de PWM y Atmega1280

Hola, tengo algunos problemas para entender cómo vincular un temporizador a un pin y por eso mi código no se ejecuta...

#include <avr/io.h>

void init_PWM(void)
{
    TCCR0A|=(1<<WGM00)|(1<<WGM01)|(1<<COM0A1)|(1<<CS00);

    //Set OC0 PIN as output. It is  PB3 on ATmega16 ATmega32

    DDRB|=(1<<PB7);
}

void setPWM(uint8_t duty)
{
   OCR0A = duty;
}

void main (void)
{
   uint8_t brightness = 0;
   init_PWM();

   for (brightness=0; brightness<=255; brightness++)
   {
      setPWM(brightness);
      _delay_ms(100);
   }
}

Mi problema es ¿cómo asignar el temporizador a PB7?

Mi objetivo es parpadear el LED en PB7 con el modo FastPWM.

Respuestas (1)

Ok, puedo ver algunos problemas con este código (supongo que esta es su hoja de datos ):

  • En primer lugar, si desea un desvanecimiento suave, use el temporizador de 16 bits en lugar de 8 bits (TCCR1A)
  • Desea Fast PWM sin embargo, lo tiene configurado en Phase Correct (pág. 148, desea el Modo 14)
  • No está indicando la frecuencia que desea, en el modo Fast PWM, de acuerdo con la hoja de datos, debe establecer el valor TOP, para hacer esto, debe realizar algún cálculo (fórmula en la página 152 en la parte superior).
  • Una vez que calculó su TOP, el ICR1 debe establecerse en ese valor (use un preescalador si su número es mayor que 65535, tabla en la página 161)
  • Para habilitar PWM en OC0A (PINB7), debe configurar COM0A1 y COM0A0

Consulte este ejemplo, es para el Atmega128 y utiliza un temporizador de 16 bits. La frecuencia es de 120 Hz y la velocidad del reloj de mi CPU es de 16 MHz. Por lo tanto, al usar la fórmula, terminé con un TOP (16665) y mi prescaler fue 8, creo.

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

int main(void) {

    //Fast PWM, using inverted mode (default low)
    TCCR1A |= 1<<WGM11 | 1<<COM1A1 | 1<<COM1A0;
    TCCR1B |= 1<<WGM12 | 1<<WGM13 | 1<<CS11;

    //Top
    ICR1 = 16665;

    //Set pins to input/output

    DDRB |= 1<<PINB5;

    OCR1A = 0;

    while(1) {
        //continuous loop where everything happens
        int i;

        for(i=0; OCR1A<ICR1; i+=166) {
            OCR1A = i;
            _delay_ms(6);
        }

        for(i=0; i<ICR1; i+=166) {
            OCR1A = ICR1 - i;
            _delay_ms(6);
        }

        OCR1A = 0;
        _delay_ms(500);

    }

}
+1 Respuesta muy completa. Debe poner en negrita la parte "(PINB7) que necesita para configurar tanto COM0A1 como COM0A0", ya que esa era la pregunta principal.