Hello there!
I wrote a program in C with the help of all the great Tutorials from AVR-Freaks. It suppose to do several things. I'll connect a switched capacitor filter to my schematic and this part needs a clock source. I decided to produce that clock with the ATMega 128 Timer. This works already. Furthermore I need to do an analog digital conversion of the output of that filter and decided to use the ADC within the ATMega128 in 10BIT mode, continuous sampling. This works as well. For test reasons I put the result of the conversion on a LCD. I get the ADC register (ADCL/ADCH) printed correct on the LCD and when I measure the voltage I get the right result if I multiply my ADC with the reference Voltage and divide this by 1024. So I put that equation into my program but I just don't get the right result on my display. Later on I want to send the result on a UART but one step at a time, right?
Another thing is that the code in main.c is not executed anymore as soon as the ADC is running. Is there a possibility to run that code as well? Here there are just a few LED's flashing for test reaons. They flash with the activated Timer but not with the activated ADC anymore. Any suggestions on this topic? I'm pretty new to interrupts so maybe I am missing something important.
EDIT:
Almost forgot:
CPU: Atmega 128 at 16MHz external Clock source
Language: C
Software: AVR Studio 4.14 using WinAVR 20080610
Fuses: see attached Image.
END of EDIT.
Here is my code:
#define VREF 2480 //measured VRef pin in mV #define F_CPU 16000000 // important for delay.h #include#include #include #include #include #include "lcd.h" int main (void) { int i = 0; // Port E als Ausgang (als Kontrolle, ob die CPU noch arbeitet) DDRE = 0xFF; // TIMER DEFINITION //================= // Setze Port 5 als Ausgang (filter_CLK fuer LTC1067) DDRB |= (1 << 5); // Timer 1 in CTC mode konfigurieren TCCR1B |= (1 << WGM12); // Timer 1 Compare Output channel A in Toggle Modus aktivieren TCCR1A |= (1 << COM1A0); // Setze CTC Vergleichswert auf 20kHz bei 16MHz AVR Takt, Mit einem Vorteiler von 8 OCR1A = 49; // Starte Timer 1 mit Fcpu/8 TCCR1B |= (1 << CS11); // ADC DEFINITION //=============== // Setze ADC Vorteiler auf 128 - 125KHz Sample Rate @ 16MHz ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Setze ADC Referenzspannung auf AVCC ADMUX |= (1 << REFS0); // Setze ADC Referenzspannung auf Intere 2.56V Referenz mit ext. Kondensator am AREF Pin ADMUX |= (1 << REFS1) | (1 << REFS0); // Keine MUX Werte muessen geaendert werden um ADC0 zu verwenden // Setze ADC in den Free-Running Modus ADCSRA |= (1 << ADFR); // Aktiviere ADC ADCSRA |= (1 << ADEN); // Aktiviere ADC Interrupt ADCSRA |= (1 << ADIE); // Start A/D Konvertierung ADCSRA |= (1 << ADSC); //LCD Initialisierung lcd_init(); // Aktiviere Globale Interrupts sei(); while (1) //loop forever { //some kind of "Cyclone Eye" to show that the CPU is not stuck for(i = 1; i < 64; i = i*2) { PORTE = i; _delay_ms(70); } for(i = 64; i > 1; i -= i/2) { PORTE = i; _delay_ms(70); } // End of Cyclone Eye } } // Ende von main ISR(ADC_vect) { char temp [9]; uint16_t num; uint32_t voltage; // erst ADCL auslesen, dann ADCH , WICHTIG! Reihenfolge beachten... // bei ATMega 128 kann auch einfach ADC ausgelesen werden, 16BIT breit //ADC_Ergebnis |= ADCL; //ADC_Ergebnis |= (ADCH << 8); num = ADC; voltage = (num * VREF) / 1024; itoa (num,temp,10); set_cursor(0,1); lcd_data('A'); lcd_data('D'); lcd_data('C'); lcd_data(':'); lcd_data(91); lcd_string(temp); lcd_data(93); lcd_data(32); itoa (voltage,temp,10); set_cursor(0,2); lcd_data(91); lcd_string(temp); lcd_data(32); lcd_data('m'); lcd_data('V'); lcd_data(32); lcd_data(93); lcd_data(32); _delay_ms(50); }