Forum: Compiler & IDEs ATtiny10 Software-UART optimieren


von Leo H. (Gast)


Angehängte Dateien:

Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

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)"

von Leo H. (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.