Vorstellung 8-Bit Pic treiber für SK6812RBGW

Bitte nutzt dieses Forum um eure eigenen Projekte vorzustellen oder um selbst entwickelten Code zur Verfügung zu stellen.

Vorstellung 8-Bit Pic treiber für SK6812RBGW

#1

Ungelesener Beitrag ÜberDaniel » 5. Dez 2019, 21:00

Guten Abend,

Ich erstelle mir gerade eine Software für einen Treiber-PIC um in Reihe geschaltete SK6812RBGW LEDs anzusteuern.
Hier einmal das Datenblatt: https://cdn-shop.adafruit.com/product-f ... _REV01.pdf

Ich benutze einen PIC 16LF18346, den ich noch von meiner Technikerarbeit übrig habe. Es soll im Endeffekt der Billigste 8-Bit, 32 MHz Pic verwendet werden.

Da der SK6812RBGW ein 800 kHz Datenstrom benötigt, der als High/Low Signal zudem noch in LOW= 0,3us High - 0,9us Low und HIGH= 0,6us High - 0,6us Low als PDM Signal ausgegeben werden soll, was im Worst Case innerhalb von 0,3us auf high und auf low Springen muss. Blieb mir (laut Daten Blatt benötigt der PIC nun Mal 125ns für einen Befehl) nur Assembler Code.

Der Sinn dahinter soll folgender sein:
Ich hab einen PIC den ich per I2C oder Serial ansteuern kann, welchem ich einen Datenstrom schicke, welcher diesen dann an die LEDs weitergibt.
Das Folgende Programm wurde mit einem Logic-Analyzer optimiert um die Zeiten einzuhalten. Leider habe ich noch nicht so viel Erfahrung in Assembler weswegen ich darum bitte mir optimierungsvorschläge zu geben (aktuelleLED = eine Byte einer RBGW LED Einheit, eine RBGW Einheit hat 4 aktuelleLED s, der Ganze zu sendende Datenstrom befindet sich in dem Array LEDs)

Hier ein Codeausschnitt aus dem C Programm, mit ASM Code:

Code: Alles auswählen

    unsigned char aktuelleLED __at(0x20);
    unsigned char LEDS[2];
    unsigned char counter;
    unsigned char ledsMAX = 2;

    counter = 0;
    aktuelleLED = LEDS[0];
    asm("Startpunkt:");
    asm("banksel PORTB");
    if(counter < ledsMAX){
        aktuelleLED = LEDS[counter];
        asm("nop");
    }
    else{
        aktuelleLED = 0;
        counter = 0;
    }
        //------------------------------------------------------------------BIT0
        asm("Bit0:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB ERSTES BIT AUF 0 IST
        asm("btfss 0x20,0");
        //--------------Wenn ja springe zu golow
        asm("goto LOW0");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit1");
        //LOW-ZWEIG 
        asm("LOW0:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit1");
        //------------------------------------------------------------------BIT1
        asm("Bit1:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB ZWEITES BIT AUF 0 IST
        asm("btfss 0x20,1");
        //--------------Wenn ja springe zu golow
        asm("goto LOW1");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit2");
        //LOW-Zweig
        asm("LOW1:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit2");
        //------------------------------------------------------------------BIT2
        asm("Bit2:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB DRITTES BIT AUF 0 IST
        asm("btfss 0x20,2");
        //--------------Wenn ja springe zu golow
        asm("goto LOW2");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit3");
        //LOW-ZWEIG 
        asm("LOW2:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit3");
        //------------------------------------------------------------------BIT3
        asm("Bit3:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB VIERTES BIT AUF 0 IST
        asm("btfss 0x20,3");
        //--------------Wenn ja springe zu golow
        asm("goto LOW3");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit4");
        //LOW-ZWEIG 
        asm("LOW3:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit4");
        //------------------------------------------------------------------BIT4
        asm("Bit4:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB FÜNFTESS BIT AUF 0 IST
        asm("btfss 0x20,4");
        //--------------Wenn ja springe zu golow
        asm("goto LOW4");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit5");
        //LOW-ZWEIG 
        asm("LOW4:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit5");
        //------------------------------------------------------------------BIT5
        asm("Bit5:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB SECHSTES BIT AUF 0 IST
        asm("btfss 0x20,5");
        //--------------Wenn ja springe zu golow
        asm("goto LOW5");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit6");
        //LOW-ZWEIG 
        asm("LOW5:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit6");
        //------------------------------------------------------------------BIT6
        asm("Bit6:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB SIEBTES BIT AUF 0 IST
        asm("btfss 0x20,6");
        //--------------Wenn ja springe zu golow
        asm("goto LOW6");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Bit7");
        //LOW-ZWEIG 
        asm("LOW6:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop"); 
        asm("nop");
        asm("goto Bit7");
        //------------------------------------------------------------------BIT7
        asm("Bit7:");
        //--------------PIN auf HIGH für 600ns
        asm("movlw 0xff");       //125 us
        asm("movwf PORTB");          //125 us
        //--------------TESTE OB ACHTES BIT AUF 0 IST
        asm("btfss 0x20,7");
        //--------------Wenn ja springe zu golow
        asm("goto LOW7");
        //HIGH-Zweig
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Startpunkt");
        //LOW-ZWEIG 
        asm("LOW7:");
        asm("movlw 0x00");       //125 us
        asm("movwf PORTB");          //125 us
        asm("nop");
        asm("nop");
        asm("nop");
        asm("nop");
        asm("goto Startpunkt");
Gruß,
Überdaniel, verächter der Ardunino "Hacker"
Zuletzt geändert von Nico am 6. Dez 2019, 12:21, insgesamt 1-mal geändert.
Grund: Formatierung korrigiert

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#2

Ungelesener Beitrag ÜberDaniel » 5. Dez 2019, 21:19

Ja geil, mein erster Post und kann ihn nicht mehr bearbeiten um ggf. Fehler zu korrigieren. Hier werd ich mich auf jeden Fall öfters aufhalten...

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#3

Ungelesener Beitrag vloki » 5. Dez 2019, 22:35

Solltest du schon bearbeiten können. Bei mir geht das innerhalb einer gewissen Zeit schon. Frag jetzt nicht wie lange...

Sind das ws2812 kompatible LEDs?
Dann ist das Timing nicht wirklich so kritisch wie man auf den ersten Blick denken sollte. Das geht auch mit 16MHz und in C, wenn man weiß, was man tut und darf ;-)

<Edith 5min>
<10min später>

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#4

Ungelesener Beitrag vloki » 5. Dez 2019, 22:54

Nach 16min kann ich nicht mehr bearbeiten.

Alter Thread zu PIC 16MHz und WS2812:
https://www.mikrocontroller.net/topic/322375#5874504

Wirklich kritisch ist wohl nur die Zeit für die High-Pegel des Datenstroms. Beschreibung dazu gibt es auch in meinem uCQuick Skript...

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#5

Ungelesener Beitrag ÜberDaniel » 5. Dez 2019, 23:25

Es funktioniert ja bisher, gibt es ein vereinfachte Form die Bits in einer Schleifen abzufragen also unnötigerweise für alle 8 bits des selben Code zu duplizieren?
Was mich gerade noch beschäftigt ist diese Zeile: asm("btfss 0x20,6");.
Gibt es da einen weg das abzufragende Bit mit einer Schleife zu durchlaufen?
Gruß

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#6

Ungelesener Beitrag vloki » 6. Dez 2019, 09:58

Nein. Wenn das in einer Schleife gemacht werden soll, dann muss es immer das gleiche Bit sein. Das könnte man dadurch erreichen, dass man das Byte vorher shiftet...

Die neuen PIC16 Haber aber auch oft HW integriert, die das ganze wesentlich vereinfachen können. Wenn ich mich richtig erinnere, dann gibt es dazu eine AN von MCHP.

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#7

Ungelesener Beitrag vloki » 6. Dez 2019, 11:00

Anscheinend gibt es sogar zwei Application Notes, die sich mit dem Thema befassen.
AN1890 und AN1606. CLC hat dein PIC ja auch...

Meine ersten Versuche waren auch in Assembler und haben vermutlich so ähnlich ausgeschaut, wie dein Entwurf.
Dann wollte ich das in C nachbilden und habe festgestellt, dass es hauptsächlich auf die Zeiten der High-Pegel ankkommt.
Das Timing wirklich korrekt einzuhalten wäre ansonsten in C ohne sehr hohe Taktfrequenzen nicht möglich.

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#8

Ungelesener Beitrag Nico » 6. Dez 2019, 12:34

Bearbeitet werden kann ein Beitrag bis 15 Minuten nachdem er erstellt wurde :-)

Der Button im Editor mit den beiden spitzen Klammern (Button <> erzeugt [c][/c]) ist für Inline-Code, genau wie eben gerade benutzt. Der zweite Button weiter links (Button </> erzeugt [code][/code]) wird benutzt um mehrere Zeilen Code in eine Box zu packen.

Gruß Nico

Re: Vorstellung 8-Bit Pic treiber für SK6812RBGW

#9

Ungelesener Beitrag ÜberDaniel » 13. Dez 2019, 13:35

Danke für die ganzen Tipps,
werde mich nun an die AN1890 halten, da ich das ebenfalls so ähnlich mit dem PIC-RAM vorhatte, nur jetzt eben mit mehr RAM = mehr LEDs. Denke die AN1890 sollte mit 800 kHz und den SK6812RBGW LEDs ebenfalls machbar sein. Das 23LC102 SRAM ist eben angekommen, werde das demnächst mal aufbauen :)

Gruß

Antworten
  • Vergleichbare Themen
    Antworten
    Zugriffe
    Letzter Beitrag

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast