Hallo, ich benutze den MSP430F2013 und möchte damit per SPI mit einigen Peripherie-Bauteilen kommunizieren (u.a. AD-Wandler). Die per SPI eingelesenen Daten möchte ich per UART über das UART-USB-Konverter-Modul UM232R (mit dem Chip FT232R) von FTDI an einen PC schicken. Das Skript im Anhang (aus http://www.ti.com/litv/zip/slac080a) habe ich bereits zum Laufen gebracht. Mit der Software Docklight kann ich somit einen Buchstaben per USB-Kabel über das FTDI-Modul an den MSP senden. Der MSP schickt dann den gleichen Buchstaben zurück an Docklight. Das Skript von TI, das ich benütze, benötigt für diese UART-Kommunikation die Ports P1.1 und P1.5. Für SPI benötige ich laut Datenblatt des MSP die Ports P1.5 (Clock), P1.6 (SDO), P1.7 (SDI) und einen beliebigen Pin, z.B. P1.0 (CS). Also wird der P1.5 für UART und für SPI benötigt. UART wird in diesem Skript über den Timer_A realisiert. Mit diesem Timer kenn ich mich nicht richtig aus. Kennt jemand eine Möglichkeit, statt dem P1.5 einen anderen Pin zu verwenden oder ist das wegen dem Timer nicht möglich? Natürlich wäre es möglich zwei beliebige Pins für die UART-Kommunikation zu verwenden und diese per Bit-Banging zu betreiben. Dann geht aber so weit ich weiß der Low-Power-Mode nicht mehr und der Eingangs-Port muss dauernd abgefragt werden, oder? Oder ist es möglich, den Pin zuerst für SPI zu konfigurieren, ihn dann auf UART umzustellen, die Daten per UART zu senden und dann wieder auf SPI umstellen? Zum angehängten Skript habe ich noch eine weitere Frage: Mir ist nicht klar, wo in dem Skript der Befehl fürs Empfangen des Buchstabens steht und welcher Befehl für das Senden zuständig ist. Ich möchte nämlich gerne nur einen Buchstaben vom MSP aussenden oder einen Buchstaben nur einlesen, und kein Echo auf einen eingehenden Buchstaben schicken. Kennt jemand die einzelnen Befehle für das Senden und Empfangen eines Buchstabens? Über Antworten zu meinen Fragen würde ich mich sehr freuen. Gruß, Martin
Das einbinden des Anhangs hat vorher nicht funktioniert. Jetzt probiere ich das noch einmal...
Was Du da "Skript" nennst, ist C-Sourcecode für eine Software-UART. Wenn ich das richtig verstehe, musst Du nur die #defines RXD und TXD ändern, und Du kannst andere Port-Bits von Port1 verwenden. Die Funktion TX_Byte sendet das in der globalen Variable RXTXData gespeicherte Byte. Dieselbe Variable wird auch verwendet, um Zeichen zu empfangen; der Empfang geschieht interruptgesteuert im Interrupthandler für Timer_A. Vermutlich lässt sich diese Doppelbelegung auch vermeiden.
Vielen Dank für Deine Antwort! Rufus t. Firefly wrote: > die #defines RXD und TXD ändern, > und Du kannst andere Port-Bits von Port1 verwenden. Ich hab mal eben den TXD-Pin auf P1.4 geändert: #define TXD 0x10 und entsprechend meine Schaltung umgebaut. Das Programm lässt sich compilieren und auf den MSP überspielen, das Echo funktioniert aber leider nicht mehr :( Dann gehts anscheinend auf diese Art und Weise nicht.
Du kannst keine anderen Pins bei diesem Beispiel verwenden, das Ganze basiert auf Timerfunktionen zu denen korrespondierende Pins gehören. Der F2013 besitzt keine echte UART, dass ist also schon ein BITBANGING. Allerdings kannst du leicht deine SPI in SW mit beliebigen PINS lösen.
Der 2013 hat doch 2 Capture Compare Einheiten. So wie es aussieht wird doch die "0" Einheit im Beispiel benutzt. Könnte man das nicht auf die "1" Einheit umbiegen?
Moin moin, versuch doch mal statt der "Timer A Capture/Compare 0" den "Timer A Capture/Compare 1" zu benutzen. Da liegt der Ausgang auf Port 2.6. Eingangsseitig hängt der an Port 1.2. Viel Glück. Und wech...
Finds echt super, dass mir hier so viele helfen :-) Danke für den Tipp, den Capture/Compare 1 mal zu testen. Dafür gibts laut Datenblatt den Eingang P1.2 (CCI1A) und den Ausgang P1.6 (CCI1B) und auch noch den Ausgang P2.6 (GND). Weil an P2.6 ein Quarz angeschlossen ist (wird bei diesem UART-Beispiel-Programm gebraucht), habe ich mal P1.2 und P1.6 verwendet, meine Schaltung umgebaut und folgendermaßen das Programm geändert:
1 | #define RXD 0x04 // RXD on P1.2
|
2 | #define TXD 0x40 // TXD on P1.6
|
Die Timerfunktionen habe ich wie folgt ersetzt: CCR0 -> CCR1 CCTL0 -> CCTL1 CCIS0 -> CCIS1 TIMERA0_VECTOR -> TIMERA1_VECTOR Sonst habe ich nichts am Programm verändert. Leider funktionierts so nicht. Habe ich evtl. noch vergessen, eine Funktion zu ändern oder hab ich zuviel geändert? Falls UART mit P1.2 und P1.6 funktionieren würde, hätte ich immer noch das Problem eines Pin-Konflikts. Falls ich aber P2.6 statt P1.6 verwenden kann und den Quarz einsparen kann, würds passen. Jetzt probiere ich mal, statt dem externen Uhrenquarz die interne Quarzfunktion des MSP430F2013 zu verwenden. Weiß vielleicht jemand, wie man das umstellen kann? Falls das alles nichts hilft, werde ich mal eine Software-SPI probieren. Kennt ihr zufällig eine entsprechende Bibliothek?
Den Interruptvektor solltest Du nicht ändern. Timer_A hat mehrere Capture-/Compare-Units, die alle auf denselben Interruptvektor laufen.
Du musst natürlich ein paar andere Anpassungen auch machen. Der Vector stimmt so, TIMERRA0 ist NUR für CCR0, TIMERA1 ist für CCR1 und 2, falls vorhanden. Schau mal im Datenblatt, ob an CCR1 auch die Register genauso belegt sind. Die RX und TX defines sind nur für´s Umschalten der Port-Richtung und Zweitfunktion. Ich hatte bei mir auch mal versucht, den CCR1 zum Capturen eines externen Signals zu verwenden (MSP430F1611), aber das hab ich nicht hinbekommen. Weiß nicht, ob das ein Bug ist? Poste doch mal den geänderten Quellcode.
Oh, sorry für all meine Irrtümer; ist schon ein paar Tage her, daß ich mich mit dem Timer_A beschäftigt habe, und schon damals habe ich mir irgendwas verknotet - und in meiner Routine nur CCR1 und CCR2 verwendet. Grr.
Im Anhang ist der geänderte Quellcode. Geändert ist nur das, was ich vorher beschrieben habe. Leider habe ich noch nicht herausgefunden, welcher Befehl aus der Funktion TX_Byte verantwortlich dafür ist, den Buchstaben aus der Variable RXTXData wegzuschicken. Mein Ziel wäre nämlich, vorerst nur mal Daten per UART zu senden und nicht wie hier in dem Beispiel ein echo zu senden. Ich hab auch schon versucht, in der for-Schleife der main-Funktion das RX_Ready und _BIS_SR... auszukommentieren und manuell ein RXTXData='b' zu definieren, um das b zu senden. Das geht aber leider nicht. Was allerdings geht, ist, wenn ich am Ende dieser for-Schleife
1 | RXTXData='b'; |
2 | TX_Byte(); |
einfüge. Dann sendet das Programm das Echo und hängt noch ein b dran... Muss jetzt weg für heute. Morgen werd ich wieder weitertüfteln... Gruß Martin
> Leider habe ich noch nicht herausgefunden, welcher > Befehl aus der Funktion TX_Byte verantwortlich dafür ist, > den Buchstaben aus der Variable RXTXData wegzuschicken. Das geschieht im Interrupthandler, wenn der Ausdruck (CCTL0 & CCIS0) wahr ist. (in Deinem nicht angehängten Code sollte statt CCTL0 CCTL1 und statt CCIS0 CCIS1 stehen)
Ups, sorry. Hier ist nun der geänderte Code...
Du solltest in der TimerA1 ISR unbedingt abfragen, ob das TAIV Register den Wert 2 hat. Und wenn du senden willst, musst du trotzdem vorher das RX_Ready() aufrufen. Und den Globalen Interrupt freigeben. Also _EINT(); RX_Ready(); TX_Byte();
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.