Forum: Mikrocontroller und Digitale Elektronik WS2812/2811 mit PIC asm.Verzweiflung!


von Tom L. (xedux)


Angehängte Dateien:

Lesenswert?

Moin ihrs..

ich probiere seit einigen Tagen, die WS2812 LEDs zum laufen zu bekommen.
Controller ist ein PIC18F2320, derb übertaktet mit 32MHz (läuft aber 
trotzdem). So komm ich auf einen Systemtakt von 8MHz.
Die gewählte Methode ist das sog. Bitbanging.
Ich hab es "schon" auf die Reihe bekommen, die LEDs anzusteuern, 
allerdings eher Laienhaft. Mein erster Code war einfach nur ne Bitfolge 
(24 Bits) mit anschließendem Reset code für die LEDs. Mehrere LEDs 
konnte ich auch zum leuchten bringen, indem ich das ganze kontinuierlich 
geloopt habe. Das alles allerdings nur in einer Farbe und nicht 
wechselnd oder fadend.

Mein Code ist im Anhang, interessant wirds erst ab der "main".
Ich habe irgendwie das gefühl ich bin mit meiner Methode VÖLLIG auf dem 
Holzweg, denn wenn ich versuche verschiedene Farben oder Übergänge zu 
erzeugen, check ich nicht wie das gehen soll. Das ganze rumgewusel um 
andere Farben zu erzeugen zerstört irgendwie mein Timing :(

Könnte sich da mal einer erbarmen und meinen Code durchschauen?
Ganz Klasse wäre natürlich eine Codevorlage die gut zu verstehen ist in 
asm und welche evtl auch mal die Farben wechselt, damit ich das 
verstehen kann..

Dank und Gruß

xedux

von usuru (Gast)


Lesenswert?

nimm die 3 Bytes für die 3 Farben und schiebe sie über die 
SPI-Schnittstelle raus (Din an DATA anschliessen, den CLK einfach 
vergessen)

von Tom L. (xedux)


Lesenswert?

Ich hab gelesen, dass die SPI nicht schnell genug ist für die 800kbps.
SPI hab ich auch noch nie benutzt... muss ich erstmal lesen wie das 
gehen soll..

von akaDem (Gast)


Lesenswert?

Tom L. schrieb:
> Ich hab gelesen, dass die SPI nicht schnell genug ist für die 800kbps.
> SPI hab ich auch noch nie benutzt... muss ich erstmal lesen wie das
> gehen soll..

Ich hab gelesen, dass du nichts über SPI zu wissen scheinst.

von spontan (Gast)


Lesenswert?

Warum willst Du den Prozessor übertakten? Hat das einen technischen 
Sinn????

von Tom L. (xedux)


Lesenswert?

akaDem schrieb:
> Ich hab gelesen, dass du nichts über SPI zu wissen scheinst.



jo, da hast du Recht! Was ich weiß ist, dass das ne serielle 
Schnittstelle ist, habs aber noch nie benutzt und weiß daher nicht wie 
das Ding funktioniert. Ich denk mal Byte in den Puffer, dann übertragen 
bis Byte leer, nächstes Byte. aber wie das nun auf dem PIC geht ...habs 
mir grad im Datenblatt angeschaut... erschlägt mich erstmal. Ich werd 
mal schauen, ob ich ein Beispiel finde..

von Tom L. (xedux)


Lesenswert?

spontan schrieb:
> Warum willst Du den Prozessor übertakten? Hat das einen technischen
> Sinn????

Ja, um auf meine Bit-Zeiten zu kommen. Der PIC hat nen Frequenzteiler (4 
x Mux) intern, der den Oszillatortakt durch 4 teilt für den Systemtakt. 
und mit 32MHz lande ich bei ner Bitzeit von 125ns.

von Chris B. (dekatz)


Lesenswert?

Wieso ist der Übertaktet???
Der 18F2320 schafft HS-PLL Modus mit einem 10MHz Quarz 40Mhz !
CONFIG1H, FOSC3:0 = b'0110'

Mit deiner CONFIG OSC=HS schafft er genau die Quarzfrequenz, die 
richtige Einstellung ist CONFIG OSC=HSPLL !

Datenblatt:
--> 1.3 Device Overview
--> 2.3 HSPLL
--> 23.1 Configuration Bis

von Tom L. (xedux)


Lesenswert?

Chris B. schrieb:
> Wieso ist der Übertaktet???
> Der 18F2320 schafft HS-PLL Modus mit einem 10MHz Quarz 40Mhz !
> CONFIG1H, FOSC3:0 = b'0110'

Ja, das stimmt. Allerdings ist dann mein Systemtakt wieder bei 10MHz, da 
Fosc/4 = Systemtakt. Damit kann ich meine Timings nicht passend 
einstellen.
Und selbst wenn die Toleranzen dies zulassen...
...geht es hier auch nicht um übertaktet oder nicht.. sondern 
ausschließlich darum, wie ich das Ding sinnvoll betreibe..

von Tom L. (xedux)


Lesenswert?

Chris B. schrieb:
> Mit deiner CONFIG OSC=HS schafft er genau die Quarzfrequenz, die
> richtige Einstellung ist CONFIG OSC=HSPLL !

Ja, auch das hab ich gesehen, allerdings hab ich keinen 10MHz Schwinger 
da. nur 16 und 32. Daher meine Wahl

Die Bitzeiten passen gefünftelt oder gezehntelt einfach besser

von PIC N. (eigo) Benutzerseite


Lesenswert?

Vielleicht hilft dir das beim Einarbeiten in SPI: 
http://pic-projekte.de/wiki/index.php?title=PIC_Tutorial#SPI

von Tom L. (xedux)


Lesenswert?

jo, danke. Ich versuchs jetzt mal mit Hilfe des Datenblattes. Ist ja gar 
nicht so kompliziert, wie ich dachte.... mal schauen was das wird.

von Ollus (Gast)


Lesenswert?

Tom L. schrieb:
> Ja, das stimmt. Allerdings ist dann mein Systemtakt wieder bei 10MHz, da
> Fosc/4 = Systemtakt. Damit kann ich meine Timings nicht passend
> einstellen.

Dann nim halt einen 8MHz Quarz. Weil: 8*4/4 = 8. Und man braucht sich 
hier schon mal keine Gedanken ums Übertakten zu machen.

Und beim PIC-Assembler muß man nicht so viel 'GOTO' benutzen. Das bringt 
uns PIC-Programmierer immer wieder in Verruf und hält das Vorurteil 
aufrecht, PIC-Code sei unübersichtlich ;-)

Übrigens geht das Bitbanging auch mit 10MHz:
Beitrag "Re: [Mitbestellung] SMD5050 RGB-LED mit integriertem 8-bit PWM Controller"

von Tom L. (xedux)


Lesenswert?

Ollus schrieb:
> Dann nim halt einen 8MHz Quarz. Weil: 8*4/4 = 8. Und man braucht sich
> hier schon mal keine Gedanken ums Übertakten zu machen.
>
> Und beim PIC-Assembler muß man nicht so viel 'GOTO' benutzen. Das bringt
> uns PIC-Programmierer immer wieder in Verruf und hält das Vorurteil
> aufrecht, PIC-Code sei unübersichtlich ;-)
>
> Übrigens geht das Bitbanging auch mit 10MHz:

Stimmt mit 8MHz und PLL an ginge das auch, wäre dasselbe. Hab aber jetzt 
auch keinen 8MHz Quartz. Wie auch immer, das ist erstmal Nebensache.

Das mit den vielen GOTOs hab ich nur erstmal so gemacht.. schön ist der 
code nicht, das weiß ich wohl :)

Sobald ich raus hab wie das nun funktioniert wird das angepasst.

SPI funktioniert übrigens, hab gerade ein Testbyte rausgeschoben, 
allerdings noch mit Ruhepegel high.. der muss noc hauf low. aber sonst 
scheint das zu klappen. Jetzt ärgert mich noch, dass ich immer 8 Bit 
ausgeben muss, bevor das nächste Byte in den Buffer kann... Meine 
Bitzelle für die LEDs ist 1,25µs und das sind bei 8MHz 10 Bits bzw 5 
Bits bei 4MHz.
Kann man auch nur 5 Bits pro Byte senden? bzw. wie mache ich aus meiner 
8 Bit-Variablen im code ein 5 Bit langes "Byte"?

von Tom L. (xedux)


Lesenswert?

Ollus schrieb:
> Und beim PIC-Assembler muß man nicht so viel 'GOTO' benutzen. Das bringt
> uns PIC-Programmierer immer wieder in Verruf und hält das Vorurteil
> aufrecht, PIC-Code sei unübersichtlich ;-)

ich hab mir noch keine Technik angeeignet, welche die gotos umgeht. Hab 
mal versucht den PC zu manipulieren und so zu springen, hat aber nicht 
geklappt....

von Tom L. (xedux)


Angehängte Dateien:

Lesenswert?

Die "einfache" Datenweitergabe funktioniert bei den Dingern leider 
nicht.
Ich muss aus jedem Byte des Controllers EIN Bit für die LED basteln 
(siehe Datenblatt) Einfach nur 3 Byte ausm Controller in die LED 
schieben geht dämlicherweise nicht :(   ..scheiss Dinger. Ich frag mich 
warum die nicht eine echte SPI implementiert haben, wo man dann selber 
clocken kann und so.
Echt ärgerlich, so als Anfänger, das alles so hinzubasteln wie es 
vielleicht gehen könnte.

von Tom L. (xedux)


Lesenswert?

usuru schrieb:
> nimm die 3 Bytes für die 3 Farben und schiebe sie über die
> SPI-Schnittstelle raus (Din an DATA anschliessen, den CLK einfach
> vergessen)

Du meintest wohl Dout?!

von usuru (Gast)


Lesenswert?

>> nimm die 3 Bytes für die 3 Farben und schiebe sie über die
>> SPI-Schnittstelle raus (Din an DATA anschliessen, den CLK einfach
>> vergessen)
> Du meintest wohl Dout?!

den SDO (Pin 15 des PIC) der SPI-Schnittstelle an Din des WS2812 (Pin 2)

von R. M. (rmax)


Lesenswert?

Zum PIC kann ich nichts sagen, aber mit einem AVR auf 8MHz konnte ich 
einen Strip mit 30 Stück WS2812 problemlos per Bitbanging ansteuern. Das 
einzig Wichtige scheint zu sein, ob die ON-Zeit kleiner oder größer als 
ein gewisser Schwellwert ist. Die OFF-Zeit ist unkritisch, solange man 
nicht in die Nähe der Reset-Zeit kommt.

Für eine 0 hatte ich ein sbi direkt gefolgt von einem cbi (je zwei 
Takte), für eine 1 waren es zwei sbi und ein cbi, das macht eine 
Pulslänge von 250ns für eine 0 und von 500ns für eine 1.

von Michael (Gast)


Lesenswert?


von Ralf (Gast)


Lesenswert?

@Tom L.
> Die "einfache" Datenweitergabe funktioniert bei den Dingern leider
> nicht.
Je nach verwendetem Interface... Ich kenne den PIC nicht. Wenn aber 
beispielsweise der UART die Option hat Start- und Stopbit zu 
deaktivieren biste damit vielleicht besser dran.

> Ich muss aus jedem Byte des Controllers EIN Bit für die LED basteln
Du meinst umgekehrt: Aus jedem Farb-Byte acht SPI-Bytes. Das sollte aber 
doch nicht so schwer sein, oder? Ich hab aber jetzt nicht in deinen Code 
geguckt.

> ..scheiss Dinger. Ich frag mich warum die nicht eine echte SPI
> implementiert haben, wo man dann selber clocken kann und so.
Dann nimm einen WS2801 oder WS2803, da geht das. Und sag bitte nicht, 
dass das ja dann ein externer Chip ist, an den man normale LEDs hängen 
muss.
"Scheiss Dinger" sind das nämlich nicht, ich hab die WS2812 an einem 
8051 per echtem(!) BitBanging (nicht SPI etc.) ans Laufen bekommen.
Bist du fit in Assembler? Dann kommst du vielleicht weiter.

> Echt ärgerlich, so als Anfänger, das alles so hinzubasteln wie es
> vielleicht gehen könnte.
Mach's halt richtig. Ich meine ich hab im Web einen Artikel gelesen, bei 
dem einer die Dinger per SPI auf einem PIC ans laufen brachte. Such mal 
in Youtube nach "LED with integrated WS2811" (nicht WS2812). Wenn ich 
mich recht erinnere, sollte da auch gepostet sein, wie das da gemacht 
wurde.

Ralf

von Ralf (Gast)


Lesenswert?

Nachtrag:
> Kann man auch nur 5 Bits pro Byte senden? bzw. wie mache ich aus meiner
> 8 Bit-Variablen im code ein 5 Bit langes "Byte"?
In dem YT-Link ist auch erklärt, welche Timing-Toleranzen der Chip 
zulässt (steht ja auch im Datenblatt), und welche 8-Bit SPI-Werte dann 
noch funktionieren.

Ralf

von R. M. (rmax)


Lesenswert?

Ralf schrieb:

> Wenn aber beispielsweise der UART die Option hat Start-
> und Stopbit zu deaktivieren biste damit vielleicht besser dran.

Oder den UART-Ausgang (ggf. extern) invertieren, dann kann man Start- 
und Stopbit einfach mitverwenden und bekommt in einem 7n1-Byte des UART 
sogar 3 Bits für den WS2811/12 unter.

von Markus M. (adrock)


Lesenswert?

Tja... das mit dem Protokoll ist so eine Sache. Wie auch immer, Dein 
Programm muss ja im zeitkritischen Teil nur die Bytes aus dem RAM 
protokollgerecht zu den LEDs schicken. In der Pause die danach nötig ist 
berechnest Du dann die neuen Farben etc.

Natürlich brauchst Du pro LED 3 Bytes Speicher.

Die einfachste Methode die ich mir vorstellen kann ist ungefähr so:


Schleife1:
    Hole nächstes Byte aus Speicher in X

    Bitzaehler = 8

Schleife2:
    Schiebe X ein Bit nach links ins Carry
    Wenn Carry gesetzt, springe zu Led_An

    Setze DOUT=1
    <Verzoegerung Bit0_High>
    Setze DOUT=0
    <Verzoegerung Bit0_Low>
    Springe zu Nächstes_Bit

Led_An:
    Setze DOUT=1
    <Verzoegerung Bit1_High>
    Setze DOUT=0
    <Verzoegerung Bit1_Low>

Nächstes_Bit:
    Bitzaehler--
    Wenn Bitzaehler > 0 springe zu Schleife2

    Bytezaehler--
    Wenn Bytezaehler > 0 springe zu Schleife1


PIC Assembler sieht ja dermaßen grausig aus, was bin ich froh AVR zu 
nehmen :-)

Grüße
Markus

von Ollus (Gast)


Lesenswert?

Markus M. schrieb:
> PIC Assembler sieht ja dermaßen grausig aus, was bin ich froh AVR zu
> nehmen :-)

Na bitte, hab ich's nicht gesagt? :-)))
Beitrag "Re: WS2812/2811 mit PIC asm.Verzweiflung!"

von Tom L. (xedux)


Lesenswert?

Danke für die vielen Antworten. Ich hab bereits die LEDs mit 
integriertem Controller.. und zusammen wird das WS2812 genannt.. da is 
der WS2811 drin!
Das mit den Timings ist nicht das Problem, das hab ich verstanden und 
funktioniert auch, siehe erster post. SPI hab ich gestern auf die Reihe 
bekommen, funktioniert auch. Mir war lediglich nicht klar wie ich 
Farbverläufe etc generieren kann, scheint aber alles als Daten im 
Speicher zu liegen, also jede 24-Bitfolge. Heißt also, jeden 
Helligkeitswert für jede Farbe und jede LED ausm Speicher holen und 
rausschieben.

Bzw, irgendeine geloopte Routine schreiben, die zB heller oder dunkler 
fadet.. wie auch immer.

Danke!

von Tom L. (xedux)


Lesenswert?

Markus M. schrieb:
> Tja... das mit dem Protokoll ist so eine Sache. Wie auch immer, Dein
> Programm muss ja im zeitkritischen Teil nur die Bytes aus dem RAM
> protokollgerecht zu den LEDs schicken. In der Pause die danach nötig ist
> berechnest Du dann die neuen Farben etc.

Moin Markus,

genau so funktioniert mein code ja auch, bis auf das "Byteholen", der 
sonstige ablauf entspricht dem was du gesschrieben hast. War ich ja doch 
nciht so auf dem Holzweg. Hab auch gemerkt, dass ich mehr oder weniger 
schon fertig war mit der ausgabe.. also byte laden, in einen Buffer 
schieben (TempShift) und das dann übers carry hiften und je nach dem ob 
carry gesetzt oder nicht, in die Unterroutinen für Bit_HI und Bit_LO 
springen.

Danke

von Markus M. (adrock)


Lesenswert?

Jo... und wie Du schon selbst festgestellt hast, das Faden etc. machst 
Du dann mit einfachen Operationen auf Deine Tabelle mit den RGB-Werten.

Am besten Du schreibst Dir kleine Unterprogramme die die gewünschte 
Funktion auf eine Menge von Werten ausführt. Z.B.

- Verschieben nach links/rechts
- Faden (addieren/abziehen von festen RGB-Werten auf alle Werte im 
Array, am besten noch mit Begrenzung damit kein Überlauf entsteht)
etc.

Evtl. macht es noch Sinn eine Gammakorrektur einzubauen...

Grüße
Markus

von Tom L. (xedux)


Lesenswert?

Markus M. schrieb:
> Evtl. macht es noch Sinn eine Gammakorrektur einzubauen...

HRHR... :D ich hinke ja noch bei der generellen Ingetriebnahme, da 
kannste mir doch nicht mit nem Stabhochsprung à la Gammakorrektur kommen 
:)
Ich werd bei Gelegenheit später mal drüber nachdenken.

Danke!

von Ralf (Gast)


Lesenswert?

Vergiss nicht während der Ausgabe die Interrupts zu sperren! Ansonsten 
verdrückst du dir dein Timing.

Ralf

von Tom L. (xedux)


Lesenswert?

sind bereits disabled :)

von TicTac (Gast)


Lesenswert?


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.