MSP430-Baudratengenerierung: Diskrepanz im Datenblatt

Mein Projekt basiert auf dem MSP430F5529. Aus dem Benutzerhandbuch der MSP430x5xx-Familie :

HINWEIS: Schnelleinrichtung der Baudrateneinstellungen

Führen Sie die folgenden Schritte aus, um die korrekten Einstellungen für die Baudratengenerierung zu berechnen:

  1. N = fBRCLK/Baudrate berechnen [wenn N > 16 weiter mit Schritt 3, sonst mit Schritt 2]

  2. OS16 = 0, UCBRx = INT(N) [weiter mit Schritt 4]

  3. OS16 = 1, UCBRx = INT(N/16), UCBRFx = INT([(N/16) – INT(N/16)] × 16)

  4. UCBRSx kann gefunden werden, indem der Bruchteil von N ( = N - INT(N) ) in Tabelle Tabelle 39-4 nachgeschlagen wird

  5. Wenn OS16 = 0 gewählt wurde, empfiehlt TI eine detaillierte Fehlerberechnung durchzuführen.

Ich berechne gerade die Registereinstellungen für 230,4 kbps bei einem 16 MHz Takt. Meine Berechnungen sind wie folgt:

  1. N = (16000000/230400) = 69,4444 ....
  2. N / A
  3. OS16 = 1 (Oversampling-Modus), UCBRx = (int)(69,4444/16) = 4 , UCBRFx = (int)([(69,4444/16)-(int)(69,4444/16)]*16) = 5
  4. Gemäß Tabelle 39-4 (unten) ist N-(int)N = 69,4444-69 = 0,4444 => UCBRSx = 0x55

Geben Sie hier die Bildbeschreibung ein

Jetzt kommt der verwirrende Teil. Wenn Sie sich Tabelle 36-5 auf Seite 954 ansehen, sehen Sie die folgenden empfohlenen Einstellungen für 16 MHz bei 230,4 kbps mit OS16 = 1:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass „5“ für UCBRSx und „3“ für UCBRFx vorgeschlagen wird. Wie Sie sehen können, stimmen diese Zahlen eindeutig nicht mit den Berechnungen überein. Wenn ich die berechneten Werte und den Wert für UCBRSx aus der Lookup-Tabelle verwende, verhält sich der UART nicht immer richtig, insbesondere bei den niedrigen Bitraten (<9600 bps) und den hohen (>115200 bps). Ich muss in der Lage sein, die Registerwerte des Baudratengenerators für 300 bps bis 230400 bps im laufenden Betrieb zu berechnen, und diese Diskrepanz im Datenblatt macht dies sehr schwierig.

Wenn ich den Berechnungen nicht trauen kann, wie bestimme ich die Registerwerte richtig? Vielleicht interpretiere ich das falsch? Ich habe dieses Tool auch verwendet , um die Einstellungen zu berechnen, und die Ergebnisse stimmen mit Tabelle 36-5 im Datenblatt überein, obwohl die auf der Seite erwähnten Berechnungen die Ergebnisse liefern, die ich aus meinen eigenen Berechnungen erhalten habe.

Ich sehe, dass sie eine detaillierte Fehlerberechnung für verschiedene Optionen vorschlagen, aber das bezieht sich entweder auf die Einstellung der niederfrequenten Baudrate (OS16 = 0) oder wenn für UCBRSx nur Werte zwischen 0 und 7 ausgewählt werden. Dies scheint sich von Tabelle 39-4 zu unterscheiden, da die Tabelle darauf hindeutet, dass Werte zwischen 0x00 und 0xFF verwendet werden könnten.

Mein Code ist wie folgt:

void uartConfig(uint32_t frequency, uint32_t baud) {

    float divFactor;
    uint16_t UCBRx;
    uint8_t oversampling;
    uint8_t UCBRFx;
    uint8_t UCBRSx;

    // Calculate baud rate modulation register values
    divFactor = (float)((float)frequency/(float)baud);
    // High frequency mode
    oversampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;    // High frequency baud rate generation
    UCBRx = (uint16_t)(divFactor/16);                               // Calculate integer part of N divided by 16
    UCBRFx = round(((divFactor/16) - (uint16_t)(divFactor/16)) * 16);   // Calculate first modulation stage
    // Found from table for N-INT(N); See slau208q Pg. 1037 for details
    UCBRSx = getUCBRSxValue(divFactor);                             // Second modulation register

    uartParams.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
    uartParams.clockPrescalar = UCBRx;
    uartParams.firstModReg = UCBRFx;
    uartParams.secondModReg = UCBRSx;
    uartParams.parity = USCI_A_UART_NO_PARITY;
    uartParams.msborLsbFirst = USCI_A_UART_LSB_FIRST;
    uartParams.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
    uartParams.uartMode = USCI_A_UART_MODE;
    uartParams.overSampling = oversampling;
}

Und die "Nachschlagetabelle" (ish):

// Lookup table for UCBRSx values
uint8_t getUCBRSxValue(float factor) {
    uint16_t frac = (factor - (uint16_t)factor) * 10000;
    if (frac < 529) {
        return 0x00;
    } else if ((frac >= 529) && (frac < 715)) {
        return 0x01;
    } else if ((frac >= 715) && (frac < 835)) {
        return 0x02;
    } else if ((frac >= 835) && (frac < 1001)) {
        return 0x04;
    } else if ((frac >= 1001) && (frac < 1252)) {
        return 0x08;
    } else if ((frac >= 1252) && (frac < 1430)) {
        return 0x10;
    } else if ((frac >= 1430) && (frac < 1670)) {
        return 0x20;
    } else if ((frac >= 1670) && (frac < 2147)) {
        return 0x11;
    } else if ((frac >= 2147) && (frac < 2224)) {
        return 0x21;
    } else if ((frac >= 2224) && (frac < 2503)) {
        return 0x22;
    } else if ((frac >= 2503) && (frac < 3000)) {
        return 0x44;
    } else if ((frac >= 3000) && (frac < 3335)) {
        return 0x25;
    } else if ((frac >= 3335) && (frac < 3575)) {
        return 0x49;
    } else if ((frac >= 3575) && (frac < 3753)) {
        return 0x4A;
    } else if ((frac >= 3753) && (frac < 4003)) {
        return 0x52;
    } else if ((frac >= 4003) && (frac < 4286)) {
        return 0x92;
    } else if ((frac >= 4286) && (frac < 4378)) {
        return 0x53;
    } else if ((frac >= 4378) && (frac < 5002)) {
        return 0x55;
    } else if ((frac >= 5002) && (frac < 5715)) {
        return 0xAA;
    } else if ((frac >= 5715) && (frac < 6003)) {
        return 0x6B;
    } else if ((frac >= 6003) && (frac < 6254)) {
        return 0xAD;
    } else if ((frac >= 6254) && (frac < 6432)) {
        return 0xB5;
    } else if ((frac >= 6432) && (frac < 6667)) {
        return 0xB6;
    } else if ((frac >= 6667) && (frac < 7001)) {
        return 0xD6;
    } else if ((frac >= 7001) && (frac < 7147)) {
        return 0xB7;
    } else if ((frac >= 7147) && (frac < 7503)) {
        return 0xBB;
    } else if ((frac >= 7503) && (frac < 7861)) {
        return 0xDD;
    } else if ((frac >= 7861) && (frac < 8004)) {
        return 0xED;
    } else if ((frac >= 8004) && (frac < 8333)) {
        return 0xEE;
    } else if ((frac >= 8333) && (frac < 8464)) {
        return 0xBF;
    } else if ((frac >= 8464) && (frac < 8572)) {
        return 0xDF;
    } else if ((frac >= 8572) && (frac < 8751)) {
        return 0xEF;
    } else if ((frac >= 8751) && (frac < 9004)) {
        return 0xF7;
    } else if ((frac >= 9004) && (frac < 9170)) {
        return 0xFB;
    } else if ((frac >= 9170) && (frac < 9288)) {
        return 0xFD;
    } else if (frac >= 9288) {
        return 0xFE;
    }
    return 0x00;
}
Sie berechnen UCBRx nicht korrekt. Du hast vergessen, es durch 16 zu teilen
Welchen Chip verwendest du?
@EugenSch. Entschuldigung, ich habe vergessen, das einzugeben. Ich berechne N = 69,4444, aber ich teile durch 16, um den UCBRx zu erhalten (der in diesem Fall gleich 4 ist).
@jsolarski Ich werde den Beitrag aktualisieren.
Ich denke, der Schlüssel liegt im letzten Satz von 39.3.10.2: Die Einstellung der zweiten Modulationsstufe (UCBRSx) kann durch Ausführen einer detaillierten Fehlerberechnung oder durch Verwenden von Tabelle 39-4 und dem Bruchteil von N = fBRCLK/Baudrate gefunden werden. . Vermutlich werden die Werte aus den Tabellen durch eine detaillierte Fehlerrechnung ermittelt .
@EugenSch. Ich habe mich gefragt, ob das so ist. Möglicherweise muss ich auf die Berechnungen ganz verzichten und eine vollständige Nachschlagetabelle für alle Werte zusammenstellen, die ich benötige (300 bps bis 230400 bps).
Seltsamerweise funktionieren die Werte aus der Tabelle bei 230400 nicht. Ich vermute, dass mein Takt nicht genau 16 MHz beträgt, aber vielleicht 15999000 oder so ähnlich. Ich bin mir nicht sicher, welche Art von Toleranz diese Uhr hat, ohne in das Datenblatt einzudringen

Antworten (2)

IIRC USCI und eUSCI sind zwei unterschiedliche Implementierungen von Hardwaremodulen (beachten Sie den Moniker „erweitert“ in Abschnitt 39, nichts in Abschnitt 36).

Die TI-Referenzhandbücher neigen dazu, Abschnitte für ganze Familien einzufügen, sodass Sie zum jeweiligen Datenblatt gehen müssen, um zu sehen, was Sie tatsächlich haben.

Der '5529 hätte gegebenenfalls Abschnitt 36, nicht Abschnitt 39, da ich im Gerätedatenblatt keine Hinweise auf ein eUSCI sehe.

Ich stimme auch zu, Tabelle 36-4 und Tabelle 36-5 sollten die richtigen Einstellungen sein.
Guter Fang bei eUSCI vs. USCI. Das ist nicht das erste Mal, dass ich davon gebissen wurde. Es scheint, dass die Tabelle, auf die ich mich bezogen habe (39-4), tatsächlich NICHT auf meine Situation anwendbar ist, da ich den nicht "erweiterten" UART verwende. Es scheint, dass ich keine Wahl habe und eine vollständige Fehleranalyse der UCBRSx-Einstellungen (0-7) durchführen muss, um diejenige zu finden, die korrekt funktioniert. Ich werde wahrscheinlich nur eine Nachschlagetabelle für die Werte erstellen.
Ich würde eine Nachschlagetabelle verwenden und sie dann benutzerdefinierte auf Segment A flashen, wenn Sie keine DCO-Kalibrierung verwenden, wenn Sie eine DCO-Kalibrierung oder eine andere Kalibrierung verwenden, die Segment A verwendet, funktioniert Segment B ebenfalls, aber es ist auf 128 Bytes begrenzt ebenso C und D
Ich denke, ich werde mir die Einschränkung auferlegen, dass meine Taktfrequenz immer 16 MHz beträgt, in diesem Fall kann ich einfach einen Schalter / ein Gehäuse für die Baudrate verwenden und vorher bestimmte Werte anwenden. Ich denke, das wäre schneller als ein Lesen aus dem Flash

Wie ist das im Vergleich? UCA0MCTL = 0x5B

clock: 16000000Hz
  desired baud rate: 230400bps
  division factor: 69.5
  effective baud rate: 230216bps
  maximum error: 0.0347us   0.80%

  time table (microseconds):
        event      desired effective  error   error%
startbit->D0      4.34      4.31  +0.0277  +0.64
D0->D1            8.68      8.69  -0.0069  -0.16
D1->D2           13.02     13.00  +0.0208  +0.48
D2->D3           17.36     17.38  -0.0138  -0.32
D3->D4           21.70     21.69  +0.0138  +0.32
D4->D5           26.04     26.06  -0.0208  -0.48
D5->D6           30.38     30.37  +0.0069  +0.16
D6->D7           34.72     34.75  -0.0277  -0.64
D7->stopbit      39.06     39.06  +0       +0.00
end of stopb     43.40     43.44  -0.0347  -0.80

 UBR00=0x45; UBR10=0x00; UMCTL0=0xAA;  uart0 16000000Hz 230215bps 
 UBR01=0x45; UBR11=0x00; UMCTL1=0xAA;  uart1 16000000Hz 230215bps 

uart-Rechner: http://mspgcc.sourceforge.net/baudrate.html

Diese Programmlizenz finden Sie unter: http://www.fsf.org/licenses/licenses.html#GPL

  this program is distributed WITHOUT ANY WARRANTY

Sie werden verstehen, ob dies relevant ist, nicht ich ...

Integrieren der Änderungen, die in dem in mspgcc-20120911 https://github.com/contiki-os/contiki/wiki/MSP430X bereitgestellten Patch enthalten sind

Das ist ein nettes Werkzeug.