Hallo liebe Erbsenzähler,
ich habe eine Verständnisfrage zum USART-Transmitter im ATmega88:
Abschnitt 20.3 (p. 172) im Datenblatt des AVR erklärt, wie die Baudrate
für die USART generiert wird. Details in Fig. 20-2.
Jetzt verstehe ich das so, dass der Hauptoszillator per UBRR
runtergeteilt wird, um dann einen Takt von f_osc/UBRR+1 zu erzeugen,
dieser wird nochmal durch 2 und durch 4 geteilt und dann per txclk dem
Transmit Shift Register zugeführt. Der Takt am Schieberegister ist also
f_sr = f_osc/((UBRR+1)*2*4).
Für ein konkretes Beispiel habe ich hier f_osc=2.5MHz, UBRR=4, was einer
Baudrate von 31250Hz entspricht. f_sr ergibt sich mit dann mit 62500Hz,
der doppelten Baudrate, was ja auch Sinn ergibt für die Ansteuerung des
Transmit Shift Registers.
Soweit erstmal mein Verständnis der USART im AVR, jetzt zu meiner Frage:
Ich sehe keine Punkt, an dem der Prescaler bei Laden eines zu senden
Bytes resettet wird. Demnach dürfte beim Reinladen eines Bytes ins
Datenregister UDR eine Latenz von bis zu 1/f_sr = 16us entstehen, bis
die UART anfängt die Daten rauszuschieben, da der Counter ja gerade erst
eine Instruktion zuvor einen Tick generiert haben könnte.
Ich habe nun einen Timer IRQ laufen, der nichts anderes macht als 1 Byte
in die UART zu laden. Der Jitter der entstehenden ISR Response Time
hängt von der momentan ausgeführten Instruktion ab während der Timer
zuschlägt, das sind 0-4 Cycles, maximal also 4/2.5MHz=1.6us.
Wenn ich nun aber den Jitter der UART-Bytes messe (abgetastet mit 24MHz,
15k Samples), so bekomme ich nur diskrete Period Jitter bei +-2us. Was
zur Hölle verstehe ich hier nicht?
Über jeden Hinweis bin ich dankbar.
Viele Grüße,
Max
@ max123 (Gast)
>Jetzt verstehe ich das so, dass der Hauptoszillator per UBRR>runtergeteilt wird, um dann einen Takt von f_osc/UBRR+1 zu erzeugen,
Ja.
>dieser wird nochmal durch 2 und durch 4 geteilt und dann per txclk dem>Transmit Shift Register zugeführt.
Jain.
"The Transmitter divides the baud rate generator clock output by 2, 8 or
16 depending on mode."
8 und 16 sind UART Mode, 2 ist SPI Mode.
>Ich sehe keine Punkt, an dem der Prescaler bei Laden eines zu senden>Bytes resettet wird.
Wird er auch nicht.
>Demnach dürfte beim Reinladen eines Bytes ins>Datenregister UDR eine Latenz von bis zu 1/f_sr = 16us entstehen, bis>die UART anfängt die Daten rauszuschieben, da der Counter ja gerade erst>eine Instruktion zuvor einen Tick generiert haben könnte.
Nein. Die 16 us sind ja die Bitdauer. Diese besteht aber aus 8(16)
Abtasttakten, eben dem Arbeitstakt des USART, welcher CLK / (UBRR+1)
ist.
>Ich habe nun einen Timer IRQ laufen, der nichts anderes macht als 1 Byte>in die UART zu laden. Der Jitter der entstehenden ISR Response Time>hängt von der momentan ausgeführten Instruktion ab während der Timer>zuschlägt, das sind 0-4 Cycles, maximal also 4/2.5MHz=1.6us.>Wenn ich nun aber den Jitter der UART-Bytes messe (abgetastet mit 24MHz,>15k Samples), so bekomme ich nur diskrete Period Jitter bei +-2us. Was>zur Hölle verstehe ich hier nicht?
Ich nehme an, du triggerst auf die Flanke des Startbytes und siehtst dir
dann das nachfolgende Startbyte an. Nun, 2,5 MHz / (4+1) = 500kHz = 2us.
Das ist der Arbeitstakt von Sender und Empfänger. Der Sender schickt
alle 8(16) Takte ein Bit auf die Reise, kann aber bei jedem Arbeitstakt
(500kHz) mit der Sendefolge anfangen.
Hallo Falk,
danke für deine ausführliche Darlegung, das bringt etwas Licht ins
Dunkel!
In wiefern verstehe ich dann Fig. 20-2 falsch, wenn ich den durch 8(16)
geteilten Takt an txclk interpretiere? Wo ist die Funktionalität des
Arbeitstaktes dargestellt?
Max
Ergänzend:
Ich verstehe den ungeteilten Takt f_osc/UBRR+1 nur als Abtasttakt für
den Enpfänger, finde nicht die Stelle, an der der Transmitter damit
angetrieben wird.
@ Max 123 (max123)
>In dieser UART-Darstellung bekommt das TX-SR auch nur Baudclock / 16.
Ja das ist nicht so ganz perfekt dargestellt, ist real aber so. Die
ganze TX Lofig läuft mit f_osc/UBRR+1, danach wird nochmal /16 geteilt,
wie im Bild zu sehen ist.
@ falk
fällt dir dazu ne Literatur ein? Ich muss das für ne wiss. Arbeit
verwenden, wo ich den Jitter abschätze, da wäre ne Bezugsquelle super.
Alles was ich bisher finden konnte hat es leider nicht dargestellt.
Das Thema UART ist ja nun nicht sonderlich wissenschaftlich, demzufolge
wirst du da nicht sooo viel finden. Bestenfalls einen VHDL-Code, wo man
diese zweistufiga Arbeitsweise (f_osc/UBRR+1, danach wird nochmal /16
geteilt) sehen kann.
Dann muss ich damit ggf. leben, in Ordnung.
Was mir jetzt heute bei genauer Betrachtung aber noch aufstößt ist die
Tatsache, dass der Period Jitter 2us beträgt. Und der ISR Jitter also
garnicht zum Tragen kommt. Wo versteckt der sich? Ich sende nur ein
Byte, 0xf0 und triggere auf die fallende Flanke.
Kann ich davon ausgehen, dass der Code synchron zu der ISR läuft? Denn
nur dann hätte ich ja eine konstante IRQ Response Time, wie in [1] schön
erklärt ist. Das kann bei dem Code aber eigentlich nicht sein, da er
nicht nur in der Hauptschleife NOP-t
[1]
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=133252
@ Max 123 (max123)
>Was mir jetzt heute bei genauer Betrachtung aber noch aufstößt ist die>Tatsache, dass der Period Jitter 2us beträgt. Und der ISR Jitter also>garnicht zum Tragen kommt. Wo versteckt der sich?
Wenn er denn übehaupt vorhanden ist innerhalb deiner 2us. Da eine UART
Sendung nur im 2us Raster starten kann, kommt hier ein Jitter kleiner
2us nicht zum tragen. bzw. Wenn die Phasenlage günstig ist, nämlich IM
2us Fenster, hast du gar keinen Jitter am Ausgang!
>Kann ich davon ausgehen, dass der Code synchron zu der ISR läuft?
Welcher Code?
>Denn>nur dann hätte ich ja eine konstante IRQ Response Time, wie in [1] schön>erklärt ist.
In diesem Beispiel stimmt das auch.
Falk Brunner schrieb:>>Was mir jetzt heute bei genauer Betrachtung aber noch aufstößt ist die>>Tatsache, dass der Period Jitter 2us beträgt. Und der ISR Jitter also>>garnicht zum Tragen kommt. Wo versteckt der sich?>> Wenn er denn übehaupt vorhanden ist innerhalb deiner 2us. Da eine UART> Sendung nur im 2us Raster starten kann, kommt hier ein Jitter kleiner> 2us nicht zum tragen. bzw. Wenn die Phasenlage günstig ist, nämlich IM> 2us Fenster, hast du gar keinen Jitter am Ausgang!
:) Da muss ich breit grinsen. Natürlich, da versteckt er sich! Besten
Dank, alle Unklarheiten beseitigt, fabelhaft!
Mit dem Code meine ich den Code in der main-Schleife der ja synchron
laufen müsste mit den IRQs um immer die selbe IRQ Response Time
hervorzurufen.
Heute hab ich viel gelernt. Besten Dank!
Zur Dokumentation für zukünftige Lesende hier die Antwort vom Atmel
Support:
----------8<------------
Hi Maximilian,
The block diagram is simplified, so all the logic is not shown in the
diagram. All the dividers in the path before the TX clock output are
used by the TX shift register only, and thus can be reset whenever
starting transfer of a new byte. This should give a maximum jitter of
fosc/UBRRn+1
Best Regards,
Andreas Loehre
Atmel Technical Support Team
----------8<------------