96-Bit "Wert" bearbeiten (LED-Laufschrift)

OP #493896
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
Gast #493929
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
#493939
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.
OP #493946
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
Gast #493953
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
#493980
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)
#493982
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.
#493999
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 :-)

#494001
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.
#494004
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?
:-)
Moderator Persönliche Seite #494084
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
}
Gast #496496
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren