www.mikrocontroller.net

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


Autor: Sebastian S. (goerk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian S. (aliendrummer)
Datum:

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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sebastian S. (goerk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sebastian S. (goerk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sebastian S. (goerk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
union Zeile {
  struct Digits {
    unsigned char Digit00 : 5;

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick Dohmen wrote:
>
> union Zeile {
>   struct Digits {
>     unsigned char Digit00 : 5;
> 
>
> 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 :-)


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Patrick Dohmen wrote:
>>
>> union Zeile {
>>   struct Digits {
>>     unsigned char Digit00 : 5;
>> 
>>
>> 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.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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!?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?
:-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
#include <stdint.h>

union Zeile {
  struct Digits {
    uint8_t Digit00 : 5;
    uint8_t Digit01 : 5;
    uint8_t Digit02 : 5;
    uint8_t Digit03 : 5;
    uint8_t Digit04 : 5;
    uint8_t Digit05 : 5;
    uint8_t Digit06 : 5;
    uint8_t Digit07 : 5;
  } d;
  uint8_t Digits[0];
} z;

void
shiftout(void)
{
  uint8_t i;

  for (i = 0; i < sizeof z / sizeof(uint8_t); i++) {
    SPDR = z.Digits[i];
    while ((SPSR & _BV(SPIF)) == 0) ;
  }
}

int
main(void)
{
  z.d.Digit00 = 0x11;
  z.d.Digit01 = 0x02;
  z.d.Digit02 = 0x13;
  z.d.Digit03 = 0x04;
  z.d.Digit04 = 0x15;
  z.d.Digit05 = 0x06;
  z.d.Digit06 = 0x17;
  z.d.Digit07 = 0x08;
  shiftout();

  return 0;
}

Autor: goerk (Gast)
Datum:

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sebastian S. (goerk)
Datum:

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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar, diese Funktion kann ein Bitfeld ganz einfach übernehmen. ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.