Hallo, ich hab 3 kleine Funktionen geschrieben mit denen ich gern daten vom MSP430 an meinen PC übertragen wollte Eine Interruptroutine sollte immer ein Zeichen nach dem anderen verschicken, aber aus mir nicht bekannten gründen wird die nie aufgerufen. Ich Poste einfach mal die Funktionen: void usart0_init_send() { P3SEL |= BIT5 + BIT4; // P3.5 und P3.4 als USART TXD/RXD ME1 |= UTXE0; // TX- und RX-modul erst mal anschalten UCTL0 |= CHAR; // 8 data bits, 1 stop bit, no parity (8N1) UTCTL0 |= SSEL0; // ACLK als UCLK festlegen UBR00 = 0x03; // 9600 baud aus 32.768 kHz erzeugen UBR10 = 0x00; // siehe application note tabelle 2, seite 10 UMCTL0 = 0x4A; // korrektur der division UCTL0 &= ~SWRST; // USART freigeben IE1 |= UTXIE0; // TX- Interrupt anschalten IFG1 &= ~UTXIFG0; // initales interrupt-flag loeschen _BIS_SR(GIE); } #pragma vector=UART0TX_VECTOR __interrupt void usart0_tx (void) { if (outputBufferCounter<send_size) { TXBUF0 = outputBuffer[outputBufferCounter++]; } else { TXBUF0 = 0x0D; sendFlag = 1; } } void usart0_send(char* data, int bytes) { int i; send_size = bytes; sendFlag = 0; outputBufferCounter = 0; for(i=0;i<bytes;i++) outputBuffer[i] = data[i]; usart0_init_send(); while (sendFlag == 0); // Warten bis fertig gesendet free(outputBuffer); IE1 &= ~(UTXIE0); // Sendeinterrupt abschalten } Und jetz wollt ich gern mit dem Aufruf "usart0_send("test", 4);" was an mein Hyperterminal schicken, aber das funktioniert nicht. Wie gesagt ich glaub der Interrupt wird nich aufgerufen! Sieht da irgendwer nen Fehler? Ich verzweifel! :(
Man sollte aus dem "glauben" erst mal "wissen" machen. IAR Compiler/Degugger? Breakpoint in der ISR setzen und schauen ob er wirklich nicht in die Routine springt. Evt. auch mal die UART Register beobachten.
Ja gut ich weiß es weil genau das hab ich gemacht! :P Aber warum? :(
Mal aus dem Bauch heraus,ohne ins Datenblatt zu schauen.... Frage: Wann wird der Sende-Interrupt ausgelöst?Wenn eine aktuelle Übertragung fertig ist oder wenn der Sendepuffer beschrieben werden kann ohne das ein eventuell bereits drin stehendes Zeichen verloren geht?
Wenn der Sendepuffer beschrieben werden kann -> Laut Datenblatt, aber ich nehm ehrlichgesagt an dass des auch gleichzeitig bedeutet dass das Byte verschickt wurde(is für mich nich so direkt ersichtlich).
Aber genau das is relevant.Weil sonst niemals der 1.Interrupt auftritt,mit welchem das nächste (erste!!) Zeichen rausgeschiokt wird. Notfalls kann man beim Aufruf von UARTsend schon das 1.Zeichen rausschicken. Auf diese Weise kann man übrigens auch nicht blockierende Sende-Funktionen schreiben.Die Sendefunktion reiht die Daten in den Sendepuffer ein und kehrt sofort zurück.Alles weitere geschieht quasi im Hintergrund per Interrupt.
servus, also ich mache als ersten funktionstest einer uart meist erstmal ein echo, damit ich weiß das uart auch funzt... desweiteren bitte mal den gesamten code posten... watchdog abgeschaltet? einstellungen am hyperterminal richtig (8N1)? initialisierung der uart sieht gut aus, da vermute ich keinen fehler... gruß
ist zwar ein ganz schönes durcheinander in deinem code, aber der fehler liegt glaub ich in "void usart0_send(char* data, int bytes)" da gehört glaub ich noch einmal die zeile "TXBUF0 = outputBuffer[outputBufferCounter++];" hinein, das ding muss erst einmal angestoßen werden, check das ma... und "if (outputBufferCounter<send_size)" in der isr kannst dir sparen, wenn du da auf "if (data[i] != '\0')" überprüfst und dir den counter und die for-schleife ebenfalls sparst... also ungefähr so: #pragma vector=UART0TX_VECTOR __interrupt void usart0_tx (void) { if (data[i] != '\0') { TXBUF0 = data[i++]; } else { i = 0; // i ist global (ich weiß, nicht ganz fein) } } void usart0_send(char* data) { usart0_init_send(); // würde ich in die main verlagern genau wie den // GIE TXBUF0 = data[i++]; // IE1 &= ~(UTXIE0); // Sendeinterrupt abschalten !!! wozu??? } so, un jetz ab dafür...
So Fehler gefunden: mein ACLK geht nidd... ich hab ka warum mir wurde nur gesagt auf dem board ginge das nidd! o_O aber jetz passt anscheinend meine synchonisation nimmer... zumindest wird der interrupt imme rbrav ausgelöst und von allem was man irgendwie intern ablesen kann wird das zeug verschickt... und extern seh ich mit m oscar auch das es geht ABER es kommt drüben nix an -> baut rate falsch eingestellt... welche einstellungen kann ich für SMCLK nehmen für 9600 baut oder kleiner?
ACLK geht nich? Also kein 32Khz Quarz auf dem Board, oder wie? Wenn man mit der UART arbeiten will, sollte man den schon drauf machen. Dann kann man mit dem DCO immer noch bequem den takt hochsetzen, aber ohne den Quarz läuft der MSP mit dem internen RC Oszillator bei ~800Khz. Und das ist wirklich ungefähr. Wenn man die Parameter für den Baudratenteiler einstellt, funktionieren die nur bei Zimmertemperatur, sobald es ne andere Temperatur oder andere Versorgungsspannung ist, passt das nicht mehr. Da können auch deine Baudratenparameter nicht passen. Da musst du bissl probieren. Ich hatte bei meinen MSPs immer so um die 740khz, wäre also Teiler 77,08 für 9600 Baud. Also UBR00 = 4D; Den Modulator musst du eventuell auch setzen, je nach wirklicher Frequenz (mit dem Oszi messen). Aber das ist dann alles andere als sinnvoll. Bau mal lieber den 32Khz Quarz ein. Kostet ja nicht die Welt.
Naja das Board gehört ja nidd mir! ;) aber das mit den ca 800 khz hab ich auch ca ausgerechnet! :P ich hatte UBR00 = 47 aber ich muss das jetz erstma nochma gescheit mit nem oscar nachmessen!
Und dann wirds mal bissl kühler oder wärmer und nix geht mehr. Also darauf würd ich mich nicht verlassen. Es sei denn, es ist ein neuer MSP aus der x20xx Reihe, die haben Kalibrierwerte für die Oszillatoren...damit gehts besser. Quarz wäre trotzdem gescheiter. Wem gehört das Board denn?
800000/9600 = 0x47??? holla,da haste wo eher mit ca. 680KHz gerechnet... (da kann schon ma grütze am uart ankommen) www.msp430.info sagt für 800kHz -> UBR00=0x53; UBR10=0x00; UMCTL0=0x21; /* uart0 800000Hz 9600bps (9603.84bps) */... hab mir mein eigenes tool geschrieben, das sagt UMCTL0=0x92, und damit lag ich bis jetzt bei jeder baud rate richtig... aber dco is so'ne sache, der reagiert doch schon auf körperwärme ;)...
Jo, müssten 4D sein, hab ich mich wohl vertippt oder so. Aber der DCO mit FLL+ läuft doch auch bei Temp-Schwankungen super ?!? Also ich konnt da noch keine komischen Effekte feststellen, die Frequenz jittert nur immer nen bissl, aber das is ja minimal, hatte mal bei 4,096Mhz aus dem 32Khz Quarz generiert ein Jitter von 12ns oder sowas.
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.