Controlar PWM con un potenciómetro usando atmega328p

1

Estoy usando un atmega328p y quiero controlar el ciclo de trabajo de PWM con un potenciómetro.

La frecuencia es de 20 ms y el ciclo de trabajo está entre 0 ms y 2 ms. Problema: cuando simulo esto en Proteus, el PWM no funcionó, este es mi código:

#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif

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


int main(void)
{
    DDRB |= 1<< PINB1 ;

    TCCR1A |= 1<< COM1A0 | 1<< COM1A1 | 1<<WGM11 ;
    TCCR1B |= 1<< WGM12 | 1<<WGM13 | 1<<CS10 | 1<<CS11 ;
    ICR1 = 4999 ; // 50 Hz

    ADCSRA |= 1<<ADEN | 1<< ADIE | 1<<ADPS2 | 1<<ADPS1 ;  // 64 prescaler
    ADMUX |= REFS0 ;
    sei();
    ADCSRA |= 1<<ADSC ;
    while (1) 
    {
    }
}

ISR(ADC_vect)
{
 uint8_t low = ADCL ;
 uint16_t tenvar = ADCH << 8 | low ;  // value from potentiometer 10 bit

 OCR1A = 4999 - ((499/1024)*tenvar ); // OCR1A is between 4999 and 4500 (4500 represent 2ms )


 ADCSRA |= 1<< ADSC ;
 }
    
pregunta Mourad

2 respuestas

2
((499/1024)*tenvar )

Oops.

(tenvar * 499L / 1024)

A menos que realmente no te importe que el resultado siempre sea 0

    
respondido por el Ignacio Vazquez-Abrams
0

Encontré el problema: me olvidé de poner

1<<REFS0

en el registro ADMUX

y por simplicidad podría haber usado

OCR1A = 4999 - (ADC * 499L / 1024  ) ;

en lugar de

uint8_t low = ADCL ;
uint16_t tenvar = ADCH << 8 | low ;  

OCR1A = 4999 - (tenvar * 499L / 1024);
    
respondido por el Mourad

Lea otras preguntas en las etiquetas