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.
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.
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.
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.
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.
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.
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.
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.
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):
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
voidsendByte(unsignedcharb)
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.
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.