3-Kanal SPI?

Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2092
Registered: 03 / 2003
Subject:

3-Kanal SPI?

 · 
Posted: 18.02.2022 - 17:40  ·  #1
Hallo Zusammen,

ich habe RGB-LED-Panele bekommen, in die man über ein Minimal-SPI (nur MOSI und SCK) die Daten rein schiebt. Der Haken: Man muß rot, grün und blau parallel mit einem gemeinsamen Clock übertragen. Also ein 3-Kanal-SPI. Hat das schon mal jemand gemacht oder wenigstens einen Ansatz zur Ausführung für mich?

Gruss
Harry
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1373
Registered: 03 / 2005
Subject:

Re: 3-Kanal SPI?

 · 
Posted: 18.02.2022 - 17:53  ·  #2
I would use 4 pins of a single port - one for the clock and 3 for the channels. It means effectively writing you own 3 channel SPI, but it is not difficult. I don't think you can use built-in SPI drivers.

Fastest would be to leave remaining pins unused, or use a port with only 4 of its pins defined If there is one!).

==============================================================================

Ich würde 4 Pins eines einzigen Ports verwenden - einen für die Uhr und 3 für die Kanäle. Das bedeutet, dass man effektiv einen eigenen 3-Kanal-SPI schreiben muss, aber das ist nicht schwierig. Ich glaube nicht, dass Sie integrierte SPI-Treiber verwenden können.

Am schnellsten wäre es, die restlichen Pins unbenutzt zu lassen oder einen Port mit nur 4 definierten Pins zu verwenden (falls es einen gibt!).

Übersetzt mit www.DeepL.com/Translator (kostenlose Version)
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2092
Registered: 03 / 2003
Subject:

Re: 3-Kanal SPI?

 · 
Posted: 19.02.2022 - 15:41  ·  #3
Danke Merlin, es funktioniert :)
Code

Var
  PClk[@PortB,0]        : Bit;                        // Port Clock
  PR[@PortB,1]          : Bit;                        // Port Daten rot
  PG[@PortB,2]          : Bit;                        // Port Daten grün
  PB[@PortB,3]          : Bit;                        // Port Daten blau


Procedure SPI3K(DR,DG,DB:Byte);  // jeweils 8 Bit RGB senden
  Var Counter : Byte;
  Begin
    PClk:=0;
    //uDelay(1);
    For Counter:=0 to 7 do
      PR:=Bit(DR,Counter);
      PG:=Bit(DG,Counter);
      PB:=Bit(DB,Counter);
      //uDelay(1);
      PClk:=1;
      //uDelay(1);
      PClk:=0;
      //uDelay(1);
      EndFor;
  End SPI3K;


Jetzt muß ich nur noch den LCDGraphic/GraphColor umbauen, daß er mit dem Panel funktioniert.

Gruss
Harry

[Edit]Delays entfernt, nicht notwendig bei Mega644@20MHz
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1373
Registered: 03 / 2005
Subject:

Re: 3-Kanal SPI?

 · 
Posted: 19.02.2022 - 16:02  ·  #4
:zustimm:
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2092
Registered: 03 / 2003
Subject:

Re: 3-Kanal SPI?

 · 
Posted: 19.02.2022 - 20:32  ·  #5
Ich habs :) .... selten ein so beschissen adressiertes Display gesehen.
4 Quadranten, je Quadrant (wenn man es mit einem linear adressierten LCD vergleicht) sind die Bytes so verteilt und alle ungeraden gespiegelt den LEDs zugeordnet:
Code

ein Quadrant mit 16x12 LEDs (hier eine Farbe)
00  02
01  03
04  06
05  07
08  10
09  11
12  14
13  15
16  18
17  19
20  22
21  23

Da das ganze ein recht langes Schieberegister ist, muß man natürlich immer komplett übertragen, und zwar von Byte 23 nach 00 hoch. Dann folgt ein Latch zur Datenübernahme auf die LED-Treiber. 144 16-Bit LED-Treiber sind auf der Platine! Jeder mit einem kleine Kühlkörper.

Gruss
Harry
Attachments
 
Filename: PM.avi
Filesize: 518.85 KB
Title:
Download counter: 15
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2092
Registered: 03 / 2003
Subject:

Re: 3-Kanal SPI?

 · 
Posted: 20.02.2022 - 10:49  ·  #6
Falls es noch jemand interessiert: Ich habe jetzt in der Ausgabe alle (!) Delays raus genommen und das Display funktioniert immer noch problemlos. Betrieben wird das Teil mit einem Mega644@20MHz (wegen der 5V). Der komplette Refresh (288 Byte) dauert 9.5ms.

Das Display wurde mithilfe des Grafiktreibers (LCDGraphic) eingebunden, jedoch funktioniert der normale gDispRefresh nicht.
Die Datenübertragung hab ich ja oben schon gezeigt, der komplette Refresh sieht so aus:
Code

Const
  Matrix                : Array[0..23] of Integer =
                        (  0, 12,  1, 13, 24, 36, 25, 37,
                          48, 60, 49, 61, 72, 84, 73, 85,
                          96,108, 97,109,120,132,121,133);

Procedure chDispRefresh;
  Var QC         : Byte;       // Quadranten-Counter
      BC         : Byte;       // Block-Counter
      Index      : Integer;    // GraphColArr-Index
      IC         : Integer;    // Index-Versatz im Quadrant
  Begin
    For QC:=0 to 3 do
      Case QC of                                      // 4 Quadranten
        0:Adr0:=0; Adr1:=0; IC:=  0;|
        1:Adr0:=1; Adr1:=0; IC:=144;|
        2:Adr0:=0; Adr1:=1; IC:=  2;|
        3:Adr0:=1; Adr1:=1; IC:=146;|
        EndCase;
      For BC:=0 to 23 do
        Index:=Matrix[BC]+IC;
        If Even(BC)
          then
            SPI3K(GraphColArr[Index],
                  GraphColArr[Index+4],
                  GraphColArr[Index+8]);
          else
            SPI3K(Mirror8(GraphColArr[Index]),
                  Mirror8(GraphColArr[Index+4]),
                  Mirror8(GraphColArr[Index+8]));
          EndIf;
        EndFor;
      EndFor;
    Latch:=1;
    Latch:=0;
  End chDispRefresh;


Größe 32x24 RGB-Pixel. Ich habe ein Display mit 96x24 definiert, wobei X:0-31 für rot, 32-63 für grün und 64-95 für blau ist. D.h. wenn ich ein violettes Quadrat mit 32x24 Pixel zeichnen will, muß ich 2 Quadrate mit gDrawRect(0,0,31,23,$FF) und gDrawRect(0+64,0,31+64,23,$FF) zeichnen.
Ich habs mit der Definition von 3 ViewPorts (je einen für rot, grün und blau) versucht, aber da hat sich das ganze seltsam verhalten. Nicht die Ausgabe aufs Display, sondern die Zeichenfunktionen. Vielleicht kann mich ja einer erhellen?

Grob sah das so aus:
Code

Define
  LCDGraphic     = 96, 24, 8;               { x-pix, y-pix, accesswidth        }
  LCDgraphMode   = readonly, iData;
  DefCharSet     = 'Graphchars.pchr';
  GViewports     = 4, iData;                { logical ViewPorts, scalings      }

...
  gOpenView(1, 0,0,31,23);
  gOpenView(2,32,0,63,23);
  gOpenView(3,64,0,95,23);
...
  gSwitchView(1);
  gDrawRect(0,0,31,23,$FF);
  gSwitchView(2);
  gDrawRect(0,0,31,23,$FF);
  gSwitchView(3);
  gDrawRect(0,0,31,23,$FF);

Mein Gedanke war, daß wenn ich den ViewPort umschalte, kann ich mit normalen Koordinaten X:0..31 und Y:0..23 arbeiten, jedoch wurde das ganze Bild gestaucht und verzogen. Muß man zwingend auch gScaleView machen?

Gruss
Harry

PS.: Diese Module nennen sich anscheinend Lighthouse-Module und waren bei Shows/TV/Bühnentechnik im Einsatz und haben wohl auch schon ein paar Jahre aufm Buckel. Ich habe meines hier via PWM (Auflösung 100 Punkte) gedimmt und betreibe es hier mit einem PWM-Wert von 1-2. Bei 20 oder größer ist die Helligkeit nicht auszuhalten :D. Das zugehörige Netzteil ist für 3 Module ausgelegt und liefert 5V/50A!
Hab jetzt auf Hardware-PWM umgestellt mit 8Bit Auflösung :). Jetzt sieht man beim hell/dunkel stellen keinerlei flackern mehr. Frequenz (gemessen) 305Hz.
PS, die 2.: Auch mit einem XMega @ 64MHz läuft das Modul ohne Delays. Pegelanpassung 5V mit 2 74ABT245. Hab jetzt 3 Module zu einem 32x72-Pixel-RGB-LED-Display zusammen geschaltet. Das definierte Grafikdisplay hat 96x72 Pixel und wie gehabt ist X(0..31) rot, X(32..63) grün und X(64..95) blau. Muß mal schaun, ob ich das mit den ViewPorts noch hin bekomme.
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 16 · Cache Hits: 14   107   121 · Page-Gen-Time: 0.032824s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI