Problema rápido de PWM y Atmega1280

2

Hola, tengo algunos problemas para entender cómo enlazar un temporizador a un Pin y, debido a eso, mi código no se está ejecutando ...

#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.

    
pregunta Martin Nikolaev

1 respuesta

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 PWM rápido, pero lo tiene configurado en la Corrección de fase (pág. 148, desea el Modo 14)
  • No está indicando la frecuencia que desea, en el modo PWM rápido, De acuerdo con la hoja de datos que necesita para establecer el valor TOP, para hacer esto necesita realizar algún cálculo (fórmula en la página 152 en la parte superior).
  • Una vez que haya calculado su TOP, el ICR1 debe configurarse a ese valor (use un prescaler si su número es mayor que 65535, tabla en la página 161)
  • Para habilitar PWM en OC0A (PINB7), debe configurar tanto COM0A1 como amp; COM0A0

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

#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);

    }

}
    
respondido por el 1337holiday

Lea otras preguntas en las etiquetas