Forum: Mikrocontroller und Digitale Elektronik Potentiometer Einlesefehler


von TMB11FK (Gast)


Angehängte Dateien:

Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von schrammler (Gast)


Lesenswert?

hey!

Macht mal die doppelten Includes, Defines und das erste main() raus. 
Bekommt ihr keinen Fehler beim Kompilieren?

von Karl H. (kbuchegg)


Lesenswert?

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

von TMB11FK (Gast)


Angehängte Dateien:

Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

Noch Lust auf ein paar Kommentare und Vorschläge?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.