Registrieren Sie die Karte mit C für ein analoges MAX30001-Frontend

Ich versuche, die Best Practices bei der Registerzuordnung zu befolgen. Ich habe ein analoges MAX30001-Frontend für EKG-Anwendungen ( Datenblatt ) und auf Seite 38 gibt es eine Tabelle, die Benutzerbefehle und Registerkarten enthält: 32 Wörter mit jeweils 24 Informationsbits. Soll ich Strukturen oder Makros verwenden?

Verwendung von Strukturen mit Bitfeldern:

typedef struct {

    volatile uint8_t Bit0 : 1;
    volatile uint8_t Bit1 : 1;
    volatile uint8_t Bit2 : 1;
    volatile uint8_t Bit3 : 1;
    // ... 
    // and so on
    // ... 
    volatile uint8_t Bit23 : 1;
} foo;

Verwendung von Makros:

#define STATUS (*(volatile uint32_t*)0x01))
Können Sie erklären, wie Sie Strukturen oder Makros verwenden würden? Fügen Sie für jedes Beispiel ein Beispiel (und ggf. externe Referenzen) hinzu. Ich verstehe wahrscheinlich, was du meinst [glaube ich]. Aber es wäre besser, wenn Sie sich erklären würden.
Angenommen, Sie möchten BINT (statusReg:bit3) festlegen ... wie würde der Code für jede der Zuordnungsmethoden aussehen? ... was wäre einfacher zu lesen?
In Ordnung. Beitrag bearbeitet.

Antworten (2)

Im allgemeinen Fall, in dem Sie speicherabgebildete Register haben, sollten Sie Bitfeldstrukturen immer vermeiden. Dies liegt daran, dass diese vom C-Standard sehr schlecht spezifiziert sind. Grundlegende Dinge, von denen Sie annehmen könnten, dass sie spezifiziert sind, sind es nicht. Dazu gehören Bit-Reihenfolge, Byte-Reihenfolge, Padding & Alignment.

Außerdem uint8_tist unter anderem Typen nicht einmal ein zulässiger Typ in Bitfeldern! Sie können nur intTypen verwenden, wenn intzählt als signiert oder unsigniert ist auch nicht angegeben ...

Zusammenfassend lässt sich sagen, dass Bitfelder schrecklich unzuverlässig sind und Sie der Compiler-Implementierung (falls vorhanden) ausgeliefert sind, wenn Sie sie verwenden.

Was Sie stattdessen tun sollten, ist, immer Adress- und Bitmaskenmakros zusammen mit den bitweisen Operatoren zu verwenden. Diese sind zu 100 % gut definiert und portabel.

Der MAX30001 verwendet eine SPI-Schnittstelle. Es ist kein speicherabgebildetes Gerät, daher sind hier weder Strukturen noch Makros verwendbar.

Alles, was Sie sinnvollerweise tun können, ist, eine Reihe von Makros zu definieren, um die Registernummern und einzelne Bits darin darzustellen, z.

#define MAX30001_NO_OP           0x00
#define MAX30001_STATUS          0x01
#define MAX30001_STATUS_EINT     0x800000
#define MAX30001_STATUS_EOVF     0x400000
#define MAX30001_STATUS_FSTINT   0x200000
// etc

Selbst für speicherabgebildete Geräte ist es im Allgemeinen am besten, Bitfelder (wie Bit0:1) zu vermeiden. C-Compiler handhaben sie oft schlecht und geben nur wenige Garantien darüber, wie Bitfelder in eine Struktur gepackt werden. Verwenden Sie Makros, um einzelne Bits innerhalb eines einzelnen Registers darzustellen.