Estaba tratando de simular en proteus ADC con potenciómetro y obtener la lectura para controlar el motor de CC con PWM, está funcionando, pero el problema es que el valor de ADC no es preciso. ADCH alcanza el valor máximo antes de que el potenciómetro esté al 100%. No sé por qué este comportamiento. Espero que me lo puedas explicar. Aquí está el código.
#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>
void pwm_init()
{
DDRB |= (1<<PB3);
TCCR0 |= (1<<WGM00) | (1<<WGM01) | (1<<COM01) | (1<<CS01);
OCR0 = 0x00;
}
void adc_init()
{
DDRA =0x00;
ADMUX |= (1<<REFS0);// AVCC ref
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADLAR) | (1<<ADATE); // 1MHZ With
prescaler 8 gives adc freq 125 khz
}
uint8_t adc_read()
{
ADCSRA |= (1<<ADSC);
while(!(ADCSRA && (1<<ADIF)));
ADCSRA |= (1<<ADIF);
return ADC;
}
int main(void)
{
pwm_init();
adc_init();
while (1)
{
OCR0 = adc_read();
}
}
También puede ver en la imagen de abajo que el ciclo de trabajo es casi del 100%, mientras que el potenciómetro es solo del 12%.
Si ADLAR = 1, entonces de acuerdo con la hoja de datos (sección 26.8.4, ver adjunto), el resultado de ADC se alinea a la izquierda con el par de 16 bits ADCH-ADCL.
Su función adc_read()
devuelve un entero de 8 bits. Por lo tanto, devuelve solo ADCL
(ver figura), porque los 8 bits superiores se pierden en la conversión uint_16->uint_8.
En otras palabras, si A0 o A1 son 1, obtendrá un valor de servicio grande, porque el valor devuelto por adc_read()
estará entre 0x40 y 0xC0.
Solución: en su función adc_read()
de retorno ADCH
solamente.
Además, el potenciómetro debe estar conectado a una fuente de voltaje con AREF volt, donde AREF es el voltaje de referencia del ADC. Si está utilizando la referencia interna, no conecte el potenciómetro directamente al pin AREF, porque dicho pin tiene una capacidad de corriente de salida muy pequeña.
Gracias, chicos, por su ayuda
Encontré el problema.
Configuré ADLAR en el registro ADCSRA y debería configurarse en ADMUX. Lo arreglé y todo funcionó bien.
Ale..chenski
usuario247954
bruce abbott
G36