MPLABX: Wie liest/schreibt man eine vorzeichenlose 4-Byte-Ganzzahl in das EEPROM?

Meine Frage sieht einfach aus, aber ich habe mich trotzdem verirrt, um das Problem zu lösen. Die Diskussion könnte mir den Weg weisen.

Ich verwende den Mikrocontroller Pic16f877A, um EEPROM mit I2C (jeweils 1 Byte) zu schreiben. Ich muss einen 4-Byte-Ganzzahlwert schreiben (sagen wir 4284967295 ~ 0xFF67697F). Ich möchte diesen Wert in das EEPROM schreiben und diesen Wert bei Bedarf aus dem EEPROM lesen. Ich bin nicht in der Lage, die bestmöglichen Möglichkeiten zum Schreiben/Lesen dieses Werts zu finden.

Ich habe versucht, mich folgendermaßen zu nähern:

unsigned int a = 4284967295;
unsigned int result1, result2, result3, result4;
result1 = (( a & 0x000000FF ) ); \\ result1 = 127
result2 = (( a & 0x0000FF00 ) ); \\ result2 = 26880
result3 = (( a & 0x00FF0000 ) ); \\ result3 = 6750208
result4 = (( a & 0xFF000000 ) ); \\ result4 = 4278190080

aber den Weg verloren. Und Referenz, Link und Ihre Anleitung werden geschätzt.

Vielen Dank im Voraus!!!!!!!

Das Datenblatt des entsprechenden Produkts enthält wertvollen Beispielcode: ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf (Seite 35). Wenn etwas unklar ist, fragen Sie, was genau. EDIT: Ah, ich habe die Frage falsch verstanden. Zum Glück haben zwei schnelle Antworten das Problem bereits für Sie gelöst.

Antworten (3)

Ein Problem ist, dass Sie die Bits beim Einlesen in das Ergebnis nicht mitschieben und je nach Compiler unsigned intmöglicherweise nicht groß genug für einen 32-Bit-Wert sind. Der folgende Code stammt aus einem Nicht-Microchip-Projekt, sollte Ihnen aber eine Idee zeigen. Die Verwendung des stdint.hHeaders in Ihren Projekten ist im Allgemeinen eine gute Idee, da Sie die Größe der Datentypen leicht erkennen können und sich nicht auf Compiler-abhängige Größen verlassen müssen.

#include <stdint.h>

void write_eeprom_int32(uint16_t addr, uint32_t data)
{
    write_eeprom(addr, data & 0xFF);
    write_eeprom(addr + 1, data >> 8 & 0xFF);
    write_eeprom(addr + 2, data >> 16 & 0xFF);
    write_eeprom(addr + 3, data >> 24 & 0xFF);
}

uint32_t read_eeprom_int32(uint16_t addr)
{
    uint32_t result;

    result = read_eeprom(addr + 3);
    result <<= 8;
    result += read_eeprom(addr + 2);
    result <<= 8;
    result += read_eeprom(addr + 1);
    result <<= 8;
    result += read_eeprom(addr);
    return result;
}
Für meine Lösung mit CodeVisionAVR funktioniert es mit [&0xFF] nach ALLEN Verschiebungen (data&0xFF, data>>8&0xFF, data>>16&0xFF und data>>24&0xFF)
Dieser Code stammte aus einem Projekt, bei dem der Wert ein 8-Bit-Wert war, sodass er abgeschnitten wurde, aber danke, es hat sich gelohnt, ihn zu aktualisieren, um ihn generischer zu machen, da dies kein garantiertes Verhalten zwischen Compilern und Bibliotheken ist.

Eine einfache Lösung besteht darin, a zu verwenden, unionum your unsigned longauf 4 Bytes neu zu definieren (beachten Sie, dass your unsigned intin XC8 nur 2 Bytes sind):

union
{
    uint32_t      uNumber;  // exactly 4 bytes, no larger
    unsigned char uByte[4];
} myUnion;

// write to eeprom ...
myUnion.uNumber = 4284967295;
for (unsigned char i = 0; i < 4; ++i)
{
    // write myUnion.uByte[i] to eeprom here
}

// read from eeprom ...
for (unsigned char i = 0; i < 4; ++i)
{
    // read myUnion.uByte[i] from eeprom here
}
unsigned long uNumberRead = myUnion.uNumber;
unsigned long int a = 4284967295;

unsigned char result[4];

result[0]=a;

result[1]=a>>8;

result[2]=a>>16;

result[3]=a>>24;

j=0;

for(i=*starting_address* ;  i<= *starting_address + 4*  ; i++)

{

  write_eeprom(i,result[j]);

  j++;

}