Software - UART / UART - Emulation

Antworten
Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Software - UART / UART - Emulation

Beitrag von Maik81SE »

Moin zusammen,

habe mal eine Frage aus reinem Interesse, ob jemanden von euch etwas über den Weg gelaufen ist, was die Formel

Code: Alles auswählen

SoftTeiler = CPU_Clock div (Baud * 22); // Bitzeitzähler
für den SoftTeiler angeht.

Laut Wiki-Artikel ist diese eher für 16MHz bei [b[9600Baud[/b] ausgelegt.
ATTinyx5 haben ja laut Datasheet max. 10 MHz.
Ich würde die Software-UART gerne auf 8MHz und maximal 115200 Baud betreiben.
Der SoftTeiler mit 3,156 565 656 57 --> 3 scheint mir etwas sehr fehlerhaft bis Arg bescheiden.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Software - UART / UART - Emulation

Beitrag von Winni »

Hi!

115200 : 9600 = 12 : 1
16 : 8 = 2 : 1

Sonst noch Rechenaufgaben für die Grundschule?

Winni

Benutzeravatar
Maik81SE
Beiträge: 308
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
CPU-Target: x86-64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Software - UART / UART - Emulation

Beitrag von Maik81SE »

hab mich heute mal uA bezügöich o.g. Formel mit dem Leiter der Software bei uns auf Arbeit unterhalten...

Selbst er kann anhand des Wikis nicht rausfinden, wo/wie/was der Faktor 22 aussagen soll...
und er ist um längen Fitter als ich, was solche Themen anbeght.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.0.0.3 FPC 3.2.2);
windows 10 (L 3.99.0.0 FPC 3.2.0)

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Software - UART / UART - Emulation

Beitrag von kupferstecher »

Maik81SE hat geschrieben:
Mi 28. Apr 2021, 19:34
Laut Wiki-Artikel ist diese eher für 16MHz bei [b[9600Baud[/b] ausgelegt.
Eine kurze Internetsuche hat mich auf diesen Wikiartikel gebracht, ich nehm an, um den geht es:

https://wiki.lazarus.freepascal.org/AVR ... _Emulation

Dort steht u.a.
"Hinweis: Dieser Code funktioniert nur mit 16MHz CPU-Takt und 9600Baud. Einfach Baud und CPU_Clock anzupassen reicht nicht, weil die Formel noch einen Fehler hat. "

Der Wert SoftTeiler wird dort im Code immer in der gleichen Weise verwendet:

Code: Alles auswählen

for i := 0 to SoftTeiler do;
Das ist in meinen Augen einfach ein schlechtes "Busy-Wait". So wie ich das nämlich verstehe soll die (leere!) Schleife genau eine Signalflanke lang brauchen. Wie schnell die Schleife durchläuft ist aber compilerabhängig und kann sich mit jeder Version ändern. Ich denke der Wert 22 wurde durch Ausprobieren ermittelt.
Richtig wäre die tatsächliche Zeit zu berechnen und dann eine Warteroutine zu rufen.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Software - UART / UART - Emulation

Beitrag von af0815 »

Das mit dem Problem der Schleife ist schon richtig, nur zu dem Zeitpunkt darf es keine Interrupts geben, deswegen sind die bei der Software RS232 abgedreht. Also kannst du dir genaugenommen nur einen bekannten Assemblercode dort einfügen, dessen Timing du kennst bzw. beherrscht und für die jeweilige CPU anpassen. Dann müsstest du nur in der Formel das richtig berücksichtigen.

Bei der Formel ist die Konstante 22 ein Wert der sich aus der Erzeugten Schleife in Assembler ergibt. Weil du muss ja wissen, wie oft du die Schleife durchläufst, bevor du das nächste Bit liest.

Klassisch wartest du einmal bis die erste fallende Flanke da ist, dann verzögerst du um ein halbes Zeichen, damit du halbwegs stabil einlieset., Dann wartest du jeweils genau eine Zeichenlänge. Dann liest du das aktuelle Bit, solange bis du alle Zeichen hast. Jetzt ist die Zeitspanne zwischen den Zeichen das, was dein Code in Assembler von Zeichen zu Zeichen benötigt. Daher brauchst du eine Schleife die genaugenommen die CPUTakte vom Einlesen, Warteloop bis zum Lesen nächsten Zeichen benötigt. Das kann man sich im erzeugten Assembler ansehen und dann seinen individuellen Divisor festlegen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Software - UART / UART - Emulation

Beitrag von siro »

8 MHz entsprechen 125 Nanosekunden.

Bei 115200 Baud ist ein Bit 8,680555555555 Mikrosekunden.

Ein Bit benötigt dann rund 69 Takte

69 mal 125 Nano Sekunden sind 8,625 Mikro Sekunden.

Man benötigt also eine Schleife, welche eine "exakte" Zeit überbrückt.
69 Zyklen für ein Bit

So eine Schleife besteht aus:
Einen Wert setzen, zum Beispiel 22
diesen Wert erniedrigen und dann gucken ob die Schleife beendet werden soll.
Je nach Programmcode/Controller/Befehlssatz kann das natürlich ganz unterschiedlich aussehen
und auch unterschiedlich viel Zeit benötigen.

Im Datenblatt des Controllers in der Rubrik "Instruction Set Summary"
stehen die einzelnen Assemblerbefehle und ganz rechts die Ausführungszyklen #Clocks

Einfache Befehle benötigen nur einen einzigen Clock also 125 Nanosekunden bei 8 MHz
Sprünge mindestens 2 oder sogar 3 bis 4.
Bedingte Sprünge mal 1 oder, wenn gesprungen wird 2

Schaut man sich nun den erzeugten Assemblercode für die "for i" Schleife an,
dann kann man exakt ausrechnen wieviele Takte der Controller für die Schleife benötigt.

Dazu kommt aber noch, das das nächste Bit welches ausgeschoben werden soll auch wieder Code und Zeit benötigt.
Insgesamt also ein recht komplexer Zeitablauf.

Irgendwer hat das anscheinend mal ausprobiert/ausgerechnet oder wie auch immer.
Oft haben die Entwicklungsumgebungen die Möglichkeit Einzelschritte auszuführen und Zyklen zu zählen.
Das vereinfacht die Angelegenheit wenn man das austesten will/muss.

Und wichtig, wie schon erwähnt: Es dürfen innerhalb des Ausschiebens für ein Byte keine Unterbrechungen auftreten
von Timern oder ähnlichem. Das wird durch die Kommandos "CLI" und "STI" sichergestellt.

Das Problem:
macht der Compiler einen anderen Assembler Code daraus, z.B. bei einer neuen Version, Update, andere Optimierungen, dann stimmt der Wert 22 evtl. nicht mehr,
deshalb tätige ich sowas gerne komplett in Assembler, damit das Timing generell sichergestellt ist.
Wenn man dann noch ein Oszilloskop zur Verfügung hat, kann man das natürlich hervorragend anpassen und testen.
Oft kann man dann mit "NOP" Befehlen noch einiges anpassen.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten