ATmega16 ADC mit Timer 0 Compare Autotrigger
In diesem Sorucecodebeispiel sampelt der ATmega16 ADC mit Hilfe des Timer0 Autotriggers in regelmässigen Abständen ein Analogsignal.
Beschreibung
Der ADC wird mit dem Compare Compare des Timer 0 autogetriggert. Timer 0 zählt von 0 bis zum Wert im Register OCR 0. Wenn er diese Wert erreicht beginnt er von vorne zu zählen (CTC).
Beim Rücksprung wird das OC0 Signal am Port B3 getoggelt. Ausserdem wird eine Analogwandlung gestartet. Wenn die Wandlung fertig ist, wird der Conversion Finished Interrupt
ausgeführt. Die Routine vergleicht den ADC Wert mit 512 und schaltet den Ausgang PB4. Auf dem Plot ist gut sichtbar, dass dieses Umschalten nur zusammen mit dem Toggeln von
OC0 stattfindet. |
Please visit: the four |
#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 C-Sourcefile mit ASCII-Schema: C-Sourcefile mit ACII-Schema
Signalplots
Gelb: Analoges Eingangssignal PA0
|