Hallo Zusammen,
ich benötige mal etwas Gedankenunterstüzung.
Um auf die Kontrollstrukturen des TLC5951 zugreifen zu können, in diesem
Fall des Grayscale-Controller, möchte ich folgende Definition vornehmen:
1 | #define NUMBERS_OF_TLC5951 4
| 2 | #define NUMBERS_OF_LED_PER_TLC5951 24
| 3 | #define NUMBERS_OF_BITS_PER_LEDS 12
| 4 | #define NUMBERS_OF_TLC5951_GSSIN_BYTE 36
| 5 | #define NUMBERS_OF_TLC5951_DCSIN_BYTE 27
| 6 | #define NUMBERS_OF_LEDS NUMBERS_OF_TLC5951 * NUMBERS_OF_LED_PER_TLC5951
| 7 |
| 8 | typedef struct
| 9 | {
| 10 | unsigned bit01:1;
| 11 | unsigned bit02:1;
| 12 | unsigned bit03:1;
| 13 | unsigned bit04:1;
| 14 | unsigned bit05:1;
| 15 | unsigned bit06:1;
| 16 | unsigned bit07:1;
| 17 | unsigned bit08:1;
| 18 | unsigned bit09:1;
| 19 | unsigned bit10:1;
| 20 | unsigned bit11:1;
| 21 | unsigned bit12:1;
| 22 | }rgb_led_struc;
| 23 |
| 24 | typedef union
| 25 | {
| 26 | rgb_led_struc gssin_led[ NUMBERS_OF_TLC5951 * NUMBERS_OF_LED_PER_TLC5951 ];
| 27 | uint8_t gssin[ ( NUMBERS_OF_TLC5951 * NUMBERS_OF_LED_PER_TLC5951 * NUMBERS_OF_BITS_PER_LED ) / 8 ];
| 28 | } rgb_leds;
|
Leider musste ich feststellen, dass die beiden Strukturen nicht gleich
groß sind, was im nachhinein natürlich klar ist, da meine Struktur
rgb_led_struc leider mit 16 Bit im Speicher abgelegt wird.
Sinn des Unions sollte sein, dass ich später in der SPI-Routine einfach
nur über das gssin interieren muss, um die Daten zu übergeben.
Jetzt stellt sich mir die Frage, kann ich den GCC irgendwie dazu
überreden, das Array gssin_led anders anzuordnen, sodass beide
Strukturen gleich groß sind? Oder muss ich mein Array gssin an die Größe
von gssin_led anpassen und in der SPI-Routine immer nur die 12 Bits
ausgeben?
Gruß
Frank
Frank Link schrieb:
> Jetzt stellt sich mir die Frage, kann ich den GCC irgendwie dazu
> überreden, das Array gssin_led anders anzuordnen, sodass beide
> Strukturen gleich groß sind?
Gar nicht.
Die kleinste Einheit in C ist ein Byte. 8 Bit
Du hast keine VIelfachen von 8 Bit
> Oder muss ich mein Array gssin an die Größe
> von gssin_led anpassen und in der SPI-Routine immer nur die 12 Bits
> ausgeben?
Du kannst du Dinge ja selbst in die Hand nehmen und dir
Zugriffssfunktionen schreiben, die dir einen 12-Bit Wert in einem
Byte-Array ablegen, wobei du die LEd Nummer als Index nimmst. Dann
kannst du, so wie du das vorhattest, einfach das Byte Array an die TLC
rausschieben.
So schwer ist das nicht.
Du könntest maximal deine Strukturen so aufblasen, dass du in einer
struct immer 2 LED beschreibst. Das sind dann 24 Bit oder eben 3
komplette Byte. Aber um die Zugriffsfunktionen kommst du auch so nicht
herum. Lediglich das Bitschubsen würde dir der Compiler abnehmen. Das
Bitschubsen ist aber ziemlich trivial, wenn man erkannt hat, dass es nur
2 verschiedene Ausrichtungen der 12 Bit gibt.
Hallo Karl Heinz,
danke für die Antwort, ich hab mir schon sowas gedacht. Leider benötige
ich in den LOW-Level Routinen den direkten Zugriff auf ein einzelnes
LED.
Wobei ich dann auf rgb_led_struc verzichten kann und an dieser Stelle
ein Integer definiere. Auch wenn ich dabei einiges an Speicher
verschwende.
Danke nochmals und Gruß
Frank
Frank Link schrieb:
> Hallo Karl Heinz,
> danke für die Antwort, ich hab mir schon sowas gedacht. Leider benötige
> ich in den LOW-Level Routinen den direkten Zugriff auf ein einzelnes
> LED.
Wozu?
Du musst pro LED 12 Bit raustakten.
Jeweils 2 LED kannst du daher leicht in 3 Bytes unterbringen, so dass du
dir beim raustakten keine Gedanken mehr um die logische Aufteilung der
Bits in 12-er Einheiten machen musst.
> Wobei ich dann auf rgb_led_struc verzichten kann und an dieser Stelle
> ein Integer definiere.
Wozu?
Zu faul sich die Situation mal aufzumalen und auszuknobeln, welches
Nibble wie gespeichert werden muss, wenn
a) die Led Nummer gerade
b) die Led Nummer ungerade
ist?
Du organisierst deinen Bytespeicher als 3 Byte Blöcke. Die Led mit der
Nummer n wird im Block mit der Nummer n/2 gespeichert (der am Index n/2
* 3 im Byte Array beginnt und 3 Bytes lang ist)
(Ansicht eines Blockes in Nibble)
| Byte 0 | Byte 1 | Byte 2 |
+------+------+------+------+------+------+
| | | | | | |
+------+------+------+------+------+------+
ist die Led Nummer gerade, dann werden die 12 Bits in diese 3 Nibbles
des jeweiligen Blocks gespeichert
| Byte 0 | Byte 1 | Byte 2 |
+------+------+------+------+------+------+
| #### | #### | #### | | | |
+------+------+------+------+------+------+
ist die Led Nummer ungerade, dann sind diese 3 Nibble des Blocks für die
12 Bit zuständig
| Byte 0 | Byte 1 | Byte 2 |
+------+------+------+------+------+------+
| | | | #### | #### | #### |
+------+------+------+------+------+------+
und das wars dann auch schon. Das ist die ganze Idee. Der Rest ist dann
nur noch Handwerk: Bits zurechtschieben und mit jeweils einem Byte aus
dem Block verunden/verodern, wobei nur das mittlere der 3 Bytes eine
Sonderbehandlung braucht, weil von diesem Byte die beiden Nibble zu
anderen Led gehören. Die Behandlung ist aber reichlich trivial.
Ach ja: Eines hab ich vergessen. Man muss natürlich darauf achten, dass
die Bits dann schon in der richtigen Reihenfolge sind (MSB / LSB) damit
sie beim raustakten auf den TLC dann auch in der richtigen Reihenfolge
rauskommen. Aber auch das lässt sich lösen, wenn man sich das alles mal
aufmalt und durchüberlegt.
Hallo Karl Heinz,
danke für Deinen Lösungsvorschlag, es hat aber erstmal nichts mit
Faulheit zu tun, dass ich diese Version nicht verwende, sondern damit,
dass ich mich auf die von mir beschriebene Struktur eingeschossen hatte.
Unabhängig von Deiner Idee bin ich jetzt auf folgende Vorgehensweise
gekommen und möchte die mal zur Diskussion stellen.
Geplant sind 4 x TLC5951 mit jeweils 8 RGLB-Leds = 24 x 4 Einzelleds.
Ich benötige insgesamt 288 Bit Gray Scale Shift Register = 36 Byte pro
Controller + 216 Bit DC/BC/FC/UD Shift Register = 27 Byte pro Controller
also insgesamt 63 Byte pro Controller = 252 Byte für die gesamte
Ansteuerung.
Von diesen 252 Bytes kann ich 4 * 6 Bytes Kontrollinformationen für die
Controller abziehen, da diese für alle Controller gleich sein sollen und
damit in einer eigenen Struktur von 6 Byte liegen. Ich würde damit also
232 Byte für die Kontrollinformationen Gray Scale und Dot Correction für
alle LEDs benötigen. Wenn ich alles linear ablegen könnte. Das geht aber
leider nicht, da ich 12 Bit Gray Scale und 7 Bit Dot Correction habe
also zusammen 19 Bit (wer sich das hat einfallen lassen, sollte
erschossen werden).
Da ich aber noch 3 Statusinformationen aus dem Controller pro LED
ablegen will, kommen also noch 3 x 24 x 4 Bit = 36 Byte hinzu.
Macht in Summe 268 Byte.
Meine Lösung sieht jetzt so aus:
Jedes LED wird mit 3 Byte beschrieben. Dabei sind die ersten 12 Bit der
Gray Scale, dann folgen 7 Bit für die Dot Correction, verbleiben zur
Zeit noch 5 Bit, in 3 von diesen 5 Bit werden die Statusinformationen,
die der Chip mir liefert abgelegt, um auf Fehler reagieren zu können.
Verbleiben zur Zeit 2 Bit je LED ohne Nutzung.
Somit komme ich auf insgesamt 3 24 4 = 288 Byte für die gesamte
Anwendung. Ich würde also insgesamt 24 Byte ungenutzt im Speicher liegen
haben.
Hat jemand noch eine andere Idee hierzu, wobei die Rahmenbedinungen
erhalten bleiben sollten. Mir ist auch bewußt, dass die Daten für das
Gray Scale Shift Register in einer anderen Reihenfolge ausgegeben werden
müssen, als die für das DC/BC/FC/UD Shift Register. Aber das ist die
Aufgabe der SPI-Funktionen und nicht die Aufgabe der Datenstrukturen.
Gruß
Frank
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|