Hi, im Anhang haben wir unser aktuelles Programm für unsere LED Ansteuerung in Abhängigkeit der Potistellung. Wir arbeiten mit einem ATmega8 auf einem myAVR Board MK2. Wenn der Mikrocontroller zum ersten Mal die Schleife durchläuft, liest er den richtigen Wert am PortC0 aus und es wird das richtige Ergebnis (z.B. 3 LEDs blinken) angezeigt Wenn das Programm läuft wird unabhängig von der Potistellung immer das gleiche, zu Beginn richtige, Ergebnis ausgegeben (3 LEDs blinken). Das passiert, obwohl wir am Anfang der do- Schleife value auf "0" setzten (grüne LED an). Value wird also überschrieben, bekommt aber immer wieder den "Anfangswert"?! Hat das eventuell etwas mit dem ADCW Befehl zu tun, der eventuell durch eine fehlende Headerdatei nicht richtig ausgeführt wird? Danke im Voraus TMB11FK
1 | #define F_CPU 3686400 // Taktferquenz des myAVR-Boards
|
2 | #include <avr/io.h> |
3 | #include <util/delay.h> |
4 | |
5 | |
6 | int main() |
7 | {
|
8 | #define F_CPU 3686400 // Taktferquenz des myAVR-Boards
|
9 | #include <avr/io.h> |
10 | #include <util/delay.h> |
11 | :
|
12 | :
|
Hast du mal nachgesehen, ob andere Programme auch so aufgebaut sind? Wie sieht die Schaltung aus? Was ist am Pin Aref angeschlossen? > Hat das eventuell etwas mit dem ADCW Befehl zu tun, der eventuell durch > eine fehlende Headerdatei nicht richtig ausgeführt wird? Wenn der Compiler eine Datei nicht findet, dann sagt er dir das schon rechtzeitig vor da ein Hexfile rauskommt...
hey! Macht mal die doppelten Includes, Defines und das erste main() raus. Bekommt ihr keinen Fehler beim Kompilieren?
Gewöhn dir solche Sachen
1 | ADCSRA=0xC0; // single conversion mode ein |
gleich wieder ab. Das macht es extrem schwer zu kontrollieren, was da eigentlich passiert und was da alles mit dem 0xC0 geschaltet wird. Du willst an dieser Stelle den ADC starten. Dazu muss das Bit ADSC in ADCSRA gesetzt werden. Dann schreib das auch so, dass man das erkennen kann
1 | ADCSAR |= ( 1 << ADSC ); |
Genauso bei der Abfrage, ob der ADC fertig ist. Der ADC setzt das Bit ADSC zurück, wenn er fertig ist. D.h. man muss so lange warten, wie das Bit gesetzt ist. Das schreibt sich dann als
1 | while( ADCSRA & ( 1 << ADSC ) ) |
2 | ;
|
In diesen Schreibweisen kann man direkt er-'lesen' mit welchen Bits gearbeitet wird und mit ein wenig Übung kennt man dann auch die Auswirkung dieser Bits, die sich oft aus dem Namen ergibt. ADSC ist die Abkürzung für "Adc Start Conversion". Kennt man diese Abkürzung, dann kennt man auch die Funktion. Und das ist sehr viel leichter zu merken und zu kontrollieren, als wie wenn man mit dem Datenblatt neben dem Monitor die Bits erst mal auseinanderdröseln muss, um zu sehen ob du nicht durch die Zuweisung von 0xC0 nicht irgendeine andere Einstellung verstellt hast. Hier finden sich ein paar getestete ADC Funktionen AVR-GCC-Tutorial/Analoge Ein- und Ausgabe: Nutzung des ADC
Vielen Dank für die Anregungen, im Programm waren das doppelte int main samt include nicht enthalten, das ist aus versehen beim reinkopieren entstanden. Mit den Änderungen von Karl Heinz Buchegger funktioniert das Programm nun einwandfrei. Wahrscheinlich hat es sich an meiner umständlichen while-Warteschleife aufgehängt. Im Anhang das verbesserte, lauffähige Programm. Nochmals Danke TMB11FK PS: Für alle die, wie ich noch vor 3 Tagen, Probleme mit der Eingangsdeklaration des Potis am Mikrokontroller haben - ADC ATmega8: http://www.avr-modelleisenbahn.de/atmega8/18-analog-digital-wandler.htm
TMB11FK schrieb: > Mit den Änderungen von Karl Heinz Buchegger funktioniert das Programm > nun einwandfrei. Wahrscheinlich hat es sich an meiner umständlichen > while-Warteschleife aufgehängt. Wahrscheinlich nicht. Es hat sich am ADIF: ADC Interrupt Flag aufgehängt. Denn dieses Bit wird dann gesetzt, wenn eine Wandlung fertig ist (unabhängig davon, ob du Interrupts verwendest oder nicht). Und dieses Flag kann nur durch einen Aufruf einer Interruptroutine oder durch explizites Schreiben einer '1' gelöscht werden (richtig: '1' fürs Löschen!). Deshalb müsstest du also sowas machen: ADCSRA=0xD0; // single conversion mode ein, reset interrupt-flag Dann klappts auch mit deinem Original-Code...
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.