Forum: Compiler & IDEs 96-Bit "Wert" bearbeiten (LED-Laufschrift)


von Sebastian S. (goerk)


Lesenswert?

Gibt es eine Möglichkeit einen 96 Bit integer Wert zu erzeugen, der mit 
Std-Operationen bearbeitet werden kann?

Für eine Zeile einer LED-Laufschrift benötige ich einen 96-Bit Wert.
um in seriell raus zuschieben.


(Einzele Buchstaben haben eine Breite von 5 => in meheren Werten nicht 
gut zu verarbeiten durch "überträge")
Am einfachten wäre das wenn ich einen 96-Bit Datentyp zur verfügung 
hätte.
Dem ist aber nicht so, oder?

vielen Dank im Voraus
Goerk

von Christian S. (aliendrummer)


Lesenswert?

wie kommste denn auf 96 Bit?
würde nicht ein array aus unsigned char gehen, welches die Größe 12 hat?
1
unsigned char wert[12];

von Falk (Gast)


Lesenswert?

@Sebastian S.

>Gibt es eine Möglichkeit einen 96 Bit integer Wert zu erzeugen, der mit
>Std-Operationen bearbeitet werden kann?

Jain. Das sind 12 Byte, ein Array bietet sich hier an.

>Für eine Zeile einer LED-Laufschrift benötige ich einen 96-Bit Wert.
>um in seriell raus zuschieben.

Kein Thema mit einem Array.

MfG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Schnellschuss:

Ev. könnte man mit Bitfeldern da was basteln um das
unangenehme Bitgepfriemel dem Compiler zu überlassen.

Auf der anderen Seite:
Wie schiebst du die Werte 'seriell raus'?
Wenn du das komplett selbst in Software machst, könntest
du ja nach jeweils 5 Bit mit der aktuellen Übertragung
aufhören und dich dem nächsten 'Byte' widmen.

von Sebastian S. (goerk)


Lesenswert?

also eine Zeile des 7 Zeiligen "Displays" hat 96 LED -> 96 Bit
Bsp. 010101010101010101010101...

Das Problem: für ein Zeichen brauche ich 5 Bit  zB: 00001

wenn ich jetzt lauter einzelne Bytes habe muss ich schon beim zweiten 
Zeichen in zwei Bytes schreiben, wobei das etwas umständlich ist die 
ersten 3 Bit ins erste Byte di nächsten zwei ins zweite Byte.

um das zu umgehen wäre es toll einen Datentyp dieser grösse zu haben

von Sebastian S. (goerk)


Lesenswert?

ich würde mit der SPI - schnittstelle die 12Byte rausschreiben, und dazu 
benätige ich immer 8 Bit Blöcke.

mit einem Bit Feld kann man nur eine grösse von 64 Bit erreichen

unsinged long long b :64 ;
da sonst die grösse des zurundeliegenden Datentyps überschritten wird

von Falk (Gast)


Lesenswert?

@Sebastian S.

>also eine Zeile des 7 Zeiligen "Displays" hat 96 LED -> 96 Bit
>Das Problem: für ein Zeichen brauche ich 5 Bit  zB: 00001

96 ist baer nicht durch 5 teilbar. ODer lässt du eifach eine LED weg?

>wenn ich jetzt lauter einzelne Bytes habe muss ich schon beim zweiten
>Zeichen in zwei Bytes schreiben, wobei das etwas umständlich ist die
>ersten 3 Bit ins erste Byte di nächsten zwei ins zweite Byte.
>um das zu umgehen wäre es toll einen Datentyp dieser grösse zu haben

Für dieses Problem gibt es zwei Lösungen.

a) Verwende pro Zeichen ein Byte und lass die obern 3 Bit ungenutzt
   -> einfache Adressierung

b) Schreib dir eine Funktion, der du das Zeichen sowie den Index 
übergibst, welche dann die Bits in mehrere Bytes reinfummelt. Die 
schreibst du nur einmal und kannst dann komfortabel damit arbeiten.

MfG
Falk

von Sebastian S. (goerk)


Lesenswert?

zu a) ist für das rausschreiben etwas ungeschickt

zu b) Ist ne Möglich keit jedoch habe ich mich gefragt ob es nich etwas
      einfacher geht

von Karl H. (kbuchegg)


Lesenswert?

Probier mal

union Zeile {
  struct Digits {
    unsigned char Digit00 : 5;
    unsigned char Digit01 : 5;
    unsigned char Digit02 : 5;
    unsigned char Digit03 : 5;
    unsigned char Digit04 : 5;
    unsigned char Digit05 : 5;
    unsigned char Digit06 : 5;
    unsigned char Digit07 : 5;
  }
  unsigned char Digits[5];
}

Dann übernimmt dir der Compiler das Bit-Gepfiemle.
(Must du natürlich noch auf die tatsächliche
Zeichenzahl erweitern)

von Karl H. (kbuchegg)


Lesenswert?

Sebastian S. wrote:
> zu a) ist für das rausschreiben etwas ungeschickt
>

Kommt drauf an.
Wenn du hardwaremässig rausschreibst (SPI) dann ja.
Bei softwareseitigem schieben ist es egal.

> zu b) Ist ne Möglich keit jedoch habe ich mich gefragt ob es nich etwas
>       einfacher geht

Irgendwer muss das Bitgepfriemel machen.
Entweder du programmierst das selbst oder du versuchst
es dem Compiler mit einem Bitfeld aufzubürden.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

1
union Zeile {
2
  struct Digits {
3
    unsigned char Digit00 : 5;

Eine Frage: ist der Datentyp bei Bitfeldern nicht sowieso auf 'int' 
festgelegt? Mir war jedenfalls so...

von Karl H. (kbuchegg)


Lesenswert?

Patrick Dohmen wrote:
>
1
> union Zeile {
2
>   struct Digits {
3
>     unsigned char Digit00 : 5;
4
>
>
> Eine Frage: ist der Datentyp bei Bitfeldern nicht sowieso auf 'int'
> festgelegt? Mir war jedenfalls so...

Hmm.
Nicht das ich wüsste.
Ob man mit double und float da arbeiten kann, dafür würde
ich meine Hand jetzt nicht ins Feuer legen, aber char, int
long sollten gehen.

Jetzt hast du mich unsicher gemacht :-)


von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger wrote:
> Patrick Dohmen wrote:
>>
1
>> union Zeile {
2
>>   struct Digits {
3
>>     unsigned char Digit00 : 5;
4
>>
>>
>> Eine Frage: ist der Datentyp bei Bitfeldern nicht sowieso auf 'int'
>> festgelegt? Mir war jedenfalls so...
>
> Hmm.
> Nicht das ich wüsste.
> Ob man mit double und float da arbeiten kann, dafür würde
> ich meine Hand jetzt nicht ins Feuer legen, aber char, int
> long sollten gehen.
>
> Jetzt hast du mich unsicher gemacht :-)

Sieht so aus als ob du Recht hast.
Wieder was dazu gelernt.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Ich hatte diese Idee auch, mir ist aber dann diese Datentypsache 
eingefallen.
Das wird dann vermutlich in weiterer Folge noch ganz andere 
unzulänglichkeiten mit sich bringen: die union beinhaltet dann 
vermutlich füllbytes!?

von Karl H. (kbuchegg)


Lesenswert?

Patrick Dohmen wrote:
> Ich hatte diese Idee auch, mir ist aber dann diese Datentypsache
> eingefallen.
> Das wird dann vermutlich in weiterer Folge noch ganz andere
> unzulänglichkeiten mit sich bringen: die union beinhaltet dann
> vermutlich füllbytes!?

Im Allgemeinen: sie könnte.
Im Speziellen auf einem AVR mit gcc: nein

:-)
"Spezielle Paddingbytetheorie", "Allgemeine Paddingbytetheorie"
woran errinert mich das blos?
:-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Es muss ein integer type sein, aber er darf explizit mit einer
Länge angegeben sein.  Diese bestimmt dann die Mindestlänge des
Bitfeldes.  Falls mehr Bits gebraucht werden, darf der Compiler
natürlich auch mehr allozieren.

Das hier müsste so einigermaßen funktionieren, mal vorausgesetzt,
dass man das SPI für "LSB first" eingerichtet hat.  Bei "MSB first"
muss man das Array vom anderen Ende aufdröseln, außerdem werden
dabei die Füllbits noch mit rausgeschoben, um aus dem N*5 ein
M*8 mit ganzzahligem M zu machen.
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
union Zeile {
5
  struct Digits {
6
    uint8_t Digit00 : 5;
7
    uint8_t Digit01 : 5;
8
    uint8_t Digit02 : 5;
9
    uint8_t Digit03 : 5;
10
    uint8_t Digit04 : 5;
11
    uint8_t Digit05 : 5;
12
    uint8_t Digit06 : 5;
13
    uint8_t Digit07 : 5;
14
  } d;
15
  uint8_t Digits[0];
16
} z;
17
18
void
19
shiftout(void)
20
{
21
  uint8_t i;
22
23
  for (i = 0; i < sizeof z / sizeof(uint8_t); i++) {
24
    SPDR = z.Digits[i];
25
    while ((SPSR & _BV(SPIF)) == 0) ;
26
  }
27
}
28
29
int
30
main(void)
31
{
32
  z.d.Digit00 = 0x11;
33
  z.d.Digit01 = 0x02;
34
  z.d.Digit02 = 0x13;
35
  z.d.Digit03 = 0x04;
36
  z.d.Digit04 = 0x15;
37
  z.d.Digit05 = 0x06;
38
  z.d.Digit06 = 0x17;
39
  z.d.Digit07 = 0x08;
40
  shiftout();
41
42
  return 0;
43
}

von goerk (Gast)


Lesenswert?

Das heißt es ist möglich mit der SPI Schnittstelle nur 5 Bit 
rauszuschieben?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nein, du schiebst damit immer nur ganze Vielfache von 8 Bit raus.
Aber ich hatte dich so verstanden, dass du die N Punkte quasi als
ein langes Schieberegister verschaltet hast.

von Sebastian S. (goerk)


Lesenswert?

die 96 Bit sind hardwaremässig als ein schieberegister vorhanden.
und auf dieses will ich sie mit dem SPI rausschieben

von Falk (Gast)


Lesenswert?

@Sebastian S.

>die 96 Bit sind hardwaremässig als ein schieberegister vorhanden.
>und auf dieses will ich sie mit dem SPI rausschieben

Womit nur Version b) übrig beleibt.

MfG
Falk

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Falk wrote:

> Womit nur Version b) übrig beleibt.

Wieso?  96 ist doch durch 8 teilbar.

Außerdem könnte man immer noch eine Mischvariante fahren: N * 8 bit
mit Hardware-SPI, die restlichen M bit dann (langsamer) über
Software-SPI an den gleichen Pins.

von Falk (Gast)


Lesenswert?

@Jörg Wunsch

>> Womit nur Version b) übrig beleibt.

>Wieso?  96 ist doch durch 8 teilbar.

Das hat ja auch keiner bestritten ;-) Es ging doch aber um einen 
einfachen Weg über einen Index die einzelnen Zeichen zu je 5 Bit 
anzusprechen.

Das war meine Version b)

b) Schreib dir eine Funktion, der du das Zeichen sowie den Index
übergibst, welche dann die Bits in mehrere Bytes reinfummelt. Die
schreibst du nur einmal und kannst dann komfortabel damit arbeiten.

MfG
Falk

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klar, diese Funktion kann ein Bitfeld ganz einfach übernehmen. ;-)

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.