Breaking a 16-bit long int, um in eeprom zu schreiben?

Ich schreibe Daten mit dem PIC-Mikrocontroller pic18f4520 in das Eeprom AT24C16. Jede Adresse dieses Eeproms kann 8 Bits enthalten, während ich lange Ints verwende, um Daten mit einer Größe von 16 Bit zu speichern. Wie kann man long int in 2 8-Bit-Teile aufteilen, um sie zu schreiben, und wie kann man sie nach dem Lesen aus dem Eeprom wieder zusammensetzen?

Zuerst die ersten 8 Bit schreiben, dann die zweiten 8 Bit? Oder fragen Sie nach tatsächlichem Code, der für Sie geschrieben wird?
Sind Sie sicher, dass a long intnur 16 Bit hat?
@HannoBinder Er sagte, dass er ein long int verwendet, um 16 Datenbits zu speichern. Er könnte die anderen 16 Bits nicht verwenden und dennoch zu 100% mit seiner Aussage richtig liegen. Ineffizient, sicher, aber immer noch richtig ...

Antworten (3)

In C können Sie Bitverschiebung und Maskierung verwenden, um jedes Byte einer längeren Zahl zu extrahieren:

lower_8bits = value & 0xff;
upper_8bits = (value >> 8) & 0xff;

Und Sie können die Zahl aus Bytes "wieder zusammensetzen", indem Sie den umgekehrten Vorgang ausführen:

value = (upper_8bits << 8) | lower_8bits;
Ich war versucht, über Gewerkschaften zu quatschen, aber jetzt ist nicht der richtige Moment, oder? ;-)
@Asmyldof Es ist verlockend, aber ein guter Compiler optimiert Bit-Shifting-Snippets so, dass sie nur das relevante Byte lesen, ohne dass Sie sich Gedanken über Endianness machen müssen.
Ich weiß, aber Gewerkschaften sind eine tolle Sauce :-D
Einige Compiler sind dumm genug, tatsächlich um 8 zu verschieben und [OR/AND], genau wie im Quellcode angegeben, sogar auf einem 8-Bit-Chip mit allen eingeschalteten Optimierungen. Ich habe Gewerkschaften und Zeigernotation verwendet, um dies zu umgehen, je nachdem, wie oft ich auf diese Weise auf jede Variable zugreifen muss.
long int my16bitdata = 0xEA51;

int MSB, LSB;

MSB = (my16bitdata>>8) & 0xFF;
LSB = my16bitdata & 0xFF;

In diesem Fall wäre das Ergebnis:

MSB = 0xEA

Und

LSB = 0x51 

Erklärung:

Durch Ausführen einer Bitverschiebungsoperation (>>) am 16-Bit-Wert können wir die oberen Bits nach unten in den unteren Abschnitt verschieben. Alle 8 von ihnen. Wir führen dann ein bitweises UND (&) mit einem 0xFF durch, um diesen Wert auf die 8 Bits anzuwenden, die in „int“ verfügbar sind.

Für die unteren 8 Bits (LSB) ist keine Bitverschiebung erforderlich, sodass wir einfach das bitweise UND ausführen können, um die benötigten Daten zu erhalten.

Ein Ansatz auf höherer Ebene, der den Compiler die Verschiebung vornehmen lässt, würde folgendermaßen aussehen:

typedef union Int16
{
  int data;
  struct
  {
    unsigned char lsb;
    unsigned char msb;
  }bytes __attribute__ ((packed));
}Int16 __attribute__ ((packed));
#define MSB bytes.msb    
#define LSB bytes.lsb    

Int16 myInt;
unsigned char msb, lsb;

myInt.data = 0x1234;
msb = myInt.MSB;
lsb = myInt.LSB;