Altifigence Academy

63 / 63 · Konzept

Abschlusslabor: UART-Sender und Rahmentiming

Teilerzähler, Schieberegister und Flusssteuerung für 8N1 verbinden und Bitgrenzen prüfen.

Zuerst das Rahmenformat festlegen

Voraussetzungen: Zähler, SchieberegisterRegister Speichert einen Zustand aus mehreren Bits. Die synchronen Register dieses Kurses übernehmen festgelegte Eingaben an Taktflanken. Mehr erfahren, valid/ready und synchroner ResetReset Steuerung zur Rückkehr in einen festgelegten Anfangszustand. Synchron/asynchron und Priorität gegenüber anderen Steuerungen müssen definiert werden. Mehr erfahren.

UARTUART Serielle Kommunikation mit Start-, Daten- und Stopbits ohne separate Taktleitung. Sender und Empfänger müssen Baudrate und Rahmenformat vereinbaren. im Format 8N1 sendet ein Startbit, acht Datenbits, keine Parität und ein Stopbit. Idle und Stop sind 1, Start ist 0, Daten kommen LSB-firstLSB Bit mit dem niedrigsten Stellenwert. Darstellungsrichtung und Indexkonvention müssen gemeinsam geprüft werden. Mehr erfahren. Alle Bits dauern gleich lang. Diese Übung behandelt nur Senden mit einem Datenlieferanten im selben Takt.

Bactual=fclkD,ϵ=Bactual−BtargetBtarget×100%B_{\mathrm{actual}}=\frac{f_{\mathrm{clk}}}{D},\qquad \epsilon=\frac{B_{\mathrm{actual}}-B_{\mathrm{target}}}{B_{\mathrm{target}}}\times100\%

Bei 48MHz und Ziel 115200 Baud ist ganzzahlig D=417 möglich. Die tatsächliche Rate liegt bei etwa 115108 Baud, Fehler etwa −0.080%. Zulässige Gesamtabweichung einschließlich Empfänger ist gerätespezifisch zu prüfen.

0x53 in Übertragungsreihenfolge entfalten

0x53 wird 01010011 geschrieben, auf der Leitung erscheinen niedrigste Bits zuerst: 1,1,0,0,1,0,1,0. Eine Diagrammspalte ist eine Bitperiode aus D Takten, kein einzelner Systemtakt. Vor- und nachgelagertes Idle ist zum Vergleich jeweils eine Spalte lang gezeigt.

UART 8N1 · 0x53 · LSB first
Wellenformdaten anzeigen
Wellenformdaten: Jedes Zeichen steht für ein Intervall, ein Punkt hält den vorherigen Zustand und p ist ein Taktzyklus.
SignalWellenformBuswerte
tx101.0.10101.
phase234523452345idle → start → d0 → d1 → d2 → d3 → d4 → d5 → d6 → d7 → stop → idle

Von Start bis Stop sind es exakt 10D Takte. Auch aufeinanderfolgende gleiche Bits haben je eine volle Bitperiode; fehlende Flanken bedeuten keine fehlenden Bits.

Ein Byte genau einmal erfassen

CLKS_PER_BIT ist eine Konstante mit einem Wert von mindestens 1. Bei busy werden keine Eingaben angenommen; nur das beim Start erfasste Byte wird verwendet. Es wird kein neuer Bit-Takt erzeugt: Ein Zähler steuert die Bewegung im ursprünglichen Takt.

SystemVerilog
module uart_tx #(
    parameter int unsigned CLKS_PER_BIT = 417,
    localparam int CW = (CLKS_PER_BIT <= 1) ? 1 : $clog2(CLKS_PER_BIT)
) (
    input  logic       clk, rst,
    input  logic       in_valid,
    output logic       in_ready,
    input  logic [7:0] in_data,
    output logic       tx, busy, done
);
    logic [9:0] frame;
    logic [3:0] bits_left;
    logic [CW-1:0] ticks_left;
    assign in_ready = !busy;

    always_ff @(posedge clk) begin
        if (rst) begin
            tx         <= 1'b1;
            busy       <= 1'b0;
            done       <= 1'b0;
            bits_left  <= 4'd0;
            ticks_left <= '0;
        end else begin
            done <= 1'b0;
            if (!busy) begin
                if (in_valid) begin
                    frame      <= {1'b1, in_data, 1'b0};
                    tx         <= 1'b0;
                    busy       <= 1'b1;
                    bits_left  <= 4'd10;
                    ticks_left <= CW'(CLKS_PER_BIT-1);
                end
            end else if (ticks_left != 0) begin
                ticks_left <= ticks_left - 1'b1;
            end else if (bits_left == 4'd1) begin
                tx   <= 1'b1;
                busy <= 1'b0;
                done <= 1'b1;
            end else begin
                frame      <= {1'b1, frame[9:1]};
                tx         <= frame[1];
                bits_left  <= bits_left - 1'b1;
                ticks_left <= CW'(CLKS_PER_BIT-1);
            end
        end
    end
endmodule

Sei E0 die Annahmeflanke: tx wird Start=0. Danach wechselt das gesendete Bit in Abständen von genau D Takten. Bei E0+9D beginnt Stop; bei E0+10D fällt busy und done pulst einen Zyklus. Auch Stop muss volle D Perioden dauern.

Da in_ready vor der Abschlussflanke noch 0 ist, kann der nächste Rahmen frühestens an der folgenden Flanke beginnen. Mindestabstand der Annahmen ist 10D+110D+1 Takte. Dieser eine Idle-Takt gehört zum normalen Verhalten.

Die Bitfolge von Hand vorhersagen

Die Daten von 8'h53 sind LSB-first 1,1,0,0,1,0,1,0. Der vollständige Rahmen lautet:

Positionstartd0d1d2d3d4d5d6d7stop
tx0110010101

Zählen Sie nicht nur tx-Wechsel: Gleichbleibende Nachbarbits erzeugen keine. Tasten Sie ab Rahmenstart jede Bitperiode in ihrer Mitte ab und vergleichen Sie, einschließlich Start-/Stopdauer. Kleine D-Werte 1,2,3 eignen sich für schnelle Komponententests.

Erweiterung mit FIFO

Eine FIFOFIFO Warteschlange, die zuerst eingefügte Daten zuerst ausgibt. Voll-/Leerzustände und Regeln gleichzeitigen Lesens/Schreibens gehören zum Vertrag. Mehr erfahren mit registriertem Lesen aktualisiert dout und dout_valid nach der angenommenen pop-Flanke. Nachfolgende gleich getaktete Logik erfasst sie an der nächsten steigenden FlankeSteigende Flanke Übergang des Takts von 0 auf 1. Nicht zu verwechseln mit dem gesamten hohen Pegelintervall CLK=1. Mehr erfahren. Wer dout schon an der pop-Annahme an UART übergibt, kann alte Daten senden. Nutzen Sie einen Einplatzpuffer für die Antwort und einen pending-Zustand, um bei UART-ready genau einmal zu übertragen.

Prüfen Sie abschließend 00, FF,01,80,55,53, Eingangswechsel bei busy, aufeinanderfolgende Rahmen und Reset mitten im Rahmen. Reset bricht ab und setzt tx auf Idle=1. Der Empfänger kann den abgebrochenen Rahmen dennoch als gültig erkennen; die UART-Rahmenprüfung allein garantiert daher keine Erkennung des Abbruchs. Wenn die betroffenen Daten verworfen werden müssen, ist eine Systemvereinbarung erforderlich, die den Reset des Empfängers mit dem Sender koordiniert oder dem Empfänger ein separates Abbruchsignal übermittelt.

Weiterführend: Microchip — EUSART and 8N1 framing

Selbst ausprobieren

CLKS_PER_BIT=4, Annahme an E0: Wann beginnen d0 und stop, wann kommt done? Wird ein neues in_valid=1 schon an E40 angenommen?

Erklärung lesen

d0 beginnt nach E4, stop nach E36, done nach E40. Vor E40 ist busy=1 und in_ready=0: noch keine Annahme. Der Sender hält valid und data; frühestens E41 wird das nächste Byte angenommen. Rahmenlänge 40 Takte, Mindestabstand 41.

Deine Auswahl gilt für diesen Browser. Du kannst sie jederzeit in der Fußzeile ändern.