Hallo Leute,
obwohl ich schon das eine oder andere Mal mit AVRs gearbeitet und mich
ebenfalls mit den Tutorial zum ADC beschäftigt habe, komme ich leider
gerade nicht weiter. Im Anhang von diesem Beitrag habe ich meine
Schlatung als Schematic angefügt, so wie ich sie auf einer
Lochrasterplatine gelötet habe.
Es sollen LEDs (PortD am uC) per Software-PWM gedimmt werden. Die
Helligkeit für jede Farbe soll dabei über einen Poti eingestellt werden
können (P1 - P3 im Schematic). Nichts außergewöhnliches, wie ich denke.
Zur Hardware:
------------
Die Ansteuerung der LEDs selber funktioniert einwandfrei. Wenn ich die
Ausgänge an PortD "fest" auf 1 setze, verhält sich die Schaltung wie
gewollt. Mein Problem bezieht sich lediglich auf das Einlesen der
Spannungswerte der Potis P1 - P3 an PortA. Was ich schon mal mit
Sicherheit sagen kann, ist, dass sich der Spannungswert von jedem Pin
des uC ändert, wenn am Poti gedreht wird. Der Spannungsbereich liegt wie
erwartet zwischen 5V und 0V. Da nur ein ADC im ATMega32 vorhanden ist,
müssen die drei Potis also nacheinander ausgelesen werden.
Die Spule zwischen VCC und AVCC des uCs aus dem ADC-ASM-Tutorial habe
ich durch einen 47 Ohm Widerstand ersetzt (Hinweis dazu steht ebenfalls
im Tutorial). Als Referenzspannung für den ADC soll die interne
Referenz, also die Spannung an AVCC genutzt werden. Vref ist deswegen
mit einer 100nF Kapazität gegen GND gezogen. Im Betrieb kann ich an AVCC
ein Spannung von 4,11V und an Vref ein Spannung von 3,7V messen.
Als Taktgeber ist der interne RC-Oszillator des AVR auf 8MHz eingestellt
worden. Für die n-MOS-Transistoren (Q1 - Q6) habe ich den IRLD024
gewählt.
Fragen dazu:
- Ist der Aufbau soweit in Ordnung?
- Gibt es Stellen die verbessert werden sollten?
- Ist es ein Wunder, dass diese Schaltung überhaupt funktioniert?
Zur Software:
------------
Im ersten Schritt wollte ich probieren nur einmal die Spannung vom Poti
P1 an Port A, Pin 0 des uCs einzulesen. Abhängig davon soll eine LED an-
oder ausgeschaltet werden. Anschalten wenn, der Wert des ADC > 0x7F ist,
andernfalls LED aus.
Hier mein bisheriges Assembler-Programm (Beschreibung folgt danach):
1
.include "m32def.inc" ; Definitionsdatei
2
3
;Definitions
4
.def A = r0
5
.def prg = r1
6
.def temp = r16
7
.def D = r17
8
.def counter1 = r18
9
.def counter2 = r19
10
.def red_light = r20
11
.def green_light = r21
12
.def blue_light = r22
13
14
; Stackpointer initialisieren
15
LDI temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
16
OUT SPL, temp
17
LDI temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
18
OUT SPH, temp
19
20
;Ein- & Ausgänge definieren
21
LDI temp,0b11110000
22
OUT DDRA,temp ; Eingänge für Potis und den Schalter setzen
Beschreibung vom Testcode:
-------------------------
Zuerst wird der Stackpointer initialisiert und die Ein- und Ausgänge
definiert.
Bei der Initialisierung vom ADC wird eingestellt, dass die interne
Spannung als Refernz genommen und das Ergebnis einer Wandlung
linksbündig in den ADC-Registern ADCH, ADCL abgelegt werden soll.
Dann wird ca. 30ms gewartet.
Den ADC einschalten und den Prescaller auf 64 setzen. Bei 8MHz ergibt
das dann eine ADC-Frequenz von 125kHz.
Dann wird erneut ca. 30ms gewartet.
Durch "SBI ADCSRA, ADSC" wird eine Konvertierung gestartet.
Warten, bis der ADC fertig ist.
Das Ergebnis vom ADC auslesen, den Vergleich durchführen und eine LED
entsprechend anschalten, falls Bedingung nicht gültig.
Danach -> Endlossschleife.
Fragen dazu:
-----------
Ich vermute, dass in der SW irgendwo was nicht stimmt. Soweit ich weiss,
gibt es bei ATMega32 auch keine Fuse-Bits, die den ADC ein- oder
ausschalten.
- Wo ist der Fehler?
- Wie ist das mit den Wartezeiten, müssen die dahin oder nicht? (Glaube
da mal was in der Doku zu uC gelesen zu haben.
- Bin ich halbwegs auf den richtigen Weg?
Vielen Dank schon mal im voraus und ich freue mich über jede Hilfe! :)
Da dieses Thema ja nicht gerade der Renner zu sein scheint, hier mal ein
"push". Ist der Eintrag zu lang, zu unverständlich oder uninteressant?
Bin ich mit meinem Vorhaben grundsätzlich auf dem richtigen Weg?
Hi
Ein paar Bemerkungen:
> OUT ADMUX, temp> RCALL WAIT_30ms
Das Warten kannst du stecken lassen. Ist unnötig.
> IN red_light , ADCL> IN green_light, ADCH> CPI red_light, 0x7F
In ADCL sind die niederwertigsten 2 Bit deines ADC-Wertes. ADCL kann bei
ADLAR=1 nur die Werte $00, $40, $80 und $C0 annehmen. Welchen Wert genau
ist aber eher Zufall. Die eigentliche Information über die Stellung des
Potis befindet sich in ADCH.
> BRLO endless> SBI PORTD, 1>endless:> RJMP endless
Damit macht dein Programm genau einen Durchlauf. Danach keine Reaktion
mehr. Besser duspringst nach
> SBI ADCSRA, ADSC
zurück. Dann musst du aber, bei nicht erfüllter Bedingung, die Led auch
wieder ausschalten.
MfG Spess
Hallo,
vielen Dank für die Antworten erstmal. Ich werde eure Vorschläge nachher
mal ausprobieren. An meiner HW-Schaltung ist sonst soweit nichts
auszusetzen?
spess53 schrieb:
> Das Warten kannst du stecken lassen. Ist unnötig.
Alles klar. :)
spess53 schrieb:
> In ADCL sind die niederwertigsten 2 Bit deines ADC-Wertes. ADCL kann bei> ADLAR=1 nur die Werte $00, $40, $80 und $C0 annehmen. Welchen Wert genau> ist aber eher Zufall. Die eigentliche Information über die Stellung des> Potis befindet sich in ADCH.
Vollkommen richtig, vielen Dank für den Hinweis.
spess53 schrieb:
> ...> Damit macht dein Programm genau einen Durchlauf. Danach keine Reaktion> mehr.
Stimmt! In diesem Fall war dies so gewollt, auch wenn es ungünstig ist.
Mein Verfahren war 1. Poti gegen 0V drehen -> 2. reset -> 3. schauen was
passiert -> 4. Poti gegen 5V drehen -> 5. reset -> 6. siehe Schritt 3
Die Schleife ist dennoch praktischer. :)
Schönen Gruß
Der 100nF-C am Reset sollte max. 4,7nF sein, sonst könnte ein
angeschlossener Programmer Schwierigkeiten beim Programmieren haben.
An VCC fehlt dagegen der 100nF-C.
Blackbird
Hi
> An meiner HW-Schaltung ist sonst soweit nichts auszusetzen?
Da hatte ich nicht so drauf geachtet. Was mir auffällt:
>Im Betrieb kann ich an AVCC>ein Spannung von 4,11V und an Vref ein Spannung von 3,7V messen.
Ist das mit dem aufgespieltem Programm gemessen? Bei initialisiertem ADC
sollt VREF identisch mit AVCC sein. Und AVCC sollte auch nicht
wesentlich kleiner als VCC sein.
MfG Spess
Hallo
Blackbird schrieb:
> Der 100nF-C am Reset sollte max. 4,7nF sein, sonst könnte ein> angeschlossener Programmer Schwierigkeiten beim Programmieren haben.> An VCC fehlt dagegen der 100nF-C.
Alles klar, programmieren geht zwar, werde die Kapazitäten trotzdem mal
ersetzen bzw. hinzufügen.
spess53 schrieb:
> Ist das mit dem aufgespieltem Programm gemessen?
Ja.
spess53 schrieb:
> Bei initialisiertem ADC sollt VREF identisch mit AVCC sein. Und AVCC> sollte auch nicht wesentlich kleiner als VCC sein.
Da dem nicht so ist, muss ja über R2 im Schematic eine Spannung
abfallen, was wiederum einem Stromfluss erfordert. Ich weiss nicht
genau, wie hoch der Einfangswiderstand von AVCC ist, aber ich vermute
mal sehr hoch (~1MOhm). Falls ich damit richtig liege, sollte doch da
ansich eher kein "großer" Strom fliessen.
Warum sich jetzt genau VREF und AVCC unterscheiden kann ich mir nicht
erklären. Die Schuld dem uC zuzuschieben, scheint mir da etwas einfach.
Schönen Gruß :)
Hi
>Ich weiss nicht genau, wie hoch der Einfangswiderstand von AVCC ist, aber>ich vermute mal sehr hoch (~1MOhm).
Da vermutest du falsch. AVCC ist ein Stromversorgungsanschluß. Damit
wird der ADC und PortA versorgt.
MfG Spess
Moin
spess53 schrieb:
> Da vermutest du falsch. AVCC ist ein Stromversorgungsanschluß. Damit> wird der ADC und PortA versorgt.
Gut, dann klärt sich das schon mal damit, warum AVCC kleiner als VCC
ist. Den genauen Wert vom Strom kann ich nachher mal messen, aber
grundsätzlich würde ich diesen im folgenden Bereich einordnen: (5V -
4,11V) / 47 Ohm = ~19mA.
Richtig soweit?
Gruß! :)
Hallo Leute,
vielen Dank für eure Tipps und Hinweise, das Problem ist gelöst. Das
ironische ist, dass es dann wirklich am uC lag. Selbst nach Änderung der
HW und SW entsprechend den Hinweisen hierm funktionierte die Schaltung
erst nicht. Nachdem ich den uC ausgetauscht hatte, lief alles wunderbar.
Als Fazit, das in diesem Beitrag beschriebene Problem lag am uC selber.
Meinetwegen kann der Thread daher gelöscht werden.
Vielen Dank!