Navigation |
LEDs blinken lassen:
Nachdem wir uns jetzt den grundsätzlichen Aufbau angeschaut haben, wollen wir doch mal mit einer ganz trivialen Aufgabe anfangen: 3 LEDs mit 3 Tastern an- und ausschalten. Der Sourcecode dazu ist noch ziemlich kurz und lautet wie folgt: Man sieht, dass zuerst eine Headerdatei msp430x14x.h eingebunden wird. In dieser Datei stehen fast alle symbolischen Bezeichner für die zahlreichen Register und Ports des MSP430. So hat man später z.B. durch ein einfaches P1OUT Zugriff auf das Ausgaberegister von Port 1, ohne dass man sich umständlich sämtliche Adressen merken muss. Als nächstes beginnt die Haupt-Routine main(), in der als erstes der Watchdog ausgeschaltet wird. Das geschieht über die Zuweisung eines Passwortes WDTPW und des Befehls zum Abschalten WDTHOLD an das Watchdog-Register WDTCTL. Nun müssen wir erst einmal die verwendeten Ports konfigurieren. Wie schon erwähnt, besitzt der MSP430F149 48 I/O-Leitungen, die in Form von 6 Ports à 8 Bit organisiert sind. Wie man dem Quelltext entnehmen kann, benutze ich Port 1 wegen der hieran angeschlossenen LEDs als Output, und zwar sicherheitshalber direkt alle 8 Bit (daher 0xFF, andere Wünsche (z.B. Port 1.1, 1.2 und 1.5 Output, der Rest Input) erfordern natürlich andere Bitmuster). Hierbei steht eine logische "1" für Output, eine logische "0" für Input. Port 6 wird daher als Input benutzt, weil hieran die Taster angeschlossen sind. Über die nächsten beiden Zuweisungen wird entschieden, dass Port 1 und 6 als "normale" I/O-Ports benutzt werden, und nicht als Timer oder A/D-Wandler (hierzu später noch mehr). Nachdem die Interrupt-Funktionalität von Port 1 ausgeschaltet wurde (auch das wird später noch näher erläutert), sehen wir die erste Anweisung, die etwas Sichtbares bewirkt: P1OUT=0x00; sorgt dafür, dass initial (also direkt nach dem Einschalten des Mikrocontrollers) alle LEDs aus sind. Man sieht also, dass Ausgabe-Routinen denkbar einfach sind: Man muss lediglich das gewünschte Datenwort (z.B. 0x00, 0xFF, 0x3B oder was auch immer) an den gewünschten Ausgabeport schreiben, und mit der nächsten Taktflanke wird das Signal automatisch als elektrische Spannung an den Port angelegt. Da ich den MSP430 mit einem LM317 auf VCC = 3,3 Volt Versorgungsspannung betreibe, würde bei mir eine logische "1" an einem Ausgabeport eine Spannung von genau diesen 3,3 Volt zur Folge haben; eine logische "0" zieht den Port hingegen auf GND. Das eigentliche Programm läuft nun in einer Endlosschleife ab. Es prüft immer wieder, ob ein Taster gedrückt ist, indem es über eine geschickte UND-Verknüpfung das zugehörige IN-Register von Port 6 abfragt (P6IN & 0x40 maskiert z.B. das dritte Bit von Port 6 heraus -- hier ist der dritte Schalter angeschlossen). Falls ein Taster gedrückt ist, wird die zugehörige LED an Port 1 angeschaltet. Hierzu muss man wissen, dass Eingabe-Routinen genauso einfach realisiert werden wie Ausgabe-Operationen: Liegt an einem Port GND an, so ist das zugehörige Register 0, liegt VCC an, ist es 1. Ich habe meine Schalter als Pull-Ups konfiguriert, d.h., sie liegen über einen 47k-Widerstand an VCC. Somit liegt VCC an den Ports an, wenn ich Schalter nicht drücke, und GND, wenn ich die Schalter drücke. Es ist aber natürlich auch ein Anschluss als Pull-Down möglich, wenn die IF-Bedingungen entsprechend angepasst werden. Als letztes im Programm prüfe ich, ob alle Taster nicht gedrückt sind, indem ich abfrage, ob alle betroffenen Register logisch 1 sind. Falls dem so ist, werden alle LEDs wieder gelöscht und die Schleife beginnt von vorne. Diesem ziemlich einfachen Beispiel folgt auf der nächsten Seite schon ein deutlich schwierigeres, nämlich die Ansteuerung eines LCD-Displays. |