< Projekte PIC2WS2812 |
Steuerung von WS2812-LEDs mit 8-Bit PIC Microcontroller | |
GrundlagenDie PIC LösungSoftwareDefines |
Lösung
mit einem (kleinen) PIC
Im WWW findet man diverse Lösungen zur Ansteuerung von WS2812 LEDs mit Mikrocontrollern, meist auf Basis von Atmel-Mikrocontrollern/Arduino. Fast immer wird Bit-Banging für die Erzeugung des WS2812-Datensignals benutzt. Diese Lösung hat prinzipiell einen Nachteil: der Controller ist während der Datenausgabe zu 100% ausgelastet und kann in dieser Zeit nichts anderes tun, als vorab gespeicherte LED-Daten an die LEDs zu schicken. Für eine Berechnung von Lichtmustern ist daher auch die maximale Anzahl der LEDs durch die Größe des zur Verfügung stehenden RAMs begrenzt, denn das komplette Datenpaket muss ja vor der Übertragung erst im Speicher zusammengebaut werden. Außerdem kann der Controller während der Übertragung nicht auf Ereignisse von außen reagieren, wie z.B. Datenempfang auf einer seriellen Schnittstelle. Es gibt von Microchip eine Application Note (AN1606) für PIC16F1509, wo das Signal mit Hilfe der Confiigurable Logic Cell (CLC) und dem MSSP-Modul (als SPI-Schnittstelle) erzeugt wird und so die Notwendigkeit des Bit-Bangings umgangen wird. Dieser Lösungsansatz ließ mich über eine alternative Lösung für einen kleineren Controller (ohne CLC) nachdenken. Die Motivation dafür war nicht, eine fertige Lösung für meine (ohnehin nicht vorhandene) WS2812-Anwendung zu finden, sondern auszutüfteln, was man mit den beschränkten Hardware-Resourcen des in der Bastelkiste vorhandenen PIC12F1840 anstellen kann... Die Herausforderung:
![]() Und hier der Schaltplan: ![]() Funktionsweise:Die kurzen Impulse (250ns)
für die "0"-Bits werden als PWM-Signal durch TMR2 in
Verbindung mit dem CCP1-Modul erzeugt. Für die längeren
"1"-Bit Impulse (625ns) wird das SPI Clock-Signal (SCL) benutzt.
Durch genau abgestimmtes Timing beim Schreiben in die Register
wird erreicht, daß die steigenden Flanken vom SCL- und
PWM-Signal exakt gleichzeitig auftreten. Diese beiden Signale
bilden die Carrier-Eingangssignale (MDCINx) des Data Signal
Modulators. Dieses Modul schaltet, je nach Signalpegel am
Modulations-Eingang (MDMIN), das eine oder das andere
Carrier-Signal zum Ausgang durch. Angesteuert wird der DSM durch
den Daten-Ausgang (SDO) vom SPI. Auf den dazwischengeschalteten
Comparator kommen wir gleich. Wenn SDO eine "0" ausgibt, wird der
MDCIN2-Eingang zum Ausgang durchgeschaltet (PWM = kurzer Impuls
für "0"), wenn das SPI eine "1" ausgibt, wird der
MDCIN1-Eingang zum Ausgang durchgeschaltet (SCL = langer Impuls
für "1").
Leider gibt es keine
Möglichkeit, intern im PIC den SCL-Ausgang direkt auf den
Carrier-Eingang des DSM zu schalten. Daher ist extern eine
Brücke zwischen den beiden Pins (5+6) am PIC notwendig. Durch
diese externe Verbindung ergäbe sich nun eine etwas
längere Laufzeit des (SCL->MDCIN1)-Signals gegenüber
einem intern verbundenen (SDO->MDMIN)-Signals, was beim Wechsel
von 0 nach 1 kurze Störimpulse am Ausgang des DSM erzeugt
würde. Hier wird der Comparator deshalb zur
Signal-Verzögerung (seine Durchlaufzeit ist ca. 200 ns)
eingesetzt, um die Flanke des MDMIN-Signals in den Zeitbereich
zu verschieben, wo das MDCIN1-Signal stabil auf 0-Pegel
liegt und keine "Glitches" mehr auftreten können.
Wenn ein Byte fertig übertragen wurde, muss die Software rechtzeitig eingreifen, denn die sonst weiterlaufende PWM-Logik würde weitere Impulse erzeugen. Daher wird schon vor der Ausgabe des letzten Bits, bereits beim vorletzten (= 7.) PWM-Impuls, über den Postscaler von TMR2 ein Interrupt ausgelöst, durch den rechtzeitig die Ausgabe des nächsten Datenbytes oder das kontrollierte Ende der Datenübertragung veranlasst wird. Nur so ist auch die zügige Ausgabe der Daten, ohne unnötig große Lücken zwischen den Datenbytes, möglich. Dennoch muss hier ein kleiner Abstrich bei der Übertragungsrate gegenüber der "idealen" Datenrate von 800 Kbit/s (= 10 µs/Byte) hingenommen werden! Das SPI Senderegister des PIC ist nicht gepuffert und erlaubt das Schreiben des nächsten Datenbytes erst, nachdem das letzte Datenbyte vollständig ausgegeben wurde. Hierdurch ergibt sich ein kleiner "Overhead" von 0,5µs zwischen zwei Bytes, so daß effektiv alle 10,5 µs ein Byte gesendet wird. Weiter geht's mit der Software. |
|
Kontakt |