1 votos

Atmega32 PWM en los cuatro pines PWM

Estoy tratando de controlar el brillo de los LEDs usando PWM en el Atmega32. Tengo un LED conectado a cada uno de los 4 pines PWM (OC0, OC1A, OC1B, y OC2). Usando el código de abajo, todos los LEDs funcionan como se espera, excepto el LED conectado a OC1A que permanece oscuro. ¿Por qué ocurre esto? Gracias por su ayuda.

#define  F_CPU 100000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>

void InitPWM()
{

   TCCR0  |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);
   TCCR1A |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00); 
   TCCR1B |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);
   TCCR2  |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);

}

int main(void)
{

    //Configure the ADC
    ADCSRA |= 1<<ADPS2;         //Enable a prescaler
    ADMUX |= 1<<ADLAR;          //8-bit or 10-bit results
    ADMUX |= 1<<REFS0;
    ADCSRA |= 1<<ADIE;          //Enable interrupts function in ADC
    ADCSRA |= 1<<ADEN;          //Turn on the ADC feature
    sei();                      //Enable global interrupts
    ADCSRA |= 1<<ADSC;          //Start the first conversion

    DDRB = 0xFF;                // initialize port B
    DDRD = 0xFF;                // initialize port D

    InitPWM();                  //initialize PWM mode

    while(1)
    {
        OCR0 = 100;
        OCR1A = 100;
        OCR1B = 100;
        OCR2 = 100;

        _delay_ms(500);        

        OCR0 = 255;
        OCR1A =255;
        OCR1B = 255;
        OCR2 = 255;

        _delay_ms(500);       
    }

}

ISR(ADC_vect) // interrupt routine and display the results
{
char adcResult[4];
itoa(ADCH, adcResult, 10);

ADCSRA |= 1<<ADSC; //Start the next conversion 
}

2voto

Andrew Walker Puntos 9038

Aunque puede que no sea tu único problema (por ejemplo, tu código es muy ligero en cuanto a la configuración y parece depender mucho de los valores por defecto, lo que puede no ser lo que suponías) un problema grave que salta a la vista está en el uso inadecuado del TCCR0 -máscaras de bits específicas para todos los registros de configuración del temporizador:

TCCR0  |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);
TCCR1A |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00); 
TCCR1B |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);
TCCR2  |= (1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);

De hecho, no son todos iguales, y los de TCCR1A están entre los más singular .

Si examina <avr/iom32.h> o presumiblemente la hoja de datos, verá por ejemplo que los bits WGM disponibles en TCCR1A se llaman WGM11 y WGM10 no WGM01 y WGM00 que no están presentes en este registro y que tienen valores diferentes cuando se producen para TCCR0 que los bits funcionalmente comparables en TCCR1A hacer.

Así que, como mínimo, tienes que corregir el bloque de código de configuración citado para utilizar los nombres de patrones de bits adecuados o, al menos, los valores aplicables a cada uno de los registros que estás intentando configurar.

Pero, de forma más general, debería comprobar dos veces todo registros implicados, tanto del temporizador como de nivel superior, que intervienen para que esto funcione, y asegúrese de que los valores que establece explícitamente o en los que confía a partir de los valores predeterminados de encendido son de hecho los adecuados para su objetivo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X