mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 UART Timing


Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: SupaChris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: SupaChris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Aleksej (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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) */

Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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???

Autor: Zimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hiho,
sperrst Du vielleicht irgendwo in Deinem Programm die Interrupts?

Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Zimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus Billeter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Zimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Zimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Markus Billeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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???

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.