Forum: Compiler & IDEs ADC Konflikt bei 2 Aufrufen


von Mark P. (pisy)


Lesenswert?

Hallo,
ich habe ein Programm in dem ich zweimal den ADC aufrufe innerhalb von 
Unterprogrammen.
Wenn ich mir beide ausgeben lasse, dann setzt das Programm alle Werte 
die ich auf C0 einlesen auf 0. Wenn ich nur einen aufrufen lasse, dann 
funktioniert es. Ich habe den Fehler wirklich auf den ADC beschränken 
können, da das Programm ingesamt 8 Seiten lang ist schreibe ich jetzt 
chronologisch die wichtigen Teile heraus (ich muss es jetzt abtippen 
habe vergessen es auf der Arbeit zu kopieren, ich bitte um Nachsicht bei 
Rechtschreibfehlern z.B. wenn ich ein Simikolon vergesse oder so, diese 
Fehler sind alle behoben):

DDRC&=~(1<<DDC);

//erste Einlesefunktion

unit16_t einlesen (uint8_t i_spg_plex)
{
i_int index;
unit16_t i_ergebnis;
ADCSRA=(1<<ADEN)|(1<<ADDPS2)|(1<<ADPS0);
ADMUX=i_spg_plex;
ADMUX|=(1<<REFS0);

ADCSRA|=(1<<ADSC);

while (ADCSRA & (1<<ADSC))
{
;
}
for (i_index=0;i_index<10;i_index++)

{ADCSRA|=(1<<ADSC);

while (ADCSRA &(1<<ADSC))
{
;
}
i_ergebnis+=ADSW;
}

ADCSRA &=~(1<<ADEN);

e_ergebnis /=10;
return i_ergebnis;
}

//Zweite Einlesefunktion

void initADC()
{
ADCSRA=0b11000111;
}



unsigned char spannung (void)
sbi (ADCSRA,6);
while (ADCSRA & 0x40)
{
}
return (unsigned char) (ADC/4);
}




main ()
{
init ADC();
ADMUX=0b11000000;
sbi (ADCSRA,6);

result=spannung();

pidsense=einlesen(2);

}


Woran könnte der Fehler liegen, ich habe mir erhofft das ich den ADC 
doch wieder freigebe in der Funktion einlesen.
Ich bin auch erst seit 3 Wochen mit C in Berührung als das ich jetzt 
sofort den Fehler finde.
Für alle Tips bin ich dankbar.

Gruß

von STK500-Besitzer (Gast)


Lesenswert?

Dein Programm lässt sich nicht compilieren, die Formatierung erzeugt 
Augenkrebs und Kommentare sind dir beim Tippen wohl abhanden gekommen.

>ADMUX=0b11000000;
>sbi (ADCSRA,6);

Es gibt diese wunderschöne Bitschieberei mit den Bitnamen. Das ist 
wesentlich übersichtlicher als das, was du da schreibst.

von Mark P. (pisy)


Lesenswert?

Lässt sich bestimmt nicht kompilieren weil es aus dem Zusammenhang 
gerissen ist. Klar habe ich die Kommentare nicht mit abgetippt, hab 
gedacht es sei eindeutig.
Also ich habe die Teile geschrieben wo die Bits mit Namen benannt 
worden, dass andere ist eine Arbei von einem Vorgänger, ich sollte die 
beide Programme verknüpfen. Bis auf den Punkt des ADC funktioniert es 
wunderbar.
Wenn es denn klappt, mache ich es in schön.
Aber es ist nich der Fehler den du benannt hast oder?

von Peter D. (peda)


Lesenswert?

Mark Pisani schrieb:
> Rechtschreibfehlern z.B. wenn ich ein Simikolon vergesse oder so, diese
> Fehler sind alle behoben):

Du wirst lachen, ich hatte mal einen Fehler gesucht und das Programm hat 
genau deshalb nicht richtig funktioniert, weil ein Semikolon gefehlt 
hat.

Und wenn Du schon etwas länger programmierst, wirst Du sehr gut 
verstehen können, daß hier allgemein eine große Abneigung gegen 
Programmschnipsel besteht, die nicht per copy&paste erstellt wurden, 
nicht compilierbar sind und nicht kommentiert sind.
Auch ist Dateianhang immer besser, da manche Ausdrücke sonst verstümmelt 
werden, wenn man nichtmal die Postingregeln (Formatierung) liest.


Man muß dem Helfenden nicht die Füße küssen, aber auch nicht möglichst 
viel Steine in den Weg legen.


Peter

von Mark P. (pisy)


Lesenswert?

Okay, dann muss ich warten bis Montag, da kann ich es 1:1 kopieren.
Aber dennoch zeigt mir der Compiler doch die Fehler an, die ich dann 
beheben kann und solche sind doch dann behoben.
Hätte ja sein können, dass ich ihn an irgendeiner Stelle doppelt 
initialisiere oder nicht wieder freigebe.

von Mark P. (Gast)


Lesenswert?

So hier die beiden Funktionen:

// ADC einlesen
uint16_t einlesen (uint8_t i_spg_plex)

{
  int i_index;
  uint16_t i_ergebnis;
  ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);
  ADMUX= i_spg_plex;
  ADMUX|=(1<<REFS0); //Beide auf 1 gesetzt, damit gilt interne 
Referenzspannung
  ADCSRA|=(1<<ADSC);

  while (ADCSRA & (1<<ADSC))
  {
    ; //wartet bis Wandlung abgeschlossen ist
  }

  for (i_index=0;i_index<10;i_index++)
  {
    //Anfang For-Schleife

    ADCSRA|=(1<<ADSC);
    while (ADCSRA &(1<<ADSC))
    {
      ;
    }
    i_ergebnis+=ADCW;

  }
  //Ende For-Schleife

  ADCSRA &=~(1<<ADEN);  //ADC auf Low setzten, ADC kann wieder als I/O 
genutzt werden

  i_ergebnis /=10;
  return i_ergebnis;
}
//----------------------------------------------------------------------

void initADC()
{
  ADCSRA=0b11000111;      //0b11000011, ADC-Clock, ADC ON
}

unsigned char spannung(void)    //Auswertung ADC...
{

  sbi  (ADCSRA,6);    // restart ADC
  while (ADCSRA & 0x40)
  {
  }      //ende warteschleife für AD-Wandlung


  return (unsigned char) (ADC/4);

}



main ()
{
  initADC();
  init();
  uint16_t result;
int i_index=0;
  int count=0;
  int checksum=0;
  ADMUX=0b11000000; //ADC Kanal C0
  sbi  (ADCSRA,6);  // restart ADC
  count=1;
  while (true) // Mainloop

result=spannung();
i_pidsense=einlesen(2);
}


i_pidsense ist eine volatile, wie gesagt es sind sehr viele Seiten, das 
gesamte Werk befindet sich im Anhang

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

...das ist doch sicher nicht copy&pasted ;-)
Oder Du hast tatsächlich das Problem, dass Dir ein Semikolon, ein 
Compound-Statement, etc. fehlt.

Btw.: Lies Dir mal die Formatierungsregeln durch: es gibt hier im Forum 
einen Syntaxhighlighter, der macht das Lesen von Sourcecode wesentlich 
einfacher! Und Dein Anhang fehlt!

von Mark P. (pisy)


Angehängte Dateien:

Lesenswert?

Hatte mein Passwort vergessen, aber habs jetzt wieder.
Deswegen hier der Anhang.
Ich habe eben eine zweite Funktion programmiert, in etwa wie die 
Funktion "einlesen" eben nur mit einem anderen Divisionsfaktor.
Ich bin soweit, dass ich mir jetzt beide Werte ausgeben lassen kann.
Nur wird die neue Funktion nun richtig ausgegeben, bei einer Vref von 
5,4 Volt wird ein Wert zwischen 0-255 ausgegeben. Anders jetzt bei der 
alten FUnktion die bis jetzt immer lief. Bei einer Spannung von z.B. 1V 
wird nun 1300 ausgegeben.
Schneide ich den ersten Aufruf, also die neue Funktion raus klappt es 
wieder mit den richtigen Werten.
Es ist ein Teufelskreis:D

von Karl H. (kbuchegg)


Lesenswert?

>     i_ergebnis+=ADCW;


Wo wird i_ergebnis eigentlich auf 0 gesetzt, ehe du die ganzen 
Messergebnisse da drinn addierst?

von Mark P. (pisy)


Lesenswert?

Danke klappt.
Hätte mich jetzt weiter totgesucht;)

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.