Forum: Mikrocontroller und Digitale Elektronik [AVR|ASM] LED-Controller mit ATtiny12


von J. W. (jw-lighting)


Angehängte Dateien:

Lesenswert?

Hallo,

ich befinde mich so mitten im Einstieg in die µC-Welt.
Nachdem ich mich ein wenig mit C probiert habe 
(Beitrag "[AVR|C] Codeschloss Projekt - wie den Code verbessern"), habe ich gemerkt das mir 
ein besseres Verständnis der Hardware wichtig ist.

Ich habe hier 4 ATtiny12 rumliegen, die ich gerne als LED-Controller 
verwenden möchte.
Der Controller soll über eine 4-Bit Einstellmöglichkeit (z.B. 
DIP-Switches) verschiedene Modi für den Betrieb einer LED realisieren.

Zum Beispiel:
Dimmen in 10%-Schritten
Strobe (versch. Geschwindigkeiten) (wollte ich den Timer nutzen)

Ich habe nach einem kurzen Blick ins Tutorial hier mir gestern einfach 
mal die AVR-Befehlsreferenz (und Google) geschnappt und drauf los 
programmiert.
Das es nicht gleich 100% geklappt hat, war zu erwarten ;)

In meinem angehängten Beispielcode wird sich ein Fehler finden lassen. 
Meine Vermutung ist, dass es mit den Flags im SREG zu tun hat, da ich 
mehrfach hintereinander cpi ausführe. (nach der Marke 'inLoop')
Was kann ich nun tun, um diesen Fehler zu vermeiden?

Da ich mit 0-Ahnung eingestiegen bin, danke ich auch für jeden 
anderweitigen Verbesserungsvorschlag.

LG:
Jan W.

von Fehler (Gast)


Lesenswert?

>In meinem angehängten Beispielcode wird sich ein Fehler finden lassen.

vllt., aber besser du beschreibst den fehler mal. gibt es eine 
fehlermeldung? welche?

Viel Erfolg

MeinFehleer

von J. W. (jw-lighting)


Lesenswert?

Oh, sorry.
Klar, so könnt ihr ja auch nichts damit anfangen.

Das Listing habe ich ja auch angehängt. Fehler werden nicht ausgegeben.

PB0-PB3 dienen zur Eingabe des Modus (die besagten 4-bit). PB4 ist der 
Ausgabepin, an dem die LED z.B. über einen ULN2803A oder 2x BC547 in 
Darlingtonschaltung angeschlossen ist.


Die Verwendung der Register habe ich am Anfang kommentiert.

1
loop:  cpi r20, 0x00  ; compare with 0
2
  brne setHigh  ; jump and set output high if r20 is not 0
3
inLoop:  in r17, PINB  ; load i/o
4
;[...]
5
6
setHigh: sbi PORTB, 5  ; set output to high
7
   rjmp inLoop  ; jump back

loop bis zu 'rjmp loop' ist der Teil, in dem ich den Modus abfrage und 
auf die entsprechenden Unterabschnitte verzweige.
Da ich über die Dip-Switches die LED auch vollständig aus schalten 
können möchte, muss ich das Einschalten bedingen.
Dazu prüfe ich r20. steht in r20 ein Wert anders 0, soll der PB4 high 
gesetzt werden.
Dazu verzweige ich zu setHigh und springe danach wieder zurück (inLoop)
1
inLoop:  in r17, PINB  ; load i/o
2
  andi r17, 0x0F  ; delete high nibble (bit 7-4)
3
   cpi r17, 0x01  ; compare with one 
4
   breq one  ; jump if one (to 'one')
5
   cpi r17, 0x02  ; compare with two
6
   breq two  ; jump if two (to 'two')
7
   cpi r17, 0x03  ; compare with three
8
   breq three  ; jump if three (to 'three')
9
  
10
    ldi r20, 0xFF  ; set output high next time
11
    rjmp loop  ; jump back to the beginning

Hier lade ich PINB und eleminiere die oberen 4 Bit mit 'andi r17, 0x0F'. 
Somit bleibt jetzt eine Zahl zwischen 0 und 31 über, die den jeweiligen 
Modus repräsentiert.
Mit den 3 Blöcken (cpi ... breq ...) frage ich die Modi 1-3 ab und 
springe ggf. Bei diesen 3 Blöcken vermute ich das Problem, vllt 
beeinflussen die Flags, die beim vorhergehenden cpi gesetzt/gelöscht 
wurden die danach kommenden cpi-breq Blöcke ja auch noch.
1
one:  cbi PORTB, 5  ; set output to low
2
  ldi r19, 0x05  ; 5 times nop     (30 cyles)
3
  ldi r20, 0xFF  ; set high after nop
4
  rjmp doNop  ; jump to nopRoutine

Hier lösche ich erst den Output, lege dann in r19 die Anzahl der NOP 
fest, die bis zum zurücksetzen auf high gewartet wird, setze r20 auf 
0xFF damit (dar größer 0) im kommenden Durchlauf von loop der Pin wieder 
high gesetzt wird, und springe dann zum Unterpunkt, in dem die NOPs 
ausgeführt werden. Jedes Mal durchlaufen dauert 6 Taktzyklen.
two ist das selbe, nur mit der doppelten Anzahl NOP-Durchläufe
1
three:  cbi PORTB, 5  ; set low
2
  ldi r20, 0x00  ; DO NOT set output high in loop
3
  rjmp loop  ; jump to the beginning

Hier schalte ich die LED aus, und bestimme in r20, dass sie ausbleiben 
soll. Dann springe ich gleich zurück. setHigh wird jetzt übersprungen 
(da r20 equal 0)
1
doNop:  cpi r19, 0x00  ; compare with 0  (1 cycle)
2
  breq loop  ; jump back if 0  (1 cycle)
3
  nop    ;      (1 cycle)
4
  dec r19    ; r19 minus 1    (1 cycle)
5
  rjmp doNop  ; and over    (2 cycles)
6
      ;    Sum:   6 cycles
Hier wird in einer Schleife die Anzahl Durchläufe gewartet bis zu loop 
zurückgesprungen (und PB4 high gesetzt) wird, die in r19 definiert 
wurden.
Ist eigentlich selbsterklärend.

LG

von spess53 (Gast)


Lesenswert?

Hi

>setHigh:            sbi PORTB, 5  ; set output to high

>one:                cbi PORTB, 5  ; set output to low
....

Gibt es nur, wenn du das Resetpin disabled hast.

>Hier lade ich PINB und eleminiere die oberen 4 Bit mit 'andi r17, 0x0F'.
>Somit bleibt jetzt eine Zahl zwischen 0 und 31 über, die den jeweiligen
>Modus repräsentiert.

Nein. 0...15.

MfG Spess

von J. W. (jw-lighting)


Lesenswert?

Danke, das ich das nochmal erklären sollte.
1
setHigh: sbi PORTB, 4  ; set output to high

funktioniert für PB4 wesentlich besser, als
1
setHigh: sbi PORTB, 5  ; set output to high


Jedoch habe ich bei nur 1 NOP-Durchlauf im Mittel nur 0.6V am Output. 
Wie bekomme ich die Spannung höher (den Code kürzer)?

spess53 schrieb:
> Gibt es nur, wenn du das Resetpin disabled hast.

Habe ich gerade schon selbst gemerkt.

spess53 schrieb:
> Nein. 0...15

Hast du natürlich recht. 0-31 wäre es bei 5-Bit ;)

von spess53 (Gast)


Lesenswert?

Hi

Wie hast du deine Led angeschlossen? Wenn ich im Simulator die H- und 
L-Zeiten vom PB4 ansehe könnten, gefühlt, deine 0,6V rauskommen.

MfG Spess

von jw-lighting (Gast)


Lesenswert?

Ich mache euch einen Schaltplan.
Es sind 2 Transistoren BC547B oder BC547C in Darlington-Schaltung vor 
der LED.
Eine LED an einem ULN2803A leuchtet übrigens ;)

von J. W. (jw-lighting)


Angehängte Dateien:

Lesenswert?

So, ich habe es gemeistert

Nachdem die 0,6V gestern zu wenig waren, leuchtet meine weiße (!) LED 
heute schon bei 0,01V :|

(Ja, ich habe mit 2 Multimetern nachgemessen, an der LED liegen 0,01V, 
und sie glimmt)

Im Anhang Schaltplan und Code.

Ich habe statt high setzen, das low setzen in die loop Routine (hätte 
ich main nennen sollen) geschrieben.
Dann habe ich eine zusätzliche Wartezeit für den low-Zustand eingebaut.
Ich kann nun beide Parameter (low und high Time) bestimmen.
Den Strobe habe ich mit dem Timer realisiert bekommen.

Und jetzt freue ich mich über Kommentare, Verbesserungsvorschläge und 
Rückfragen ;)

LG:
jan

von spess53 (Gast)


Lesenswert?

Hi

Ein BC547 ist eigentlich in der Lage eine Led anzusteuern. Weshalb du 
eine Darlington-Schaltung mit Led von Emitter nach Masse benutzt kann 
ich nicht nachvollziehen. Die einfache Schaltung sieht so aus:

GND-Emitter
µC-Basiswiderstand-Basis
VCC-Vorwiderstand-LED-Kollektor oder VCC-LED-Vorwiderstand-Kollektor

MfG Spess

von J. W. (jw-lighting)


Angehängte Dateien:

Lesenswert?

Da hast du recht!
ich hatte das während der Entwicklungszeit so aufgebaut, um ein 
möglichst vergleichbares Bild mit den LEDs auf dem Addon-Board von 
pollin zu bekommen. Die LEDs dort werden über einen ULN2803A 
angesteuert, welcher auch eine Darlingtonschaltung beinhaltet.
Nur ging es in diesem Fall um eine weiße LED.
Das Ganze ist dann als "Altlast" auf'm Steckboard geblieben, und ich 
habe den Schaltplan von dort abgeguckt.

Mittlerweile habe ich auch einen 3W-LED Driver dazu entworfen. Zusammen 
mit dem Strobeeffekt eine schöne Sache :p
Den erneuerten Schaltplan habe ich wieder angehängt.


Bei der Software denke ich gerade darüber nach, wie man manche Sachen 
verbessert programmieren kann:

Ich kann bspw. den Strobemodus nicht mit unterschiedlichen Helligkeiten 
kombinieren, und ein Strobezyklus (an...aus) muss erst zu Ende 
durchlaufen werden, bis der Modus gewechselt wird, auch wenn die 
Einstellungen früher vorgenommen werden.
Jemand einen Ansatz, wie ich das umschreiben kann?

Desweiteren erarbeite ich gerade eine RGB-Version
(PB4-2: RGB, PB1: Programm (oder besser Tempo??), PB0: Hold/Run)

LG:
jan

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.