-         
Ergebnis 1 bis 3 von 3

Thema: Bytes parallel ausgeben - Bitmatrix drehen.

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.12.2018
    Beiträge
    362

    Bytes parallel ausgeben - Bitmatrix drehen.

    Anzeige

    Hallo!
    Weiß jemand eine effiziente Methode, wie man die jeweils parallelen Bits der jeweils gleichen Stelle von 8 Bytes in ein Byte schreiben kann, um sie dann parallel in einen GPIO-Port zu schreiben? Es geht um die parallele Übertragung von 8 Bytes über 8 serielle GPIO outputs (nicht UART, sondern einfach GPIO Outputs - es geht mir hier auch nicht um Timings oder sowas... es geht sozusagen um das Drehen der Bitmatrix.)

    Also 8 Bytes, z,B.
    11111000
    11111000
    00000111
    00000111
    00000000
    00000001
    00000010
    00000011

    Ergibt für das erste Byte 00110101 -> damit werden sozusagen die 8 jeweils ersten Bits der 8 Ausgangsbytes zu einem Byte zusammengefasst und können parallel gesendet werden.
    Ergibt für das erste Byte 00110011
    Ergibt für das erste Byte 11000000
    Ergibt für das erste Byte 11000000
    usw. Die Matrix ist dann quasi gedreht oder transformiert.

    Spontan würden mir nur Bitoperatoren einfallen.
    - Erst alle Bytes mit der Position XORen
    - Dann jeweils an die richtige Stelle schieben und mit OR ins Zielbyte kopieren.

    OutByte = 0
    OutByte = OutByte | (byte1 & 1 << i) << 0
    OutByte = OutByte | (byte2 & 1 << i) << 1
    OutByte = OutByte | (byte3 & 1 << i) << 2

    Für i = 0 bis 7... erscheinen mir da etwas aufwändig. Gibts eine effizientere Lösung.
    Wenns Hilfreich ist, könnte man auch 8 Output Bytes erstellen und dann erst ausgeben.

    Erstmal würde mich eine generelle Lösung interessieren (für Tests auf einem Arduino/328P).
    Am Ende will ich das mit 32-Bit-Werten in einem ESP32 machen. Wie sieht es da aus? Bietet der was handliches dafür.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.518
    Blog-Einträge
    29
    Hallo,

    wenn Du Bytes aus Bits, anderer Bytes, zusammensetzen willst, bleiben nur Bitoperatoren.

    Vorschlag:

    Code:
    Byte = (B1&1) | ((B2&1)<<1) | ((B3&1)<<2) | ((B4&1)<<3)  | ((B5&1)<<4)  | ((B6&1)<<5)  | ((B7&1)<<6)  | ((B8&1)<<7);
    Bei solchen Sachen tendiere ich dazu, keine Schleife zu bauen, da dies zusätzliche Zeit kostet (Auswertung der Schleifenbedingung und Rücksprung an den Anfang).
    Da nehme ich lieber etwas mehr Bytes an Code in Kauf, aber der wird schnell abgearbeitet.


    MfG

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.12.2018
    Beiträge
    362
    Hab nach einigem Googeln was Gutes dazu gefunden...
    Beispielcode wesentlich aus dem Kapitel "Transposing a Bit Matrix"
    Warren Jr., Henry S. (2013). Hacker's Delight (2 ed.).
    Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8

    Code:
    #include <stdio.h>
    
    #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
    #define BYTE_TO_BINARY(byte)  \
      (byte & 0x80 ? '1' : '0'), \
      (byte & 0x40 ? '1' : '0'), \
      (byte & 0x20 ? '1' : '0'), \
      (byte & 0x10 ? '1' : '0'), \
      (byte & 0x08 ? '1' : '0'), \
      (byte & 0x04 ? '1' : '0'), \
      (byte & 0x02 ? '1' : '0'), \
      (byte & 0x01 ? '1' : '0') 
    
    int main(void)
    {
        unsigned char A[8] = {0xf8, 0xf8, 0x07, 0x07, 0x00, 0x01, 0x02, 0x03};  //Array mit Ausgangsbytes
        int m = 1;
        int n = 1;
        unsigned char B[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  //Array für Ergebnisbytes
        unsigned x, y, t;
    
        for (int i = 0; i < 8; i++) {
            printf("Ausgangsbytes "BYTE_TO_BINARY_PATTERN"\n", BYTE_TO_BINARY(A[i]));
        }
        printf("\n");
        
        // ********* Hier der eigenliche Code **********
    
        x = (A[0]<<24)   | (A[m]<<16)   | (A[2*m]<<8) | A[3*m];
        y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m];
    
        t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
        t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
    
        t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
        t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
    
        t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
        y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
        x = t; 
    
        B[0]=x>>24;   B[n]=x>>16;   B[2*n]=x>>8; B[3*n]=x;
        B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y;    
        
        // *********           Ende           **********
    
        for (int i = 0; i < 8; i++) {
            printf("Ergebnisbytes "BYTE_TO_BINARY_PATTERN"\n", BYTE_TO_BINARY(B[i])); 
        }  
        
        return 0;
    }
    Wird auf einem RISC-Prozessor laut der Quelle in 101 Prozessorinstruktionen ausgeführt.

    Trotzdem stell ich mir vor, dass sowas nicht selten gebraucht wird. Mit ein paar zusammengeschalteten Latches könnte man das doch wahrscheinlich in wenigen, vielleicht sogar in einem Taktzyklus erledigen. Kennt jemand Prozessoren, die sowas machen?
    Geändert von Gnom67 (01.10.2020 um 01:34 Uhr)

Ähnliche Themen

  1. Bytes nur zum Teil auslesen
    Von BEADG im Forum Arduino -Plattform
    Antworten: 4
    Letzter Beitrag: 23.10.2013, 15:00
  2. Ein Single aus zwei Bytes
    Von Bratwurst im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 21.02.2006, 16:19
  3. Maximale bytes fur Robby?
    Von DuneAgent im Forum Robby CCRP5
    Antworten: 4
    Letzter Beitrag: 23.01.2006, 20:59
  4. Bytes zerlegen
    Von Murus im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 14
    Letzter Beitrag: 30.11.2005, 15:28
  5. Auslesen von Bytes des PCF 8574
    Von JensB im Forum Elektronik
    Antworten: 8
    Letzter Beitrag: 20.09.2004, 17:43

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •