Registre el mapa usando C para un front-end analógico MAX30001

Estoy tratando de seguir las mejores prácticas en el mapeo de registros. Tengo un front-end analógico MAX30001 para aplicaciones de ECG ( Hoja de datos ) y en la página 38, hay una tabla que contiene comando de usuario y mapa de registro: 32 palabras, cada una con 24 bits de información. ¿Debo usar estructuras o macros?

Usando estructuras con campos de bits:

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;

Uso de macros:

#define STATUS (*(volatile uint32_t*)0x01))
¿Podría explicar cómo usaría estructuras o macros? Para cada uno, agregue un ejemplo (y referencias externas, si las hay), tal vez. Probablemente entiendo lo que quieres decir [creo]. Pero sería mejor si te explicas tú mismo.
digamos que desea configurar BINT (statusReg: bit3) ... ¿cómo se vería el código para cada uno de los métodos de mapeo? ... ¿cuál sería más fácil de leer?
Está bien. publicación editada

Respuestas (2)

En el caso general, donde tiene registros asignados a la memoria, siempre debe evitar las estructuras de campo de bits. Esto se debe a que están muy mal especificados por el estándar C. Las cosas fundamentales que puede suponer que están especificadas, no lo están. Esto incluye orden de bits, orden de bytes, relleno y alineación.

Además, uint8_tentre otros tipos, ¡ni siquiera es un tipo permitido en campos de bits! Solo puede usar inttipos, aunque inttampoco se especifica si cuenta como firmado o sin firmar...

Para resumir, los campos de bits son terriblemente poco confiables y usted queda a merced de la implementación del compilador (si corresponde) cuando los usa.

En cambio, lo que debe hacer es usar siempre macros de dirección y máscara de bits, junto con los operadores bit a bit. Esos son 100% bien definidos y portátiles.

El MAX30001 utiliza una interfaz SPI. No es un dispositivo mapeado en memoria, por lo que aquí no se pueden usar estructuras ni macros.

Casi todo lo que puede hacer de manera útil es definir un montón de macros para representar los números de registro y los bits individuales dentro de ellos, por ejemplo:

#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

Incluso para dispositivos mapeados en memoria, generalmente es mejor evitar los campos de bits (como Bit0:1). Los compiladores de C a menudo los manejan mal y ofrecen pocas garantías sobre cómo se empaquetarán los campos de bits en una estructura. Use macros para representar bits individuales dentro de un solo registro.