ATmega32 ADC mit Timer0 Autotrigger

In diesem C Codebeispiel sampelt der ATmega32 ADC mit Hilfe des Timer0 Autotriggers in regelmässigen, zeitlichen Abständen ein Analogsignal.

electroicsplanet home electroicsplanet pagetree Sourcecode Examples electroicsplanet pagetree ATmega32 electroicsplanet pagetree ADC electroicsplanet pagetree ADC mit Timer0 Trigger

Beschreibung

Der ADC wird mit der Comparefunktion des Timer 0 getriggert. Timer 0 zählt von 0 bis zum Wert im Register OCR 0. Soblad dieser Wert erreicht ist, beginnt er von vorne zu zählen (CTC Mode). Das OC3 Signal an PB3 wird immer beim Compare match getoggelt. Zu diesem Zeitpunkt liest der ADC einen Wert ein. Soblad dies abgeschlossen ist, wird der Conversion Finished Interrupt ausgeführt. Die Routine vergleicht den ADC Wert mit 512 und schaltet PB4 je nach Vergleichsresultat. Auf dem Plot ist gut sichtbar, dass dieses Umschalten nur zusammen mit dem Toggeln von OC0 stattfindet.

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

int main(void)
{

    DDRB = 0x0c;                     // Setup PB2 and PB3 as output

    OCR0 = 243;                      // Set the capturevalue
    
    TCCR0 |= (1<<CS02)|(1<<CS00)|    // Start timer0 with prescaler 1024
             (1<<WGM01)|(1<<COM00);  // CTC mode, toggle OC0 on compare match
  
    SFIOR |= (1<<ADTS0)|(1<<ADTS1);  // Set Timer 0 Compare as ADC trigger
 
    ADMUX |= (1<<REFS0);             // Set reference to AVcc

    ADCSRA |= (1<<ADEN)|(1<<ADATE)|  // Enable ADC, Enable auto Triggering
              (1<<ADPS2)|(1<<ADIE);  // Set prescaler to 16
                                     // Fadc=Fcpu/prescaler= 1000000/16=62.5kHz
                                     // Fadc should be between 50kHz and 200kHz

    sei();                           // Set the I-bit in SREG

    for(;;);                         // Endless loop;
                                     // main() will never be left

    return 0;                        // This line will never be executed

}

// Interrupt subroutine for ADC conversion complete interrupt
ISR(ADC_vect)
{
        if(ADC >= 512)                // Compare the conversionresult with 512
            PORTB |= 0x04;            // If larger, set PB3
        else
            PORTB &= ~0x04;           // If smaller, reset PB3

        TIFR |= (1<<OCF0);            // Clear the Timer 0 interruptflag
}


Download lauffähiges C-File mit ASCII-Schema: Downloadlink

Signalplots

ADC Autotrigger Timer0

Gelb: ADC Input PA0
Blau: Timer0 Output Capture Signal
Rot: PB2, zeigt an, ob der ADC wert grösser als 512 ist