Forum: Mikrocontroller und Digitale Elektronik MSP430 UART Timing


von Markus Billeter (Gast)


Lesenswert?

Hallo!

Beim Programmieren eines TI MSP430F169 bin ich auf folgendes Problem
gestossen:
Ich nütze UART, um den uP mit einem PC über RS232 zu verbinden. Nun
geht das ab und zu sehr gut, aber manchmal spinnt es auch, wie z.b. im
Moment. Ich sende aus MATLAB zehn 8-Bit-Bytes am Stück, die vom uP
aufgenommen werden sollten. Dort existiert eine switch-Anweisung in der
Interrupt-Service-Routine, die ein Byte nach dem andern ausliest aus dem
RXBUF. Nun steht aber in einigen erhaltenen Bytes (beim 5., 7. und 8.)
der Terminator (in meinem Fall 127) drin anstatt der effektive Wert.
Irgendwie scheint da ein Timing-Problem vorzuliegen. Da ich einen
4MHz-Quartz benütze, müsste 115200 Baud doch funktionieren. Ich habe
das auch so eingestellt über:
  UBR00 = 0x22;
  UBR10 = 0x00;
  UMCTL0 = 0x00;
Müsste ich die Modulation noch irgendwie anpassen, da die Division von
4MHz durch 115200 Baud keinen Integer gibt? Ich hab's auch schon mit
tieferen Baudraten probiert, was aber nichts nützte.

Vielen Dank für die Hilfe,
Markus

von SupaChris (Gast)


Lesenswert?

Also bei 8Mhz und 115,2kBit/s ist auch im Modulator was drinne, ich
glaube 0x2C. Deshalb wirst du wohl bei 4MHz auch einen Modulatorwert
brauchen.

von Markus Billeter (Gast)


Lesenswert?

Danke. Hast du eine Ahnung, welchen Modulator-Wert ich für 4 MHz
einstellen müsste? Verstehe diesen Modulator ehrlich gesagt nicht so
ganz...

von SupaChris (Gast)


Lesenswert?

Weiß ich leider nicht. Hab mich damit noch nicht so genau beschäftigt.
Bei 8Mhz ist der Teiler ja auch 0x45, also genau die Hälfte geht da
schon mal nicht. Da musst du wohl mal versuchen den Algorithmus zu
verstehn. Sorry.

von Aleksej (Gast)


Lesenswert?

Es gibt ja ein JavaScript, der so was kann:
http://msp430.info/modules.php?name=Gadgets&op=uart

Der gibt folgende Werte aus:
UBR00=0x22; UBR10=0x00; UMCTL0=0xDD; /* uart0 4000000Hz 115200bps
(115274bps) */

von Markus Billeter (Gast)


Lesenswert?

Danke, habe die gegebenen Modulator-Werte aus dem Skript mal
eingestellt. Anscheinend hat mein Problem aber nichts damit zu tun, da
die Übertragung immer noch Fehler hat. Aber nicht zufällige, sondern
reproduzierbare. Es scheinen immer genau die selben Bits falsch
übertragen zu werden. Ist komisch. Ich lese ja ein paar Bytes (also
Characters) nacheinander aus und bei gewissen Werten dieser Bytes
passiert es bei gewissen, dass mein Terminator-Byte 127 statt dem
effektiven Wert drin steht. Aber immer bei denselben...

von Markus Billeter (Gast)


Lesenswert?

Habe mittlerweile gesehen, dass der auftretende Fehler ein UART overrun
error ist, da das OE Flag gesetzt wird. Habe die Baudrate auch mal auf
9k6 runtergeschraubt, aber genau dasselbe. Es scheinen einfach Bytes
verschluckt zu werden beim Empfang... Das einzige, das ich im Moment
tue in der UART RX ISR, ist, den RXBUF0 auslesen und in ein array
abspeichern und dann einen Counter erhöhen. Ich weiss nicht, wie da ein
overrun passieren kann. Weniger kann ich ja nicht machen in der ISR wenn
ich mehrere Bytes nacheinander empfangen will... oder???

von Zimmi (Gast)


Lesenswert?

Hiho,
sperrst Du vielleicht irgendwo in Deinem Programm die Interrupts?

von Markus Billeter (Gast)


Lesenswert?

Nein, die Interrupt-Service-Routine wird schon ausgeführt, aber es
landen einfach nicht alle Bytes in tTemp. Im Moment besteht sie nur aus
einem Auslesen des Buffers:

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
  tTemp[RXCounter] = RXBUF0;
  RXCounter++;
}

Aus MATLAB schicke ich die Daten mit fprintf(serobj,packet), wobei
packet = ['z' Int Int Int ...] aus characters und Integer-Werten
besteht...

von Zimmi (Gast)


Lesenswert?

Hiho nochmal,
weitere Möglichkeit ist noch, dass das Format nicht stimmt (Anzahl
Stop-bits, Parity).
Ansonsten bitte mal den ganzen Code, falls es möglich ist, bitte
zusenden.

von Markus Billeter (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe den Sourcecode angehängt. Habe alle irrelevanten Funktionen
etc. ausgehöhlt, damit es ein bisschen übersichtlicher ist. Die
verbliebene USART ISR sollte die 12 Bytes von MATLAB erhalten.
Stopbits, Databits, Parity sind identisch auf MSP und MATLAB. Könnte es
ev. etwas mit dem Terminator Byte zu tun haben? Wie sieht das beim MSP
aus?
Danke

von Zimmi (Gast)


Lesenswert?

Hiho,
haette da ein paar Vorschlaege:
1. auf ein __disable_interrupt();
 sollte auch irgendwann ein enable folgen
2. du musst den RXBUF0 immer leeren, am besten am Anfang der ISR mit
z.B. cRxBuf = RXBUF0; und dann mit cRxBuf weiterarbeiten. Es gibt
einige Stellen, wo Du den RXBUF0 nicht ausliest z.B. case 11 oder wenn
keiner Deiner Vergleich zuschlägt. Dann kommt z.B. ein Buffer
overflow.
Zieh das mal grade, wenns dann immer noch nicht funktioniert, greife
ich mal zum aeussersten, dann denke ich nach :-)

von Markus Billeter (Gast)


Lesenswert?

Danke für die Vorschläge. Habe beides gemacht, hat aber leider keinen
Unterschied gemacht.
Da ich nur 9600 Baud eingestellt habe, kommt es mir wirklich komisch
vor, dass da ein Overrun stattfindet. Was ich auch schon probiert habe,
war, dass ich den ganzen ISR-Inhalt ersetzt habe durch ein Rausschreiben
in ein Array (siehe frühere Beitrag). Und das war ja das Minimale, das
ich tun könnte....

Oder gibt es grundsätzlich eine bessere Variante, um mehrere Bytes zu
empfangen und aus dem RXBUF0 zu lesen? Wäre DMA nötig?

von Zimmi (Gast)


Lesenswert?

Oerks,
in so einem hartnaeckigem Fall wuerde ich zum Oszi greifen und sowohl
die Pattern ueberpruefen, die vom PC geschickt werden als auch im
MSP-Programm eine Sequenz einfuehren, wo Zeichen geschickt werden und
auch die mit dem Oszi überprüfen.
Vielleicht hast Du ja diese Moeglichkeit...

von Markus Billeter (Gast)


Lesenswert?

Ich hab den Fehler gefunden! Ich hatte in den zu übermittelnden Daten ab
und zu die 10 als Byte drin, was im ASCII Code dem Line Feed entspricht.
Offensichtlich interpretiert der MSP dies als Terminator. Das kann man
wohl nicht umstellen??

Aber es geht noch weiter :--) Nachdem nun dieses Problem softwaremässig
behoben ist, bin ich auf ein Weiteres gestossen:

Die 8-Bit-Werte von 128 bis 159 werden falsch im MSP430 empfangen, sie
betragen immer 26 oder 63 anstatt des effektiven Wertes. Sämtliche
anderen Werte werden absolut fehlerfrei übertragen (1-127, 160-255).
Ich habe den 8-Bit-Modus natürlich eingestellt auf dem MSP.

Hat da jemand eine Ahnung, was schiefläuft???

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
Noch kein Account? Hier anmelden.