Forum: Mikrocontroller und Digitale Elektronik Problem mit AD - Wandler


von Rumpelstilzchen 1. (billson)


Lesenswert?

hallo, ich habe ein problem mit dem analog digitalwandler meines 
atmega16.
das programm lässt sich einwandfrei compilieren. doch wenn ich den 
debugger starte, wird der wert umgewandelt, der interrupt gestartet, und 
wenn er dann in das unterprogramm zurückkehrt, bleibt er in der while 
schleife stecken, die zum warten bis zum abschluss der wandlung gedacht 
war.
kann mir jemand damit helfen?

andabei mein programm: der interrupt muss nicht unbedingt verwendet 
werden, doch ich hab ihn aus experimentellen gründen aktiviert.


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


void main()
{

  volatile int messung;

  DDRB=0xff;
  PORTB=0x00;
  ADMUX=0x20;
  ADCSRA=0x00;

  sei();          //Interrupts aktivieren

  while (1)
  {

    messung=ADW();

  }
}




ISR (ADC_vect)

{

  ADCSRA=0x00;

}


void ADW()

{
  int messung;

  ADCSRA =0xC8;

  while(ADSC)        //hier steckt der fehler
  {}

  messung=ADCH;
  return messung;
}

danke für die hilfe

von Johannes M. (johnny-m)


Lesenswert?

Wolfgang Graf wrote:
>   while(ADSC)        //hier steckt der fehler
>   {}
Gut erkannt! ADSC ist eine Bitnummer, die in einer Headerdatei definiert 
ist. Und die Nummer ist ungleich Null und dementsprechend immer wahr. 
Die (leere) Schleife wird also bis zum Sankt Nimmerleinstag 
ausgeführt... Schau mal im AVR-GCC-Tutorial nach, wie das mit den 
Bitzugriffen läuft (kleiner Tip: Es hat was mit Schiebeoperatoren zu 
tun)...

von Hubert G. (hubertg)


Lesenswert?

Ist nicht die ISR dafür da zu signalisieren das die Messung beendet ist. 
Worauf wartest du in der while-Schleife.

von Johannes M. (johnny-m)


Lesenswert?

Übrigens: Wenn Du am Ende von ADW() einfach
1
return ADCH;
schreibst, kannst Du Dir die funktionslokale Variable messung 
sparen...

von holger (Gast)


Lesenswert?

>>  while(ADSC)        //hier steckt der fehler

ADSC ist nur die Bitnummer dieses Bits. Das kannst du
so nicht direkt lesen. Das while(ADSC) endet also nie
weil ADSC ein Wert größer Null ist.

Du musst das Register lesen in dem ADSC steht
und entsprechend verknüpfen:

  while(ADCSRA & (1<<ADSC))

von Herbert vom Karvenzmann (Gast)


Lesenswert?

So würde ich das Programm nicht strukturieren. Busywait vertrödelt doch 
nur unnötig Rechenleistung. Dazu gibt es doch Alternativen.

Der ADC kann einen Interrupt auslösen wenn er fertig ist.

Der ADC kann im Free-Run-Mode vor sich hin werkeln, im Timer-Interrupt 
fragt (oder hieß das frägt ?) man mal so nebenbei sein letztes 
Ergebnis ab, sichert es und schaltet bei Bedarf den Eingangsmultiplexer 
um.

Das sind alles Methoden, bei denen der AVR nicht im Busywait hängt und 
derweil andere Dinge erledigen kann.

Gruß aus dem Karvendel,
HerBert

von Johannes M. (johnny-m)


Lesenswert?

Herbert vom Karvenzmann wrote:
> So würde ich das Programm nicht strukturieren. Busywait vertrödelt doch
> nur unnötig Rechenleistung. Dazu gibt es doch Alternativen.
Ich glaube nicht, dass ein Anfänger in seinem ersten Testprogramm 
irgendeinen Wert auf seine Rechenleistung legt. Warum muss immer alles 
gleich optimiert werden? Lasst ihn doch erst mal überhaupt was aus 
seinem ADC rausbekommen. Wenn er das Tutorial durcharbeitet, kommt er 
früher oder später selbst darauf...

von Martin (Gast)


Lesenswert?

Und ich würde der Funktion einen Datentyp geben, nicht void, bei void 
kannste keine Werte zurückgeben

von Johannes M. (johnny-m)


Lesenswert?

Martin wrote:
> Und ich würde der Funktion einen Datentyp geben, nicht void, bei void
> kannste keine Werte zurückgeben
Das stimmt allerdings...

von Rumpelstilzchen 1. (billson)


Lesenswert?

danke für die vielen meldungen, das ganze hat mich schon ein stück
weiter gebracht!
mfg

@ johnny m
du hattest recht, das mit der bitnummer war der fehler, ich war es nur 
so gewohnt, weil man bei einem 8051 controller so eine bitnummer direkt 
(so wie ich es obend versucht habe) abfragen kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.