![]() |
![]() |
![]() |
Navigation |
Eine Dimmerschaltung:
Den Sourcecode zum Dimmer-Projekt gibt es hier. Die neue Library lcd_dco.c, die ihr benötigt, findet ihr hier. Dabei gilt es prinzipiell zu beachten, dass ich meinen gesamten Code (und insbesondere die Funktion wait_precise(), die für den Zündzeitpunkt zuständig ist) auf den internen DCO mit 800kHz ausgelegt habe. Insofern sollte eigentlich jeder meinen Code benutzen können, denn der intere DCO ist ja bei jedem MSP430 gleich. Wenn ihr aber doch einen anderen Takt benutzen wollt, müsst ihr (am besten mit einem Oszilloskop) die wait_precise()-Funktion anpassen, damit der Zündzeitpunkt des Triacs wieder stimmt! Nun, kommen wir zum Code: Nach den üblichen Includes und Prototypen- sowie einigen Variablen-Definitionen sehen wir die erste Neuigkeit schon in Zeile 19. Die Anweisung P1DIR=0xEF; definiert Port 1 nun nämlich anders als bisher, und zwar so, dass an Pin 16 das RECT-OUT-Signal von der Nulldurchgangserkennung passend ausgewertet werden kann. Eine weitere Neuigkeit in Zeile 22: Pin 49 (entspricht P5.5) wird nun auch noch als Output benötigt, da dort die eben erwähnte Optokoppler/Triac-Schaltung (über MSP-IN) angeschlossen wird. In den Zeilen 33 bis 35 wird die Interrupt-Fähigkeit von Pin 16 eingeschaltet. Nun wird jedesmal, wenn an Pin 16 eine steigende Flanke entdeckt wird, der Interrupt-Handler (ab Zeile 107) aufgerufen. Die Zeilen 37 bis 50 sollten selbsterklärend bzw. aus den vorigen Tutorials bekannt sein. Die eigentliche Hauptroutine ruft in einer Endlosschleife doSomeStuff() auf. In dieser Funktion wiederum wird als erstes die aktuelle Helligkeit auf dem angeschlossenen LCD ausgegeben, wobei man wissen sollte, dass 0 ganz an und 33 ganz aus ist. Anschließend (in den Zeilen 86 bis 89) wird abhängig davon, welche der 4 Tasten gedrückt wurde, eine Routine fadeIn(a, b); oder fadeOut(a, b); aufgerufen. Wie der Name schon vermuten lässt, faden (d.h. blenden) diese meinen angeschlossenen 150W-Baumarktstrahler mehr oder weniger schnell auf eine bestimmte Helligkeit. Im Sourcecode von fadeIn() und fadeOut() wird im Prinzip nur die Variable brightness_global verändert -- nach oben oder nach unten, mit variabler Geschwindigkeit über wait(delay); verzögert. Das elegante an der Interrupt-Geschichte ist nun, dass der Interrupt-Handler völlig unabhängig vom Hauptprogramm garantiert 50 mal pro Sekunde aufgerufen wird, denn genau so viele steigende Flanken hat ja mein erzeugtes Rechtecksignal. Im Interrupt-Handler geschieht dann schließlich das Zünden des Triacs: Hierzu wird in Zeile 110 zuerst noch einmal sicherheitshalber geprüft, ob der erzeugte Interrupt auch wirklich von Pin 16 (also der Nulldurchgangserkennung) kam. Ist dies der Fall, wird eine gewisse Zeit x gewartet, und zwar mittels einer präziseren Wartefunktion. Die früher von mir geschriebene wait(x); wartet nämlich nur x Millisekunden, was zur genauen Einstellung des Zündzeitpunktes nicht genügend ist! In Zeile 113 wird der Triac schließlich gezündet -- jedoch nur, wenn er nicht vollständig aus sein soll, denn dann können wir uns das Zünden ja komplett sparen! Zum Zünden wird P5.5 (also Pin 49, der MSP-IN-Pin) für 1ms auf high und kurz danach wieder auf low gelegt. Alles weitere geschieht nun wie auf der letzten Seite besprochen: Der MOC3023 zündet, leitet auf seiner Sekundärseite durch, dadurch zündet sich der TIC216 quasi über die Netzspannung selber und letztlich liegt der mehr oder weniger abgeschnittene "grüne" Anteil der Sinusspannung an der Lampe an. Somit sind meine Routinen insgesamt denke ich recht elegant geworden, denn über ein einfaches Anpassen der Variablen brightness_global kann man nun die angeschlossene Lampe dimmen. Dadurch, dass der Interrupt-Handler völlig unabhängig vom Rest des Programmes 50 mal pro Sekunde den Triac mit der Verzögerung brightness_global zündet, hat man im Hauptprogramm beliebige Freiheiten. Ich habe z.B. testweise mal ein Poti über den A/D-Wandler ausgelesen und den A/D-gewandelten Wert (im Wertebereich leicht angepasst) in brightness_global geschrieben. So kann man dann wie gewohnt durch Drehen an einem Knopf die Helligkeit einer Lampe einstellen. Nur eben etwas high-technischer ... ;-) Schließlich sind auch andere Anwendungen wie eine Zeitschaltuhr oder eine Lichtorgel kein Problem mehr. Eine Zeitschaltuhr bestünde im Prinzip nur aus einem Timer, der mehr oder weniger hoch zählt (eine Stunde, fünf Stunden, einen Tag o.ä.) und nach Ablauf der Zeit dann brightness_global auf 0 oder 33 setzt. Eurer Fantasie seien hier keine Grenzen gesetzt. :-) Eine Lichtorgel ist auch nicht viel schwerer: Die Audio-Stufe haben wir ja schon im Disco-Kapitel kennen gelernt; lediglich eine Anpassung der Helligkeitswerte an den Halogenstrahler wäre wohl nötig. Falls einer von euch noch ein paar interessante Sourcecodes hat (musikgetaktetes Lauflicht o.ä.) -- ich bin immer dankbar für neue Ideen! |