Leggere un valore analogico direttamente dal registro ADCH in asincrono

A suo tempo avevo fatto anche io delle prove per ADC FreeRunning ed avevo verificato la lettura anche su due canali diversi (passaggio da A0 ed A1 e viceversa) ... magari questo programmino può essere utile :wink: :

#include <avr/sfr_defs.h>

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

void setup() {
   delay ( 500 );
   Serial.begin ( 115200 );
   //
   // Init ADC for freeRunning mode prescaler 32, VREF internal 5V, start on A0
   ADCSRA = 0;
   sbi ( ADCSRA, ADEN );
   sbi ( ADCSRA, ADATE );
   sbi ( ADCSRA, ADPS2 );
   sbi ( ADCSRA, ADPS0 );

   ADCSRB = 0;

   ADMUX  = 0x40;

   sbi ( ADCSRA, ADSC );
}

void loop() {
   int analog_A0, analog_A1;
   unsigned long tStart_0, tEnd_0, tStart_1, tEnd_1;
   //
   // read 10 times A0 and then calculates the average of the values
   tStart_0 = micros();
   analog_A0 = 0;
   for ( byte i = 0; i < 10; i++ ) {
      loop_until_bit_is_set ( ADCSRA, ADIF );
      analog_A0 += ADC;
      cbi ( ADCSRA, ADIF );
   }
   tEnd_0 = micros();
   analog_A0 /= 10;
   //
   // switch to analog port A1
   tStart_1 = micros();
   cbi ( ADCSRA, ADEN );
   ADMUX  = 0x41;
   sbi ( ADCSRA, ADEN );
   sbi ( ADCSRA, ADSC );
   // read one time analog port A1
   loop_until_bit_is_set ( ADCSRA, ADIF );
   analog_A1 = ADC;
   cbi ( ADCSRA, ADIF );
   //
   // switch back to analog port A0
   cbi ( ADCSRA, ADEN );
   ADMUX  = 0x40;
   sbi ( ADCSRA, ADEN );
   sbi ( ADCSRA, ADSC );
   tEnd_1 = micros();
   //
   // print the values
   Serial.print ( "Valore A0 = " );
   Serial.print ( analog_A0 );
   Serial.print ( " - Elapsed time 0 = " );
   Serial.println ( tEnd_0 - tStart_0 );
   Serial.print ( "Valore A1 = " );
   Serial.print ( analog_A1 );
   Serial.print ( " - Elapsed time 1 = " );
   Serial.println ( tEnd_1 - tStart_1 );
}

Guglielmo

1 Like