- HEMS Solar Speicher Tutorial    Werbung      
Ergebnis 1 bis 10 von 18

Thema: Daten aus 2 hintereinander liegenden Registern in ein char[8] Array einlesen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Hin und zurück kopieren sollte so gehen

    Code:
    struct  // hier habe ich eine 8 Byte Struktur
    {
      unsigned int a;   // 4 Bytes
      unsigned int b;  // nochmal 4 Bytes
    } value;
    
    char* pRegister;
    
    unsigned char Data[8];
    
    int main(void)
    {int i;
    
        // 8 Bytes initialisieren
        value.a = 0x11223344;
        value.b = 0x55667788;
    
        pRegister = (char*)&value;  // Zeiger setzen
    
        for (i=0; i<8; i++)    // alle 8 Bytes kopieren
        {
          Data[i]=*pRegister++;
        }
    
       // !!!!! den Pointer wieder richtig setzen !!!! hatte ich eben auch vergessen.....
        pRegister = (char*)&value;  // Zeiger wieder auf Start setzen
    
        for (i=0; i<8; i++)    // alle 8 Bytes zurück kopieren
        {
          *pRegister++=Data[i];
        }
    Geändert von Siro (18.02.2019 um 21:37 Uhr)

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    05.10.2018
    Beiträge
    33
    . . glaube es siet bei mir ziemlich änlich aus ausser das ich CAN Register mit bestimmten Adresse anspreche.

    Aber das ist ja auch NUR Speicher . . .

    ++++++++++++++++++++
    char Data[8] = "11223344";

    volatile char *pTxRegister = (char *)(CAN1_BASE + CAN_TDL0R_OFFSET);

    for (unsigned char i = 0; i < 8; i++){
    *pTxRegister = Data[i ];
    pTxRegister++;
    }

    Müsste doch gehen, ABER
    jedes Zeichen wird nicht nur in das adressierte Byte sondern in jedes der 4 Bytes des Registers übertragen.

    - - - Aktualisiert - - -

    . . ok hab es erst mal so gelöst:
    pTxReg1 = Data[i+3] << 24 | Data[i+2] << 16 | Data[i+1] << 8 | Data[i+0];
    pTxReg2 = Data[i+7] << 24 | Data[i+6] << 16 | Data[i+5] << 8 | Data[i+4];

    i - ist die Verschiebung durch das Data Array.

    Ist nicht so elegant wie ne Schleife aber erfüllt den Zweck.

    Trotzdem würde mich interessieren wieso es mit der Schleife nicht tut ???
    Wo ist da der Fehler ??

  3. #3
    HaWe
    Gast
    ... leider arbeite ich in einer ganz bestimmten Umgebung die KEINEN memcpy hat
    memcpy ist Teil der Bibliothek <cstring> bzw. <string.h> , wieso kannst du die nicht #includen? Das ist schließlich eine C99 Standardbibliothek, die jeder C Compiler einbinden kann.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Die ganze Sache ist nicht so einfach. Das fängt schon mal mit der Größe der Variablen an. Ein int ist in C mindestens 16 Bit, kann aber auch 64 Bit sein. Dazu kommt noch die Anordnung und die Orientierung der Bytes im Speicher, also ob Big oder Little Endian. Sauberer C-Code sollte von all dem nicht abhängig sein. Spätestens bei der Übertragung der Daten zwischen verschiedenen Systemen fällt einem das sonst auf die Füsse.

    Um die Größe sicherzustellen, kann man int32_t bzw. uint32_t verwenden. Und um Probleme mit der Endianes zu vermeiden ist
    Code:
    pTxReg1 = Data[i+3] << 24 | Data[i+2] << 16 | Data[i+1] << 8 | Data[i+0];
    ein Weg. Rückwärts geht es dann über Schieben nach rechts und ausmaskieren. Das sollte auf allen Architekturen das gleiche Ergebnis liefern.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    41
    Beiträge
    3.416
    kein memcpy?
    hast du denn
    #include <string.h>
    schon probiert?
    Der compiler weis meistens am besten wie man mit registern umgeht, also sollte man es dem compiler auch überlassen.

    Ich unterstütze hier Klebwax mit seiner Aussage, wenn man schon Bare-Bone programmiert sollte man sich ein klein wenig mit der Architektur mit der man arbeitet auseinandersetzen.

    Die Register sind je nach Controller und zugehöriger Bibliothek ander zu benutzen und sollten (wenn man nicht gerade irgendwelche Magie mit DMAs versucht) auch so benutzt werden. Ein Register manuell per Pointer anzusprechen führt nur zu den seltsamsten Effekten. Da gibt es z.B. den XMega (okay nicht gerade ein ARM, aber ein gutes Beispiel) bei dem man immer erst das high und dann das low byte beschreiben muss, weil er sonst nur das low byte kopiert und das high byte dann irgendwo anders landet wenn man ein anderes Register beschreibt.
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  6. #6
    HaWe
    Gast
    das mit dem #include <cstring> bzw. <string.h> hatte ich oben ja auch bereits angemerkt.
    Welche Endianess vom Compiler bzw. MCU benutzt werden, ist aber eigentlich egal, wenn man es anschließend wieder als (int) bzw. (uint32_t) ausliest oder aber zurückkopiert - das mache ich auch immer so, und es klappt sowohl auf AVRs als auch ARM Cortex M0, M3, M4 als auch auf dem Raspi (ARM57).

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    41
    Beiträge
    3.416
    das mit dem #include <cstring> bzw. <string.h> hatte ich oben ja auch bereits angemerkt.
    Sorry muss ich überlesen haben

    Welche Endianess vom Compiler bzw. MCU benutzt werden, ist aber eigentlich egal, wenn man es anschließend wieder als (int) bzw. (uint32_t) ausliest oder aber zurückkopiert
    sicher, aber wenn du es vorher in Bytes zerlegst und willkürlich speicherst kommt am Ende nur Murks raus wenn man nicht auf die Byteorder achtet Bild  

    Worauf ich hinaus wollte war eher dass man die Register nach Möglichkeit ausschließlich (DMA als Ausnahme genannt) über ihr Registernamen und nicht über Pointer ansprechen sollte! Bzw die Zuweisung zu Registern und ggf. auch das auslesen immer (quasi-)atomar machen sollte und nicht stückeln.
    Bei AtMegas und XMegas wie erwähnt, kann man auch manche Register word- oder byteweise schreiben aber da der Bus nur 8 bzw. 16 bit breit ist muss man da auf die Reihenfolge achten, da quasi der halbe Schreibbefehl in einem Puffer landet und der Latch erst mit dem schreiben des low Byte ausgeführt wird und wenn man falsch herum schreibt kommt auch nur Murks dabei raus.

    Byteweise + Register (>8bit bzw. >Busbreite) sollte man generell vermeiden, das ist der Kern meiner Aussage
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

Ähnliche Themen

  1. Char mit array verbinden ?
    Von AsuroPhilip im Forum Software, Algorithmen und KI
    Antworten: 22
    Letzter Beitrag: 08.09.2011, 13:37
  2. Videoframes online in VisualBasic-Array einlesen
    Von malthy im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 8
    Letzter Beitrag: 26.07.2007, 10:52
  3. gelöst : Frage zu C und 2 Dim char Array
    Von jar im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 29.05.2007, 16:53
  4. zweidemensionales char-array
    Von p_mork im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 15.03.2007, 16:54
  5. Cstring einem char array zuweisen
    Von ceekay im Forum Software, Algorithmen und KI
    Antworten: 8
    Letzter Beitrag: 17.04.2006, 10:20

Berechtigungen

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

    Werbung      12V Akku bauen