Estoy tratando de configurar mi ATMEGA328p para medir la temperatura usando el sensor de temperatura TMP36GZ. Sin embargo, el ADC de 10 bits sigue devolviendo 1023. He intentado desconectar el sensor de temperatura (debería devolver 0 en este punto para la lectura de ADC), pero aún así devuelve 1023. No estoy exactamente seguro de lo que estoy haciendo mal en mi código:
volatile uint16_t TMP36_VoutADCReading = 0U;
void TMP36_Init( void )
{
// Set the ADC prescaler to 128 (i.e., 16MHz/128 = 125KHz)
ADCSRA |= ( 1 << ADPS2 ) | ( 1 << ADPS1 ) | ( 1 << ADPS0 );
// Set the voltage reference from AVcc (i.e., 5V).
ADMUX |= ( 1 << REFS0 );
// Turn on the ADC.
ADCSRA |= ( 1 << ADEN );
// Do the initial conversion (i.e., the slowest conversion)
// to ensure that everything is up and running.
ADCSRA |= ( 1 << ADSC );
}
void TMP36_ADCRead( uint8_t channel )
{
// Clear the previously read channel.
// ADCSRA &= 0xf0; <-- This was causing the bug.
ADMUX &= 0xf0; // <-- This is the fix. Thanks IgnacioVazquez-Abrams!
// Select the ADC channel to be read.
ADMUX |= channel;
// Start a new conversion. By default, this conversion will
// be performed in single conversion mode.
ADCSRA |= ( 1 << ADSC );
// Wait until the conversion is complete.
// while( ADCSRA & ( 1 << ADSC ) ); <-- This is probably also correct.
while( ADCSRA & ( 1 << ADIF ) ); // <-- Added. Thanks Adithya!
// Obtain the ADC reading from Vout.
TMP36_VoutADCReading = ADC;
// Clear the ADIF flag.
ADCSRA |= ( 1 << ADIF ); // <-- Just added. Thanks Adithya!
}
int main( void )
{
// Disable all interrupts for the time being.
cli();
// Initialize the TMP36GZ temperature sensor.
TMP36_Init();
// Enable all interrupts.
sei();
while( 1 )
{
// Compute the distance.
uint8_t channel = 1;
TMP36_ADCRead( channel ); // At this point, TMP36_VoutADCReading = 1023
}
}
En términos de conexiones, estoy intentando leer el voltaje de salida del pin PC1 en el ATMEGA328p y tengo AVcc conectado a VCC y el pin 22 (es decir, GND) conectado a la GND del pin 8. He deshabilitado el ajuste de la referencia de voltaje de AREF, entonces AREF no esta conectado
Cualquier ayuda sería muy apreciada.
ACTUALIZACIÓN:
Ignacio Vázquez-Abrams señaló que ADCSRA &= 0xf0;
debería haber sido ADMUX &= 0xf0;
. Desde entonces he modificado el código anterior. También, ¡gracias Adithya por la sugerencia que hiciste sobre la comprobación de la bandera de ADIF! Lo tomaré en consideración.