Navigation
Benutzung des USART:

Wie schon erwähnt, findet die Kommunikation zwischen MSP430 und einem PC nach dem UART-Prinzip (also asynchron) statt. Wir wollen hier nun mit einer ganz kleinen Applikation anfangen, nämlich einem Programm, das den per PC-Tastaur eingetippten Buchstaben zurückgibt (ECHO). Das komplette Programm öffnet sich wieder mal hier in einem neuen Fenster.

Doch bevor wir den Sourcecode behandeln, schauen wir uns zuerst den USART noch mal ein bisschen genauer an:


Dieses Diagramm ist der Application Note zum USART entnommen. Bei weitergehendem Interesse am USART kann ich euch nur empfehlen, die Application Note mal komplett durchzulesen, auch wenn sie weit über das hier behandelte "Progämmchen" hinausgeht. Und keine Sorge, ihr müsst das Blockschaltbild jetzt nicht auf Anhieb verstehen ... :-)

Das einzige, was zum jetzigen Zeitpunkt für unser Verständnis wichtig ist, sind die URXD- und UTXD-Leitungen rechts und die Receive und Transmit Buffer URXBUF und UTXBUF in der Mitte. Über URXD kommen Signale vom PC am MSP430 an und werden anschließend über irgend welche Mechanismen (die uns im Moment noch nicht näher interessieren) in einem speziellen Buffer namens URXBUF gespeichert, von wo aus sie ganz einfach weiter verarbeitet werden können. Genauso simpel ist es im Prinzip, Daten vom MSP430 zum PC zu senden. Hierzu muss das zu sendende Zeichen lediglich in den UTXBUF geschrieben werden. Alles weitere (Verarbeitung in Schieberegistern, Anlegen des Signals an die Sendeleitung UTXD usw.) geschieht vollautomatisch -- der User muss sich fast keinerlei Gedanken mehr machen.

Für eine funktionierende serielle Verbindung müssen nun zuerst einige Parameter vereinbart werden, wie z.B. die verwendete Baudrate, das verwendete Verfahren zur Fehlerkorrektur usw. Solche Einstellungen werden beim USART über sechs verschiedene Register vorgenommen. Diese sechs Register habe ich mal für den ersten USART (USART0) zuzüglich des Receive- und Transmit-Registers in eine Tabelle gepackt:

Name beim USART0Bedeutung
UCTL0USART Control Register
UTCTL0Transmit Control Register
URCTL0Receive Control Register
UMCTL0Modulation Control Register
UBR00Baud-Rate Register 0
UBR10Baud-Rate Register 1
RXBUF0Receive Register
TXBUF0Transmit Register

Beim zweiten USART (USART1) sind die Namen der Register fast identisch, lediglich die 0 am Ende ist jeweils durch eine 1 zu ersetzen. Die einzelnen Register sind in der folgenden Abbildung noch einmal detailliert gezeigt:


Ich kann jetzt leider schlecht jedes Bit einzeln erläutern, denn dann wäre das Tutorial 20 Seiten lang. ;-) Also empfehle ich dringend den Blick in das Datenblatt des MSP430 oder der oben verlinkten Application Note. In diesem Tutorial werde ich mich nur auf die Erklärung der für unser Programm notwendigen Einstellungen beschränken.

So, genug der grauen Theorie, jetzt wollen wir uns endlich mal dem Programm widmen: Wir sehen, dass als erstes zwei Strings (streng genommen natürlich Arrays of char) deklariert werden. Diese brauchen wir später für eine hübsche Ausgabe. Im Hauptprogramm wird nach dem üblichen Ausschalten des Watchdogs die Portkonfiguration vorgenommen. Wie bereits erwähnt, liegen TxD und RxD des USART0 auf Port P3.4 und P3.5, d.h. an den Pins 32 und 33. Da ja fast alle Pins funktional doppelbelegt sind, müssen wir dem Compiler über P3SEL=0x30; mitteilen, dass wir P3.4 und P3.5 als USART (und nicht als GPIO) benutzen wollen.

Die nächste Zeile schaltet das Sende- und Empfangsmodul erst mal ein. Ähnlich wie beim A/D-Wandler kann man den USART nämlich komplett ausschalten, um Strom zu sparen. Anschließend folgt die Definition des verwendeten Datenformates. Wir sehen, dass hier nur CHAR gesetzt ist, was für 8 Datenbits steht. Wäre CHAR nicht gesetzt, würden 7 Datenbits verwendet. Die Parität und das Stoppbit werden über das nicht gesetzte SP und PENA definiert. Ferner ist SYNC nicht gesetzt, was bewirkt, dass der UART-Mode benutzt wird. Wäre SYNC gesetzt, würde der (synchrone) SPI-Modus verwendet. Zum ebenfalls nicht gesetzten SWRST muss erwähnt werden, dass dieses Bit -- wie man der obigen Abbildung der Register auch entnehmen kann -- als einziges USART-Bit mit einem POR (Power-On-Reset) gesetzt und nicht gelöscht wird. Zum Zeitpunkt der Ausführung dieser Codezeile ist SWRST also schon gesetzt. Dies hält den USART in einem Reset-Status und gibt ihn noch nicht zur Funktion frei. Sämtliche Einstellungen, die gerade vorgenommen werden, können nämlich nur bei gesetztem SWRST vorgenommen werden.

Die nächste Anweisung (UTCTL0 |= SSEL0;) legt fest, welche Clock zur Baudratengenerierung benutzt wird. Möglich sind hier ACLK, MCLK sowie eine externe Clock an Pin 31. SSEL0 (was binär 01 entspricht) legt die ACLK als Clock-Source fest.

Da wir eine Übertragung mit 9600 bit/s realisieren wollen, müssen wir mit den nächsten beiden Zeilen einen passenden Teiler festlegen, der 9600 Hz aus 32.768 kHz erzeugt. Da das Ergebnis dieser Division ganz offenbar nicht ganzzahlig ist, wird über ein mehr oder weniger kompliziertes Verfahren eine Korrektur der Division vorgenommen. Dies sorgt dafür, dass sich die Baudraten präziser an ihren Sollwerten befinden und keine Synchronisationsfehler auftreten. Die genaue Funktionsweise ist auf Seite 6 ff. der Application Note erläutert, die hier verwendeten Zahlenwerte ergeben sich direkt aus Tabelle 2 auf Seite 10.

OK, das war's! Alle nötigen Einstellungen sind vorgenommen und es kann losgehen. Das löschen von SWRST gibt den USART frei zum Senden und Empfangen. Die nächste Zeile schaltet die RX- und TX-Interrupts ein. "Warum so kompliziert?" werdet ihr jetzt fragen ... Naja, erstens, weil wir ja immer wieder was neues lernen möchten, und zweitens, weil das Senden und Empfangen über den USART mit Benutzung von Interrupts in Wahrheit deutlich einfacher ist als ohne. Wie das genau funktioniert, werden wir gleich sehen. Nun wird noch ein mit dem POR gesetztes Interrupt-Bit gelöscht, um nicht direkt den Interrupt-Handle auszulösen, bevor es ab in den Low Power Mode 3 geht. Ohne zu sehr in die Details zu gehen: Dieser Modus ist ziemlich stromsparend, da viele Teile des MSP430 ausgeschaltet sind. Nur der USART bleibt wach und löst einen Interrupt aus, wenn er Daten sendet oder empfängt.

Auf die Interrupt-Handler möchte ich jetzt nicht mehr allzu detailliert eingehen, damit ihr auch selber noch was zu rätseln habt. :-) Kleiner Tipp nur: Jedes Senden eines einzigen Zeichens löst (wieder) einen Sende-Interrupt aus, und jedes Empfangen eines Zeichens löst einen Empfangs-Interrupt aus (die natürlich beide ihre jeweiligen Handler aufrufen).

Und wenn ihr alles richtig gemacht habt und den MSP430 über ein serielles Kabel an den PC anschließt, sollte das ganze im Terminalprogramm eures Vertrauens (Hyperterminal, ZOC o.ä.) in etwa so aussehen: