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ß
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.
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?
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
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.
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
...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!
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
> i_ergebnis+=ADCW;
Wo wird i_ergebnis eigentlich auf 0 gesetzt, ehe du die ganzen
Messergebnisse da drinn addierst?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.