Forum: Mikrocontroller und Digitale Elektronik Software UART Verständnisfragen


von andy_help (Gast)


Lesenswert?

Ich habe folgendes Bild im Internet gefunden:
https://images0.cnblogs.com/blog2015/268182/201508/211331218634679.jpg

Wenn ich das Bild sehe, dann wird als erstes das Startbit gesendet.
In der Zeit des Startbit, wird der Ausgangspin auf low gesetzt.
Nun folgen die einzelnen Bits des Bytes.

Beispielstring:
10011101

Bei einer logischen 1, ist der Ausgangspin high und bei einer logischen 
0 low.
Nachdem Übertrag des Byte, wird das Stopbit gesendet.
Beim Stopbit, wird dann der Ausgangspin auf high gesetzt.

Die Zeit vom Startbit, der einzelnen Bits u. des Stopbit sind die 
selben.

Ist dem der Fall?
Wenn ich das jetzt so überlege, dann ist die Geschwindigkeit des 
software uart, von der Geschwindigkeit des Atmega abhängig.
Anhand der Geschwindigkeit des Atmega, kann man ja dann die Zeiten mit 
einem Timer einstellen und somit die Baudrate des software uart.

von STK500-Besitzer (Gast)


Lesenswert?

andy_help schrieb:
> Wenn ich das jetzt so überlege, dann ist die Geschwindigkeit des
> software uart, von der Geschwindigkeit des Atmega abhängig.

Richtiiiich!

> Anhand der Geschwindigkeit des Atmega, kann man ja dann die Zeiten mit
> einem Timer einstellen und somit die Baudrate des software uart.

100 Punkte!
Das ist aber auc beim Hardware-UART so. Dort wird die Taktfrequenz auch 
heruntergeteilt, damit eine brauchbare Baudrate herauskommt.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

andy_help schrieb:
> Ich habe folgendes Bild im Internet gefunden:
> https://images0.cnblogs.com/blog2015/268182/201508/211331218634679.jpg
>
> Wenn ich das Bild sehe,

Wenn ich das Bild ansehen möchte, kommt bei mir
You do not have permission to get URL 
'/blog2015/268182/201508/211331218634679.jpg' from this server.

andy_help schrieb:
> Wenn ich das jetzt so überlege, dann ist die Geschwindigkeit des
> software uart, von der Geschwindigkeit des Atmega abhängig.

hm ... wie kommst du da drauf? Die Bits sind doch imemr gleich lang. Und 
die Bitlänge stellst du über einen Timer ein, so dass du nachher einen 
Timer-Tick von ... sagen wir mal 1 Milli-Sekunde hast. Und die 
Millisekunde ist immer gleich lang, egal wie schnell der uC rennt.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

andy_help schrieb:
> Wenn ich das jetzt so überlege, dann ist die Geschwindigkeit des
> software uart, von der Geschwindigkeit des Atmega abhängig.
Weil jede Software in ihrer Ausführungsgeschwindigkeit von der 
Taktfrequenz abhängt, ist natürlich auch ein Software-UART von der 
Taktfrequenz abhängig.

Aber es kommt noch dicker: auch der Hardware-UART ist von der 
Taktfrequenz abhängig. Wenn du da für den Vorteiler die falsche 
Taktfrequenz angibst oder annimmst, dann kommt die falsche Baudrate 
heraus.

Beim Software-UART kommt allerdings noch dazu, dass du ihn mit einem 
ungünstig geschriebenen Programm "durcheinanderbringen" kannst.

von neuer PIC Freund (Gast)


Lesenswert?

Einen Timer brauchst du nicht aufzusetzen. Dies ist einer der wenigen 
Fälle, wo ein Delay hilfreich ist. Mit den Interrupts gesperrt hast du 
als Auflösung die Zykluszeit des AVR.

Dies ist ein schönes Beispiel, um mal Assembler zu üben. Mit der 
Simulation des AtmelStudio ist dies auch wunderbar einfach.

Reale UART Peripherie hat meist immer einen Vorteiler von 1:4, 1:8 oder 
1:16. SoftUart in Assembler hat 1:1.

Das o.g. gilt allerdings nur für das Senden.

von A. S. (Gast)


Lesenswert?

Möchtest Du nur senden?

Und in welchen baudraten?

Senden ist viieeel einfacher als empfangen. Und Timer gehen erst, wenn 
der Takt ein paar 0en mehr als die baudrate hat.

von andy_help (Gast)


Lesenswert?

Hallo,
vielen Dank für die Infos.
@A. S. (achs)
Nein ich möchte auch empfangen.

Ich sehe die Problematik auch bei dem empfangen.

Hm...wenn ich die Daten gesendet hatte, dann muss ich den Ausgangspin 
auf 1 setzen.
Der Ausgangspin ist ja mit RX des Empfängers verbunden.
Da nun der Ausgangspin des Senders solange auf 1 bleibt, bis er neue 
Daten sendet, muss der Empfänger auf das Startbit warten.
Demzufolge muss man doch nach Empfang des Startbit, die 8 Bit in ein 
array schreiben.
Nach gesendetem Stopbit, setzt man die 8 Bit im array zusammen und 
wandelt den Binärcode in ein ascii Zeichen um.
Dieses ascii Zeichen hängt man dann an ein anderen String an.

von Thomas E. (picalic)


Lesenswert?

A. S. schrieb:
> Und Timer gehen erst, wenn
> der Takt ein paar 0en mehr als die baudrate hat.

Naja, Timer geht schon, auch wenn die Baudrate relativ hoch ist. Außer 
natürlich, wenn die Bitlänge wirklich nur ein paar Taktzyklen lang ist.
Ich benutze z.B. bei 115200 Bd auch bei einem SW-UART gerne einen Timer, 
weil es einfacher ist, den Timer-Wert per Define vom Assembler oder 
Compiler berechnen zu lassen, als die Länge der Delay-Codesequenz 
manuell anzupassen.
Da der SW-Overhead für's Timer-Polling und Bitabfragen bzw. Senden für 
jedes Bit gleich ist, kürzt sich das 'raus und man muss wirklich nur den 
Timerwert ausrechnen und nicht die genaue Laufzeit des Codes.

von Thomas E. (picalic)


Lesenswert?

andy_help schrieb:
> Nach gesendetem Stopbit, setzt man die 8 Bit im array zusammen und
> wandelt den Binärcode in ein ascii Zeichen um.

Ein "echtes" Array wäre etwas umständlich (außer, Du siehst eine 
Byte-Variable als Array aus 8 Bits an). Normalerweise macht man z.B. das 
Empfangen, indem man eine Variable in der Schleife um ein Bit nach 
rechts verschiebt und das empfangene Bit dann mit "or" im höchstwertigen 
Bit setzt.

Hier mal ein Ausschnitt aus einer Timer-ISR zum Empfang per Software 
UART (in dem Fall für einen PIC):
1
    // -------------------- receive next bit:
2
    else if (uartCRbits.RXBSY) 
3
    {
4
      if (uartCRbits.STOPBIT) 
5
      {
6
        uartCRbits.RXBSY = 0;
7
        uartCRbits.STOPBIT = 0;
8
        UIOCN = 1;          // enable rx (negative transition -> startbit)
9
10
        if (UART_PORT)        // got stopbit: rx finished
11
        {
12
          uartDR = uartShR;
13
          uartCRbits.RXBF = 1;
14
        }
15
        T1CONbits.TMR1ON = 0;    // stop timer for 16 bit manipulation
16
        TMR1 = -BITTIME*8;      // set time before any transmission can start
17
        T1CONbits.TMR1ON = 1;
18
        return;
19
      }
20
      if (uartShR & 1)        // if this is the last data bit
21
        uartCRbits.STOPBIT = 1;    // expect stopbit next (= highlevel) 
22
      uartShR >>= 1;
23
      if (UART_PORT)          // read current bit value from rx port
24
        uartShR |= 0x80;      // received a "1"-bit
25
    }

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Ganz Generell: Das senden ist einfach, wenn man dabei "blockieren" darf:

Nacheinander werden 10 Bit ausgegeben, jeweils mit einem Delay 
dazwischen von einer Bitlänge, minus der Zeit, die das setzen des Bits 
dauert. Beispiel: (!! sorgt nur dafür, dass ein Wert ungleich 0 zu 1 
wird)
1
void sendByte(unsigned char b)
2
{
3
  TX_Pin=0;        delay(); /* start */
4
  TX_Pin=!!(b& 1); delay(); /* bit 0 */
5
  TX_Pin=!!(b& 2); delay();
6
  TX_Pin=!!(b& 4); delay();
7
  TX_Pin=!!(b& 8); delay();
8
  TX_Pin=!!(b&10); delay();
9
  TX_Pin=!!(b&20); delay();
10
  TX_Pin=!!(b&40); delay();
11
  TX_Pin=!!(b&80); delay(); /* bit 7 */
12
  TX_Pin=1;        delay(); /* stopp*/
13
}

Das empfangen ist viel schwerer, da

1) die Startflanke erkannt werden muss (meist per interrupt)

2) dann nach genau einer Bitzeit jeweils wieder auf das RX geschaut 
werden muss (also Timer nach 1 aufsetzen, denn im Interrupt den Emfpang 
durchkauen ist übel)

3) die Telegramme oft zu beliebigen Zeiten kommen, während man das 
senden eher in der Hand hat. (z.B. wenn man nach jeder Verarbeitung X 
Bytes sende.

von andy_help (Gast)


Lesenswert?

Oh ok,
danke für die vielen Infos.
Ich habe da aber noch eine Frage zur Baudrate.

https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter

4.800 bit/s   208 µs
9.600 bit/s   104 µs
57.600 bit/s   17,4 µs
115.200 bit/s   8,68 µs

Beispiel:
Es werden 4800 Bits in 1 Sekunde übertragen, was pro Bit 208 µs sind.
Da sind aber das Start u. Stopbit mit einbezogen oder?
Also 1 Byte mit Start u. Stopbit sind 10 Bit.

von spess53 (Gast)


Lesenswert?

Hi

>Da sind aber das Start u. Stopbit mit einbezogen oder?

Es heißt Bit pro Sekunde. Egal ob es Start- Stop- oder Datenbits sind.

MfG Spess

von A. S. (Gast)


Lesenswert?

Ggf + parity und + zweites stoppbit (zu empfehlen)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

andy_help schrieb:
> Da sind aber das Start u. Stopbit mit einbezogen oder?

Richtig.

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.