alle byte.x von 8 bytes in ein neues byte zusammen fassen, gibt es dazu einen Trick?

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • alle byte.x von 8 bytes in ein neues byte zusammen fassen, gibt es dazu einen Trick?

      Wenn ich 8 bytes habe, wie kann ich die einzelnen bits zu wieder 8 bytes zusammen fassen?
      Wenn ich als Ausgang ein array(8) as byte habe, wäre zB. als erstes byte des Ergebnis(8): (base=0)
      Ergebnis(7).7=array(7).7
      Ergebnis(7).6=array(6).7
      Ergebnis(7).5=array(5).7...
      Geht natürlich mit einer Schleife, in der ich jedes bit x von den 8 bytes nehme und daraus die neuen bytes zusammen stecke. Das wäre dann 64 x bit-kopieren.
      Oder gibt es da einen Trick?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Trexis5 wrote:

      wie wäre es mit 8 byte die als Overlay drüberlegen?
      Ein byte über ein byte legen bringt nur einen zusätzlichen Namen für ein byte, aber sonst ändert sich nix.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Was spricht denn dagegen, das mit FOR-Schleifen zu machen? Wie Du schon schreibst, ist das ja die natürlichste Art. Der Mikrocontroller freut sich ja, wenn er etwas sinnvolles tun kann. Wenn es im Hauptprogramm schöner (für Dich) aussehen kann, dann schreibst Du es als Unterprogramm/Funktion.
      Und bevor das jetzt wieder jemand als Assembler implementieren möchte, schreib doch bitte, ob es Dir um das Prinzip geht oder um eine WS2812-Anwendung, die schon mit 16MHz läuft und es auf Geschwindigkeit ankommt.
    • @stefanhamburg es geht mir darum, ob ich einen Trick übersehe, der das Problem einfacher lösen würde. Geschwindigkeit ist aber auch nie verkehrt.
      Konkret kommt die Problemstellung bei mir hier vor:
      Ledmatrix mit 32x64 RGB-Leds. Bei solchen Matrixen sind immer 8 Leds mit einem byte anzusteuern. Diese 8 Leds liegen pysikalisch nebeneinander. Ich nenne das jetzt 'liegende bytes'. Die fonts, die ich gerne verwende, sind mit 'stehenden bytes' organisiert, bei einem 6x8 font ist ein Zeichen 1 byte hoch und 6 bytes stehen nebeneinander. Fonts, die liegende bytes verwenden, gefallen mir optisch nicht und brauchen viel Platz in der Länge für wenig Buchstaben. Um jetzt ein Zeichen auf dem display anzuzeigen, muss ich die stehenden bytes in die liegenden bytes kopieren. Das mach ich jetzt schon mit Schleifen, weil mir ja nix besseres eingefallen ist. Wenn ich jetzt das Zeichen horizontal verschieben möchte, ist das relativ einfach mit shift die bits der liegenden bytes zu verschieben. Wenn ich allerdings das Zeichen nach oben, oder unten verschieben will, wird's doch aufwändiger. Da das Zeichen bei 6x8 nur 6 bits eines liegenden bytes belegt, bzw diese 6 bits auch auf 2 nebeneinander liegenden bytes verteilt sein können, muss ich zum Verschieben diese bits einzeln anfassen und in das byte drüber oder drunter kopieren. Mein Gedanke war jetzt das Zeichen in einen Hilfsspeicher mit stehenden bytes zu schreiben. Jetzt kann dieser Hilfsspeicher mit shift bequem nach oben/unten verschoben werden (die bits darin natürlich) und ich könnte nach jedem Verschieden diesen Hilfsspeicher in das display kopieren. Aber das ist auch wieder das Kopieren von stehenden bytes in liegende. :huh:
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ganz konkret, die fonts sind aus stehenden bytes zusammengesetzt. Das 1. byte eines Zeichens bildet die linke Kante des Zeichens. Bei einem doppelt so hohen font bilden die ersten beiden bytes die linke Kante des Zeichens. Wenn ich das Zeichen jetzt auf das display bringen will, bzw in den Bildspeicher, der dann an das display geschickt wird, muß ich alle bits des bytes der linken Kante in bits des Bildspeichers kopieren. Und diese bits des Bildspeichers haben alle die gleiche Nummer.
      Momentan nehme ich also ein byte aus der data-Tabelle des fonts und verteile die bits auf die bits der 8 bytes im Bildspeicher.
      Wollerte ich liegend einlesen, müsste ich ja 8x ein byte vom font holen und davon jeweils nur ein bit verwenden, um ein byte des Bildspeichers zu füllen. Das erscheint mir doch aufwändiger, zumal die Verteilung der 8 bits auch über eine byte-Grenze hinweg erfolgen kann.
      Es bleibt mein Problem mit dem vertikalen Verschieben eines Zeichens weiterhin.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hier mal ein Bildchen zum Verdeutlichen. Das große Rechteck bildet den Bildspeicher ab, der byteweise zum display übertragen wird. Das sind die 'liegenden bytes'. Das gelbe Rechteck ist der Platz für ein Zeichen aus dem 6x8 font, 6 'stehende bytes'.
      Bildspeicher 32x64.PNG
      Um das Zeichen in den Bildspeicher zu übertragen müssen die 48 bits vom Zeichen in 16 bytes des Bildspeicher kopiert werden.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo @tschoeatsch
      Du meinst, dein dein Display ist zeilenorientiert, dein Zeichensatz aber in Spalten.

      Wenn du angenommen einen Font mit 128 Zeichen speicherst, dann brauchst du bei einem 6x8 Font 6x128 Byte. Und dann ist er so gespeichert wie du ihn vorliegen hast.

      Im Vergleich, wenn du den Font drehst und somit als 8x8 Font vorliegen hast, von dem du aber nur 6 Spalten verwendest, dann brauchst du 8x128 Byte.

      Die Differenz sind 8x128 - 6x128 = 256 Byte Flash.

      Wenn du deinen Code mit Schleife umstrickst, brauchst du vermutlich mehr als 256 Byte Code und dein Programm ist zudem deutlich langsamer.

      Den Trick den du suchst gibts vielleicht nicht. Aber es erinnert mich an eine Bitmap drehen. Was da für ein Algorythmus zu Grunde liegt weiß ich nicht.

      Wenn du aber etwas mehr Flash opferst, dann kannst du den Zeichensatz auch besser shiften.

      Es ist eine Abwägungssache, was einem wichtiger ist.

      Eine solche Routine, um den Font zu drehen, würde ich in Assembler machen, da es einfacher zu drehen ist, es ist schneller gedreht und braucht weniger Platzsparender (Code).
      Kaum macht man es richtig - und schon geht's!
    • Ich hab mir das mal durch den Kopf gehen lassen.
      Das kam dabei raus:

      BASCOM Source Code

      1. $Regfile = "m8def.dat"
      2. $Crystal = 1000000
      3. Config Base = 0
      4. Config Submode = New
      5. ' In diesem Array liegen die ungedrehten Font-Daten eines Zeichens
      6. Dim ZeichenSource(6) as Byte ' Quell-Array
      7. ' Hier werden die gedrehten Fontdaten rein geschrieben
      8. Dim ZeichenDest(8) as Byte ' Ziel-Array
      9. Sub RotateChar()
      10. LoadAdr ZeichenDest() , x ' Ziel-Array
      11. LoadAdr ZeichenSource() , z ' Quell-Array
      12. $ASM
      13. LD r23,z+ ' 6 Byte Fontdaten laden
      14. LD r22,z+
      15. LD r21,z+
      16. LD r20,z+
      17. LD r19,z+
      18. LD r18,z
      19. LDI r16,8 ' Ziel-Array ist 8 Byte groß
      20. _rotateCharLoop:
      21. CLR r24
      22. LSR r18 ' Hier werden die Bits verschoben
      23. ROR r24
      24. LSR r19
      25. ROR r24
      26. LSR r20
      27. ROR r24
      28. LSR r21
      29. ROR r24
      30. LSR r22
      31. ROR r24
      32. LSR r23
      33. ROR r24
      34. ST x+,r24 ' Zusammen-gesetztes Byte in Ziel-Array schreiben
      35. DEC r16
      36. BRNE _rotateCharLoop
      37. $END ASM
      38. End Sub
      39. Do
      40. Call RotateChar() ' Zeichen drehen
      41. Loop
      Display All
      Probiers mal aus, ob das richtig gedreht wird.
      Evtl. muss man die Einlese-Reihenfolge verdrehen (Zeile 18 - 22).
      Kannst ja Bericht erstatten, ob es geklappt hat.
      Kaum macht man es richtig - und schon geht's!
    • Mitch64 wrote:

      Wenn du angenommen einen Font mit 128 Zeichen speicherst, dann brauchst du bei einem 6x8 Font 6x128 Byte. Und dann ist er so gespeichert wie du ihn vorliegen hast.

      Im Vergleich, wenn du den Font drehst und somit als 8x8 Font vorliegen hast, von dem du aber nur 6 Spalten verwendest, dann brauchst du 8x128 Byte.

      Die Differenz sind 8x128 - 6x128 = 256 Byte Flash.
      Wenn ich meine Zeichen, die in 6x8 'senkrecht' rein passen in 8x8 'waagrecht' ablege und nur 6 bits von den bytes verwende, bringt mich das auch nicht weiter, weil die einzelnen Zeichen auch nicht genau innerhalb eines bytes im Bildspeicher landen. Abgesehen davon, dass man den Text pixelgenau positionieren können soll, sollen können, ach, weißt schon.

      Pluto25 wrote:

      Ein liegenden Font erstellen erscheint mir am einfachsten. Das vertikal scrollen geht dann Byteweise und horizontal bitweise wie bisher sowieso
      der hat so ein quadratisches Format, was mir optisch garnicht gefällt und außerdem viel Länge macht mit wenig Zeichen. Sollte man so einen Text in x-Richtung beliebig auf dem display setzen können, zack, ist man wieder bei angeschnittenen bytes für einzelne Zeichen. Man hat also zusätzliche Einschränkungen in den Positionierung, oder man hat wieder das Problem beim vertikal-scrollen.

      Mitch64 wrote:

      Ich hab mir das mal durch den Kopf gehen lassen.
      Das kam dabei raus
      danke, für deine Denkarbeit, bei einem 10x16 oder 12x16 font, die ich auch verwende, wird's dann mit den Registern knapp.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hm, eigentlich ist mein Thema nicht ganz richtig, es müsste gerade mehr:
      'wie verteile ich ein byte auf die gleichnamigen bits von 8 bytes? Gibt es neben der Möglichkeit mit bitweiser Verteilung innerhalb von Schleifen auch einen Trick, der das eleganter erledigt?' heißen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Wenn du die Bytes mit deinen Arrays drehst wird es auch kein volles Byte ergeben.
      Da sind dann auch nur die oberen 6 oder unteren 6 mit Font-Pixeldaten belegt (je Zeile).
      Ein 6x8Font ist eben nur 6 Pixel breit. Egal wie der im Speicher liegt.

      Bei einem 12x8Font musst du eben 12 Bits (2 Byte) in X-Richtung bereit stellen, um eine Zeile abzubilden.
      Wie viele Bits dann von dem Byte oder den 2 ausgegeben werden ist dann ein anderes Thema.
      Damit die Abstände der einzelnen Chars auf dem Display nur z.B. 1 Pixel ist, musst du vor der Ausgabe der Zeichen die Position sowieso korrigieren. Das macht normalerweise der Display-Treiber.

      Wenn nicht, musst du die Display-Bytes erst in einen Buffer (2.B. 2 Byte) lesen, da wo das neue Zeichen hin soll Bits ausmaskieren und das neue Zeichen dort per OR-Verknüpfung einfügen. Dann wieder die 2 Bytes ins Display schreiben.
      Kaum macht man es richtig - und schon geht's!
    • @Mitch64 diese ganze Maskiererei hab' ich eben nicht, wenn ich meine spaltenorientierten fonts verwende.
      Inzwischen kann ich mir auch keine andere/bessere Lösung für mein Problem vorstellen, als das bitweise Umeinanderkopieren.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • tschoeatsch wrote:

      Gibt es neben der Möglichkeit mit bitweiser Verteilung innerhalb von Schleifen auch einen Trick, der das eleganter erledigt?'
      Schieben ist vermutlich schneller. Zumal sowieso schon eine Routine besteht fürs horizontale Scrollen.Und da könnte das neue Zeichen gleich bei liegendem Font oder nach dem Drehen (da scheint mir Mitch64's Vorlage flash-ideal) mit reinkommen. Die Bit breite/höhe muß ja immer berücksichtigt werden.



      Das Grün a_45_132ca9f5
    • @Pluto25 wie kann ich die betreffenden bits des Bildspeichers, die im gelben Feld der Skizze liegen, vertikal verschieben? Ist sehr nur die Möglichkeit des Umkopierens und das bitweise.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Nur dieses Zeichen? Byte 40.7-2 müssen erhalten bleiben /sind nicht leer? Liegt ein Abbild des Bildspeichers im Flash?
      Was ist mit dem darüber/darunterliegendem (byte 33.1-0,Byte1.1-0 muß gesichert werden? z.B. beim hochschieben.
      Was würde von unten reinkommen?
      Angenommen ein neues Zeichen soll an Pos Byte33.1 beginnen:

      Source Code

      1. b=0
      2. pos=33
      3. bitpos=2
      4. fontbreite=6
      5. do
      6. firstloop=0
      7. temp=fontbyte(b)
      8. For a= pos to pos+64 step 8
      9. if firstloop=0 then shift Byte(a),right,bitpos
      10. shift Byte(a),left,1
      11. if temp>127 then incr byte(a)
      12. shift temp, left ,1
      13. next
      14. if b=bitpos then
      15. incr pos
      16. bitpos=8
      17. firstloop=0
      18. end if
      19. incr b
      20. loop until b> fontbreite
      Display All
      so vielleicht?
    • @Pluto25 schaut ja interessant aus. Ich muss erst noch das vor mir liegende display zum Laufen bringen, dann probier' ich das mal aus.
      Es soll wie ein mechanisches Zählwerk aussehen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • In dem fall muß es nicht horizontal geschoben werden. Wie wärs mit einem 12x8 Font idealerweise liegend das erspart die ganze Bitschieberei.
      Ps nicht den "mechanischen Fehler" vergessen; ;)

      Source Code

      1. $regfile = "attiny13a.dat"
      2. $crystal = 128000
      3. $hwstack = 4
      4. $swstack = 4
      5. $framesize = 4
      6. Deflcdchar 0 , 17 , 17 , 14 , 17 , 17 , 14 , 32 , 14
      7. Cls
      8. Lcd "2488"
      9. Locate 2 , 1
      10. Lcd "24"
      11. Lcd Chr(0)
      12. Lcd "9"
      13. End
      Display All
      :D