PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit ADC Single conversion(ATMEGA 32)



2linkehaende
14.01.2011, 12:41
ich möchte mit meine programm eine single conversion starten und das ergebnis auf 16 led´s ausgeben

doch irgendwie funktioniert mein programm nicht ](*,)

könnt ihr mir bitte helfen!

//Hauptprogramm

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

void ADC_Init(void); //Prototyp des Unterprogramms

int main (void)

{

//Definitionen der Ports

DDRC = 0xff; //Port A als Ausgang definieren
PORTC = 0x00; //Port A wird auf low gelegt
DDRB = 0xff; //Port B als Ausgang definieren
PORTB = 0x00; //Port B wird auf low gelegt

DDRD = 0x00; //Port D als Eingang definieren
PORTD = 0xff; //Pull-Up aktivieren

uint16_t xl,xh;

while(1)
{

MCUCR|=(1<<ISC01)|(1<<ISC00); //Steigende Flanke löst Interrupt aus

sei(); //Interruptes global erlauben

xl = ADCL;
xh= ADCH;

PORTC = xl;
PORTB = xh;
}

}

ISR(INT0_vect) //INT0 ist der externe Interrupt0
{

ADC_Init(); //Aufruf des Unterprogramms ADC_Init

}


//--------------------------------------------------------------------------------------------
//Erstellung eines Unterprogramms zur AD Wandlung


void ADC_Init(void)
{
ADMUX = (1<<REFS1) | (1<<REFS0); //Verwendung der internen Referenzspannungsquelle
ADCSRA |= (1<<ADEN); // ADC aktivieren

ADCSRA |= (1<<ADSC); // Start einer ADC-Wandlung im single mode Betrieb
}

Carry
14.01.2011, 13:02
Hallo,

was genau funktioniert denn nicht?

Auf die Schnelle fällt mir auf, dass 'INT0' nicht aktiviert wird. Im Register 'MCUCR' werden nur die Flanken eingestellt. Es gibt noch ein Register mit 'Interrupt 0 Enable' oder so.


Carry

Hubert.G
14.01.2011, 15:12
Du initialisierst den ADC andauernd neu.
Alles was in deiner while(1) Schleife steht, hat dort nichts zu suchen.

2linkehaende
14.01.2011, 19:03
ok danke schon mal für die hilfe

das mit int0 intialisieren hab ich ganz vergessen...

allerdings das mit der while versteh ich nicht ganz, brauche ich den die komplette while garnicht?!

Hubert.G
14.01.2011, 19:49
Du solltest mit den Klammern immer etwas einrücken damit man sieht was zusammen gehört.
Der ADC init wird in der ISR des Int0 aufgerufen.
Du solltest initalisieren und aufrufen trennen.
Das initialisieren sollte ins main.
Du kannst nicht im while das ADC-Register abfragen wenn du nicht weisst ob die conversion schon fertig ist.
Der Ablauf sollte etwa so sein:
Im main
Port definieren, variable definieren, INT0 aktivieren, ADC initialisieren aber nicht aufrufen und Interrupt aktivieren.
Die while bleibt vorläufig leer.
In der ISR Int0 den ADC starten.
In der ISR des ADC die ADC Register den Port zuweisen.
Fertig.

Dirk
14.01.2011, 19:54
... und ADIF noch löschen:
ADCSRA |= (1<<ADIF);

Hubert.G
15.01.2011, 09:14
Wenn man den ADC-Interrupt verwendet wird das ADIF automatisch gelöscht.

2linkehaende
21.01.2011, 12:19
Ich hab mein programm jetzt nochmal korregiert jedoch bekomme ich jetzt diesen fehler:
../ADWANDLER.c:32: error: `GICR' undeclared (first use in this function)

mein compiler erkennt irgendwie das GICR register nicht?!


ich verwende übrigens einen atmega32

erkennt irgendwer den fehler?


//Hauptprogramm

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

void ADC_Init(void); //Prototyp des Unterprogramms

int main (void)

{

//Definitionen der Ports

DDRC = 0xff; //Port A als Ausgang definieren
PORTC = 0x00; //Port A wird auf low gelegt
DDRB = 0xff; //Port B als Ausgang definieren
PORTB = 0x00; //Port B wird auf low gelegt

DDRD = 0x00; //Port D als Eingang definieren
PORTD = 0xff; //Pull-Up aktivieren




sei(); //Interruptes global erlauben
GICR |= (1<<INT0); //Interruptauslösung erlauben
MCUCR |= (1<<ISC01)|(1<<ISC00); //Steigende Flanke löst Interrupt aus

ADCSRA |= (1<<ADEN); // ADC aktivieren
ADMUX = (1<<REFS1) | (1<<REFS0); //Verwendung der internen Referenzspannungsquelle

while(1)
{}

}

ISR(INT0_vect) //INT0 ist der externe Interrupt0
{

ADC_Init(); //Aufruf des Unterprogramms ADC_Init

}


//--------------------------------------------------------------------------------------------
//Erstellung eines Unterprogramms zur AD Wandlung


void ADC_Init(void)
{

uint16_t xl,xh;

ADCSRA |= (1<<ADSC); // Start einer ADC-Wandlung im single mode Betrieb

xl = ADCL;
xh= ADCH;

PORTC = xl;
PORTB = xh;

}

Hubert.G
21.01.2011, 13:46
Bei mir kompiliert es fehlerfrei.
Hast du den richtigen Kontrollertyp angegeben.
Mit welchem Kompiler arbeitest du?

2linkehaende
22.01.2011, 09:35
win avr unter avr studio

und was den kontroller angeht hab ich denn richtigen ausgewählt

aber trotzdem vielen dank für deine hilfe ich werde in den nächsten tagen einfach mal auf einem anderen pc komplieren!