Hi!
Ich probier gerade die ADC Wandlung mit Interrupt, so dass der Wert auf
dem LCD Display aktualisiert wird.
Ohne Interrupt hab ichs zum laufen gebracht, aber sobald ich sei();
einfüge, scheint das Programm stecken zu bleiben und die LCD Ausgabe
wird nicht mehr erreicht.
Kann mir bitte wer helfen?
Danke!
andi
Ich bin kein großer Atmel Kenner, vermute aber, dass du die while
Schleife im Interrupt nicht verlässt.
folgende Zeile startet ja bereits deine AD-Wandlung:
ADCSRA =
(1<<ADEN)|(1<<ADSC)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE)|(1<<ADATE);
sobald die Wandlung komplett ist wird das zugehörige Flag für den
Wandler gesetzt und gleichzeitig ADSC gelöscht!
die Schleife
while (ADCSRA & (1<<ADSC))
{
}
wird somit nie verlassen, da ADSC nun bereits 0 ist
Generell ist der AD Interrupt eigentlich dazu da, dass man eben nicht
auf die Fertigstellung der Konversion warten muss, wozu also die
Schleife? Sobald der Interrupt aufgerufen wird ist das AD Ergebnis
bereits vorhanden.
Soweit ich das noch weiß, brauchst du in deiner Interuptroutine nicht
mehr warten, bis der uC fertig gewandelt hat, sondern die Routine wird
ja aufgrufen, wenn ein Wert bereit ist.
Nebenbei würde ich in der Initialisierung vom adc_value lieber den
Datentyp long nehmen, da der auf jedenfall 26 bit ist und nicht wie int
systemabhängig
und ich würde zum einen noch volatile davor schreiben,
außerdem adc_value= ADC (ist einfacher)
UND da adc_value aus 2 Bytes besteht den Interrupt sperren wenn ich es
im main auslese.
und die Anzeige wird häßlich flimmern
DANKE für alle Tips, ich hab jetzt was geändert und es funktioniert
soweit.
Frage: Warum fängt der angezeigte Wert bei 21 an und nicht bei Null.
Bei voll aufgedrehtem Poti wird 955 angezeigt und nicht 1024 (10 bit).
Ist das einfach so eine Art Streuung, und muss ich einfach 21 vom Wert
abziehen?.
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include"lcd.h"
4
#include<util/delay.h>
5
6
#define ADC_CHANNEL 1
7
8
volatileunsignedintadc_data;
9
charbuffer[7];
10
11
ISR(ADC_vect)
12
{
13
adc_data=ADC;
14
}
15
16
17
intmain(void)
18
{
19
20
ADMUX=(1<<REFS1)|(1<<REFS0);//Interne Referenz
21
ADMUX=(ADMUX&~(0x1F))|(0&0x1F);// Kanal A0 auswählen
Wie hast du denn dein Poti angeschlossen?
(Nimm es halt mal raus und verbinden den ADC Eingang direkt mit GND.
Dann muss deine Anzeige 0 sein. Genauso muss die Anzeige, wenn du die
Referenzspannung misst, 1023 sein)
Nein, es ist keine Streuung. So große Abweichungen solltest Du nicht
bekommen.
Wie sieht den der Schaltplan und Layout aus?
Hier ist ein vernünftiger Aufbau wichtig.
Gruß,
avrGerd
..also ich hab jetzt mal die Interrupt- Dinge rauskommentiert und der
ADC funktioniert immer noch, soll wohl heissen, dass mein Programm so
nicht funktioniert. Was kann das sein ?
[c]#include <avr/io.h>
#include <avr/interrupt.h>
#include "lcd.h"
#include <util/delay.h>
#define ADC_CHANNEL 1
volatile unsigned int adc_data;
char buffer[7];
//ISR (ADC_vect)
//{
//adc_data= ADC;
//}
int main(void)
{
ADMUX= (1<<REFS1)|(1<<REFS0);//Interne Referenz
ADMUX= (ADMUX & ~(0x1F))|(0&0x1F);// Kanal A0 auswählen
ADCSRA =
(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADATE)|(1<<ADPS2)|(1<<ADPS0);
lcd_init(LCD_DISP_ON);
lcd_clrscr();
//sei();
while(1)
{
lcd_gotoxy(0,0);
lcd_puts("ADC: ");
_delay_ms(1000);
lcd_clrscr();
lcd_gotoxy(6,0);
//cli();
itoa(ADC, buffer, 10);
//sei();
lcd_puts(buffer);
}
}[c]
@Karl Heinz Buchegger
@avrGerd
Das ist ein selber gebasteltes Experimentierboard, wo die Leitungen
etwas länger sind (ca 30cm), kann das schon einen Einfluss haben?
Der Grund für die langen Leitungen: Eigentlich ist das Board für PIC
Prozessoren, aber ich hab einfach vom Pollin Board die Ausgänge auf eine
Stiftleiste gelötet und in den Textool Sockel vom PIC- Board
reingesteckt. Vielleicht gibts da Nebeneffekte.
captnhanky schrieb:> @Karl Heinz Buchegger> @avrGerd>> Das ist ein selber gebasteltes Experimentierboard, wo die Leitungen> etwas länger sind (ca 30cm), kann das schon einen Einfluss haben?
30cm sind kein Problem.
Miss doch mal GND bzw. die Referenzspannung!
Dann weißt du, obs am Programm liegt oder der Hardware.
captnhanky schrieb:> Ist tatsächlich das Board, den PIN 40 vom Atmega32 kurzgeschlossen> ergibt 0.
Dann würde ich aber eher auf das Poti tippen, welches seinen Schleifer
eben nicht ganz bis an die Widerstandsbahnenden verdrehen kann, so dass
immer ein kleiner Spannungsteiler übrig bleibt.