This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

long bit fields

I am using the SPI to access a couple of 20 & 24 bit A/D converters which have some digital status bits preceding the reading. I already have some C code written (for another CPU) that defines the incoming data structure as a unsigned long. The Keil compiler, however, says I must use char or integer size bit fields. Is there an easy way around this without having to hand code the byte manipulation code manually?

  • I'm not sure I properly understand this question. If I do, a union in which one member is an unsigned long, and the other is a struct containing unsigned chars and bit fields may solve your problem.

    I never use bit fields for this sort of thing, because the way bit fields map onto bytes is implementation-dependent, and may even change from one version of a compiler to the next, or with different compiler option settings.

    -- Gary Culp

  • Here is a simplified example.

    typedef struct {
     unsigned long det_in     :4,   /*compliance & short detection bits */
                   Brd_rev    :4,   /* board / pal revision  */
                   nu        :4,    /* not used as of 8/2000 */
                   AD_data    :20;  /* 0=-max, 0x80000=0v, fffff=+max */
                  } Bridge_brd_Rx_Type;  /* for each bridge card */
    
    I do use this variable type in a union of however many longs it takes.My end goal is to point a PEC register at this structure, let the SPI run, and then access the different bit fields as
     { long reading; char revision;
    reading = Brdg1.AD_data;
    revision = Brdg1.Brd_rev;
    ...
     }
    

  • ISO C says the bit fields must support up to size of int, not long. On 32-bit platforms they are usually one in the same. C51 implements int's as 16-bits so that's as big as your bit-fields can be. Sorry.

    - Mark

  • Here are some C51 declarations for a pair of cascaded (obsolete) MC14489 LED display drivers. In an external FPGA is an SPI interface that the CPU writes to in 8-bit (unsigned char) chunks, using the unions to get the bytes. This is implemetation dependent.

    //
    // LED Display
    //
    #define LED_DATA ((unsigned char volatile xdata *)0xe080) // LED data register (WR)
    #define LED_ENABLE_OFF ((unsigned char volatile xdata *)0xe081) // negate SPI ENABLE signal (any data) (WR)

    typedef struct {
    unsigned char leds_enable :1;
    unsigned char leds_not_hex_1 :1;
    unsigned char leds_not_hex_2 :1;
    unsigned char leds_not_hex_3 :1;
    unsigned char leds_not_hex_4 :1;
    unsigned char leds_not_hex_5 :1;
    unsigned char leds_special_123 :1;
    unsigned char leds_special_45 :1;
    unsigned char not_used_1 :8;
    unsigned char not_used_2 :8;
    unsigned char digs_enable :1;
    unsigned char digs_not_hex_1 :1;
    unsigned char digs_not_hex_2 :1;
    unsigned char digs_not_hex_3 :1;
    unsigned char digs_not_hex_4 :1;
    unsigned char digs_not_hex_5 :1;
    unsigned char digs_special_123 :1;
    unsigned char digs_special_45 :1;
    } led_ctrl_struct;

    typedef struct {
    unsigned char low_pwr :1; // first four bits are bank 5 nibble for leds
    unsigned char hi_pwr :1;
    unsigned char not_used_1 :2;
    unsigned char leds_dp_pos :3; // next four bits are decimal point/brightness control for leds
    unsigned char leds_bright :1;

    unsigned char ready :1; // next four bits are bank 3 nibble for leds
    unsigned char at_power :1;
    unsigned char not_used_2 :2;
    unsigned char spare_1 :1; // next four bits are bank 4 nibble for leds
    unsigned char spare_2 :1;
    unsigned char not_used_3 :2;

    unsigned char not_used_4 :4; // next four bits are bank 1 nibble for leds (not used)
    unsigned char remote_on :1; // next four bits are bank 2 nibble for leds
    unsigned char arc :1;
    unsigned char not_used_5 :2;

    unsigned char digit_4 :4; // next four bits are bank 5 for digits
    unsigned char digs_dp_pos :3; // next four bits are decimal point/brightness for digits
    unsigned char digs_bright :1;

    unsigned char digit_2 :4; // next four bits are bank 3 for digits
    unsigned char digit_3 :4; // next four bits are bank 4 for digits

    unsigned char not_used_6 :4; // next four bits are bank 1 for digits (not used)
    unsigned char digit_1 :4; // last four bits are bank 2 for digits
    } led_data_struct;

    typedef union {
    unsigned char ledc[4];
    led_ctrl_struct ledcs;
    } led_ctrl_union;

    typedef union {
    unsigned char ledd[6];
    led_data_struct ledds;
    } led_data_union;