Moin ! Hat jemand von euch schon mal probiert die serielle schnittstelle zu nutzen?! ich habe folgendes vor: ich habe den TI (MSP430F437IPZ) bereits auf ein geeignetes boartd geloetet und den recieve und transmit pin mit einem geeigneten chip versehen, der das ausgegebene signal fuer den PC erkennbar und lesbar macht. hiernach habe ich mich an den code programmiert. danach habe ich hyperterminal entsprechend initialisiert. es passiert aber rein gar nichts. manchmal bekomme ich ein zufaelliges zeichen im hyperterminal ausgegeben wenn ich den TI hochfahre, was heisst dass da irgendwas kommuniziert. mein code sieht wie folgt aus: #include <msp430x43x.h> #include <stdio.h> int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P2DIR |= 0x0A; //P2.3 & P2.1 = outputs P2SEL |= 0x30; //UTXD0 and URXD0 = activated U0CTL = 0xF1; //even parity; 2 stop bits; 8-bit data; LISTEN=disabled; //UART mode; Idle-line MP protocol; SWRST=enabled, //while configuring other regs U0TCTL = 0x18; // UCLKI=UCLK; ACLK; UART receive start-edge feature; data U0RCTL = 0x00; ME1 = 0xC0; //USART0 transmit and receive = enabled IE1 = 0x40; //USART0 receive interrupt enabled UTCTL0 = SSEL0; // UCLK = ACLK UBR00 = 0x03; // 32k/9600 UBR10 = 0x00; // UMCTL0 = 0x4a; // P2OUT = 0x02; U0TXBUF = 0x4A; }// main // USART 0 Receive interrupt service routine #pragma vector=USART0RX_VECTOR __interrupt void USART0RX (void) { char temp; temp=U0RXBUF; P2OUT = 0x08; } vielleicht ist es ja n ganz dummer fehler. vielen dank fuer eure hilfe ! gruss johannes
Hallo, der MSP430 verlangt, dass man die im Datenblatt angegebene Reihenfolge der Registerkonfiguration genau einhält, ansonsten verhält sich die USART irgendwie, nur nicht so, wie man sie braucht (hab ich selbst schon mehrfach erlebt ...). Ansonsten ist es wichtig, während der Konfiguration den Software-Reset reinzuhauen. Das hast du zwar gemacht, aber ich seh grad nicht, wo du den auch wieder aufhebst ?!? Hier mal meine (funktionierende) Konfiguration für 38400 Baud (8N1) aus einem 4MHz-Takt. UCTL1 |= SWRST; // Software-Reset aktivieren UCTL1 |= CHAR; // 8N1 UTCTL1 |= SSEL0; // ACLK als Taktquelle UBR01 = 0x68; // 38400 Baud UBR11 = 0x00; UMCTL1 = 0x20; ME2 |= UTXE1 + URXE1; // Module einschalten (TX, RX) UCTL1 &= ~SWRST; // Software-Reset wieder raus IE2 |= URXIE1; // Interrupt Enable Hoffe das hilft weiter, Grüße, Mario
hallo! ich sehe in deinem Code keine Initialisierung des Clock Systems. Das angeschlossene 32kHz Quarz wird nämlich nicht automatisch als Clock Source verwendet, sondern der interne Oszillator, welcher ca. 800kHz hat. mfg, thomas
Danke danke fuer die schnelle hilfe !!! ich hab hier grad n bisschen thermik - ich klemm mich da morgen frueh mal hinter ! bis die tage johannes
Du sendest auch nur genau ein Zeichen! U0TXBUF wird nur in Main beschrieben, aber nicht mehr in irgendwelchen IRQs. Da kannst du nur 1 Zeichen beim Reset bekommen. Außerdem würd ich dir raten das Datenblatt genau zu lesen und nicht irgendwelche 0x?? werte zuzuweisen, sondern die bitnamen zu verwenden. Ich hab echt keine Lust die Bits zu überprüfen ob du dich da nicht irgendwo vertan hast. Hatte grade selber lang genug mit nem UART-Problem zu kämpfen. Erkenntnis: SMCLK ist nicht gleichwertig mit MCLK. Das gilt nur, solange man den DCO benutzt. Einen Quarz muss man für SMCLK nochmal getrennt von MCLK aktivieren.
Hallo R2D2, bei den MSP430s (blöder Plural !) gibt es insgesamt drei Takte: ACLK (Auxiliary CLocK), MCLK (Main CLocK) und SMCLK (Sub Main CLocK), die jeweils eigenständig arbeiten. Daneben gibt es drei (bei kleineren Derivaten manchmal auch nur zwei) Taktquellen, das sind LFXT1 (1. Quarzoszillator, auch für Uhrenquarze), XT2 (2. Quarzoszillator) und DCOCLK (der interne Oszillator, der nach einem Reset standardmäßig aktiviert ist und mit etwa 800kHz schwingt). Je nach gewünschter Konfiguration kann man jetzt diese Taktquellen (mit oder ohne Vorteiler) an die jeweiligen Takte anlegen, und auch die Peripheriemodule (USART, ADC etc.) bieten die Möglichkeit, den jeweils gewünschten Takt auszuwählen. Ist etwas undurchsichtig am Anfang, ich hab mich da auch erst durchfummeln müssen. Wenn man's mal raus hat, ist es aber eigentlich gar nicht so schlimm :-) Grüße, Mario
Danke für deine Information. Mir war das schon klar mit den verschiedenen Taktquelle. Ich hab nur bis jetzt eigentlich immer den DCO oder einen 32kHz-Quarz(ACLK) verwendet. Allerdings hatte ich noch fast nie den UART benutzt (waren alles Anwendungen die unabhängig vom PC arbeiten sollen und für's Debuggen halt der JTAG). Da SMCLK bei DCO-Benutzung standardmäßig == MCLK ist hab ich garnicht weiter drauf geachtet. Das entsprechende Bit is mir aus welchen Gründen auch immer beim ersten mal nicht aufgefallen. Hat halt ein paar Stunden bei der Fehlersuche gekostet, weil ich die ganze Zeit den Fehler bei den Optokopplern gesucht hab. An den Code hab ich halt garnicht gedacht, weil er noch von meinen Experimenten mit dem TUSB-Controller war und da hab ich den Takt an UCLK eingespeist. Aber wie's so schön heißt: Aus Fehlern wird man klug.
Also, habe jetzt meinen code wie folgt ueberarbeitet: #include <msp430x43x.h> #include <stdio.h> int main(void) { char ch; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P2DIR |= 0x1A; //P2.4, P2.3 & P2.1 = outputs P2SEL |= 0x30; //UTXD0 and URXD0 = activated U0CTL |= SWRST; // Software-Reset activated U0CTL |= CHAR; //no parity; 1 stop bits; 8-bit data; LISTEN=disabled; //UART mode; Idle-line MP protocol; // U0TCTL = 0x18; // UCLKI=UCLK; ACLK; UART receive start-edge feature; data UTCTL0 = SSEL0; // UCLK = ACLK U0BR0 = 0x68; // 38400 Baud U0BR1 = 0x00; UMCTL0 = 0x20; U0RCTL = 0x00; ME1 |= UTXE0 + URXE0; //USART0 transmit and receive = enabled U0CTL &= ~SWRST; // Software-Reset disabled IE1 = 0x40; //USART0 receive interrupt enabled /* UTCTL0 = SSEL0; // UCLK = ACLK UBR00 = 0x03; // 32k/9600 UBR10 = 0x00; // UMCTL0 = 0x4a; // */ P2OUT = 0x02; ch = 'J'; U0TXBUF = ch; }// main // USART 0 Receive interrupt service routine #pragma vector=USART0RX_VECTOR __interrupt void USART0RX (void) { char temp; temp=U0RXBUF; P2OUT = 0x08; } das sollte jetzt eigentlich laufen funzt aber auch immer noch nicht. habe saemtliche loetstellen ueberprueft - die hardware scheint i. o. zu sein. ich weiss nicht mehr weiter. @thomas: du meintest weiter: "Autor: thomas.o Datum: 14.07.2005 17:25 hallo! ich sehe in deinem Code keine Initialisierung des Clock Systems. Das angeschlossene 32kHz Quarz wird nämlich nicht automatisch als Clock Source verwendet, sondern der interne Oszillator, welcher ca. 800kHz hat. mfg, thomas" wie sehe das denn im konkreten source code aus ?! waere nett wenne mir ma n beispiel posten koenntest - bin echt verzweifelt! Danke gruss an allemann johannes
Ich weiß ja nicht ob es dein Ziel ist einfach P2.3 auf 1 zu schalten sobald irgendwas vom µC empfangen wird. Dein erstes Posting las sich so als wolltest du was am PC sehen. Auf die Gefahr hin mich zu wiederholen: "Du sendest auch nur genau ein Zeichen! U0TXBUF wird nur in Main beschrieben, aber nicht mehr in irgendwelchen IRQs. Da kannst du nur 1 Zeichen beim Reset bekommen. " Wenn du nichts senden willst solltest du auch das U0TXBUF aus main() rausnehmen.
Hallo, hmm, also wenn ich das Programm richtig verstehe, müsste der MSP430 beim Reset ein 'J' schicken und dann verstummen. Kommt vom PC das erste Zeichen rüber (egal welches), wird P2.3 gesetzt. Anschließend passiert nichts mehr ... Wie R2D2 schon sagte, ist evtl. ein bissl spartanisch an Funktionalität ;-) Was genau haste denn vor ? @R2D2: Oh ja, der MSP430 hat da ein paar versteckte "Fallen", die man erst mal wissen muss. Die ganzen Takte und Taktquellen, der genaue Initlaiisierungsablauf bei der USART, der Watchdog ... Bin da auch schon desöfteren wo reingetreten ;-) Grüße, Euer Mario
UART is doch im Datenblatt mit ner dicken fetten Warunung versehen. Wenn man nur angefangen hat das Kapitel zu lesen kann doch nix mehr schief gehen. Ok, der OP hats flsach gemacht. Aber keine Ahnung wie das geht. Den Watchdog hab ich außer für gezielte Resets noch nicht benutzt. Der GCC deaktiviert den ja automatisch beim Start, also stört der mich nicht sonderlich. Insgesamt is der MSP aber ne durchdachte, flexible Architektur. Jetzt müssen nur noch 2xxx er mit mehr Pins/Flash rauskommen. Das wär ideal.
also, zur frage was ich eigentlich machen will: erstmal sichergehen, dass meine hardware i. O. ist und das die serielle schnittstelle funktioniert (deshalb die spartanische architekture; wird ein zeichen empfangen, soll der interrupt handler ausgefuehrt werden und ein LED faengt an zu leuchten - ansonsten wird ein J beim reset gesendet). sobald das laeuft habe ich vor ein keypad auf meinem TI zu implementieren, das jeweils den wert der gedrueckten taste auf dem PC ausgibt, aber bis dahin scheint mir das noch ein langer weg zu sein... da ihr weiter nicht auf meinen code eingegangen seid vermute ich mal das der ok ist. werde dann vielleicht mal den chip zur datenuebertragung auswechseln - vielleicht hab ich den ja beim aufloeten kaputt gemacht. bis dann johannes
Hi, hm, wo wird eigentlich das Interrupt-Enable-Bit gesetzt ? Schreib mal noch die EINT-Anweisung mit rein. Ansonsten müsste der Code eigentlich schon funktionieren. Ich würd nicht gleich den Schnittstellentreiber auslöten, schau doch zuerst mal mit nem Oszi, ob da was passiert. Grüße, Mario
Mario! kurz bevor ich den software reset rausnehme aktiviere ich die interrupts. danach enable ich den receive interrupt weil ich den spaeter nutzen moechte (im prinzip brauch ich den transmit interrupt ja ueberhaupt gar nicht!). ME1 |= UTXE0 + URXE0; //USART0 transmit and receive = enabled U0CTL &= ~SWRST; // Software-Reset disabled IE1 = 0x40; //USART0 receive interrupt enabled "hm, wo wird eigentlich das Interrupt-Enable-Bit gesetzt ? Schreib mal noch die EINT-Anweisung mit rein. Ansonsten müsste der Code eigentlich schon funktionieren. " was meinst du mit der EINT-Anweisung ??? gruesse johannes
Hi, ja schon, das ist ja auch richtig, dass du die Interrupts für die USART freigibst. Du musst aber die Interrupts auch GLOBAL erlauben ! Es gibt ja beim MSP430 (und bei vielen anderen Controllern auch) immer ZWEI Stufen von Interrupt Enable-Flags, die erste sind die SPEZIFISCHEN Flags für die jeweiligen Module (also z.B. USART, ADC, Timer-Interrupts, Port-Interrupts ...), die zweite ist das (einzelne) GLOBALE Interrupt-Flag, das sich im Status-Register aufhält. Ist es nicht gesetzt, wird KEIN Interrupt ausgeführt. Je nach Compiler sieht die Anweisung für das Setzen und Löschen dieses Flags anders aus, bei mir (IAR Kickstart) setze ich das Flag z.B. mit der Anweisung: _EINT(); Hast du einen anderen Compiler, musst du evtl. mal in die Hilfe schauen, wie das bei dir funktioniert. Grüße, Mario
Du hast natuerlich vollkommen recht! ich mach das mit: _BIS_SR(LPM4_bits + GIE); //enable maskable interrupts zu dumm dass ich das vergessen hab! vielen dank fuer die hilfe soweit. ich probier das nachher ma mitm oszi aus und hoffentlich kommt da was durch. ansonsten mal sehen was ich dann mache.. bis dann johannes
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.