Hallo, für ein LED-Projekt brauchte ich viele verteilte PWM-Ausgänge. Dafür habe ich einen ATtiny10 verwendet und ein angepasstes Software-UART geschrieben. Weil der Chip nur einen Timer hat muss ich nebenbei noch eine Software-PWM laufen lassen. Die µC sind hintereinander geschaltet und reichen einen 24 Bit großen Datenrahmen weiter (der genaue Aufbau steht im Quelltext). Ein TTL-Feld wird bei jedem Schritt runtergezählt, wenn es auf "1" steht übernimmt der ATtiny die Daten. Frames mit TTL "0" gehen als Broadcast an alle Empfänger. Soweit funktioniert das schon gut, ich schaffe 490Hz PWM und ca. 16kHz Bustakt. Allerdings muss ich zwischen zwei Frames mindestens 5ms warten, ansonsten kommt die Software-PWM durcheinander. Ich würde das gerne noch optimieren um ohne die langen Pausen senden zu können. Wäre nett wenn mal jemand reinschaut, ich finde einfach nicht was da ohne Pause schief geht. Ach ja, der Speicher ist zu 99,8% voll :) Danke!
Leo-andres H. schrieb: > Wäre nett wenn mal jemand reinschaut Reinschauen reicht nicht, man müßte erstmal den ganzen Ablauf verstehen. Dazu könnte die Beschreibung deutlich ausführlicher sein. Empfängt die UART 3Bytes oder 26Bit? Ich hab hier mal ne Kommunikation zwischen MCs programmiert, die auf jedes Bit synchronisiert. Man braucht also keinen Quarz oder Autobaud. Beitrag "mehrere MC seriell über Datenbus verbinden (1Draht)"
Danke für den 124Bus, den schaue ich mir mal genauer an! Meine Software überträgt 3 Bytes. Darüber liegt dieses Bitfeld:
1 | struct { |
2 | uint8_t Preamble : 3; //Autobaud Präambel 0/1/0 |
3 | uint8_t Blank : 1; //Ausgang deaktiviert |
4 | uint16_t PWM : 11; //PWM Tastgrad 0-1024 |
5 | uint8_t Latch : 1; //Wert übernehmen |
6 | uint8_t TTL : 6; //Frame TTL, 0=Broadcast |
7 | uint8_t Parity : 1; //gerade Parität |
8 | uint8_t EOF : 1; //Endmarke 0 |
9 | }
|
Im Ruhezustand liegt die Datenleitung per Pullup auf High-Pegel, auf dem Bild sieht man wie der Master kurz vor dem Trigger seinen Ausgangstreiber aktiviert. Die ersten drei Bits sind ein festes Muster (0/1/0) und lösen Input Capture Interrupts aus um die Baudrate zu bestimmen. Alle weiteren Bits werden danach timergesteuert (Compare Match) bei ca. 50% Bitzeit eingelesen. Ein fertig empfangener Datensatz wird in der Hauptschleife ausgewertet (Parität und Endmarke prüfen, dann ggf. Werte übernehmen und weitersenden) Bevor gesendet wird wartet das Programm auf die lange PWM Phase. Die Bits werden dann im Compare Match Interrupt mit der vorher bestimmten Baudrate rausgeschoben. Edit: Einzelne Schritte lassen sich finden wenn man nach der Variable "busMode" in dieser Reihenfolge sucht: Empfangen "IDLE, RX_BAUD_LOW, RX_BAUD_HIGH, RX, RX_DONE" Senden "TX_WAIT, TX, TX_DONE, IDLE"
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.