Referring to a bit of a variable in microchip XC8? (c program)

Status
Not open for further replies.

Flyback

Well-Known Member
Hello,
I am writing C code in MPLAB.X with the free XC8 compiler (PIC18F65K22 is target)
If I have a variable in C...

unsigned int dip8

..then how do I refer to individual bits of that variable (its an 8 bit variable)
 
There are two ways... Create a struct and name each variable or just mask all but the bit you need..

Example 1
C:
struct{
   unsigned SW1   : 1;
   unsigned SW2  : 1;
   unsigned SW3  : 1;
   unsigned SW4  : 1;
   unsigned SW5  : 1;
   unsigned SW6  : 1;
   unsigned SW7  : 1;
   unsigned SW8  : 1;
}dip8;

Then access each bit as dip8.SW1, dip8.SW2... etc..
Or masking
C:
if(dip8 && 0x01) SW1  = 1;
if(dip8 && 0x02) SW2  = 1;
if(dip8 && 0x04) SW3 = 1;
if(dip8 && 0x08) SW4 = 1;
if(dip8 && 0x10) SW5  = 1;
if(dip8 && 0x20) SW6  = 1;
if(dip8 && 0x40) SW7  = 1;
if(dip8 && 0x80) SW8  = 1;
 
hm.. Ian im not sure thats correct buddy. you can do that with a normal variable... How about that same structure then access it like...

Code:
struct{
   unsigned SW1  :1;
   unsigned SW2  :1;
   unsigned SW3  :1;
   unsigned SW4  :1;
   unsigned SW5  :1;
   unsigned SW6  :1;
   unsigned SW7  :1;
   unsigned SW8  :1;
}dip8;

//USAGE

dip8 temp;

temp.SW1 = 1;

if(temp.SW2 == 0) 
{
    //BIT 2 is low
}
 
I use macros:
C:
/* Bit Operation macros */
#define sbi(b,n) ((b) |=   (1<<(n)))        /* Set bit number n in byte b   */
#define cbi(b,n) ((b) &= (~(1<<(n))))       /* Clear bit number n in byte b */
#define rbi(b,n) ((b) &    (1<<(n)))        /* Read bit number n in byte b  */
#define fbi(b,n) ((b) ^=   (1<<(n)))        /* Flip bit number n in byte b  */

#define bit_is_set(b,n)   (b & (1<<n))      /* Test if bit number n in byte b is set   */
#define bit_is_clear(b,n) (!(b & (1<<n)))   /* Test if bit number n in byte b is clear */

void main(void)
{
    uint8_t dip8;

    sbi(dip8, 0); /* Set bit number 0 */
    cbi(dip8, 7); /* Clear bit number 7 */
    fbi(dib8, 4); /* Flip bit number 4 */

    if(bit_is_set(dip8, 0))
    {
        /* Bit number 0 was set */
    }

    if(bit_is_clear(dip8, 2))
    {
        /* Bit number 2 was clear */
    }
}
 
Jason.... If you Typedef the struct.... However I haven't.. The struct has no identifier so dip8 is a struct variable..

Works believe me...
 
Jason.... If you Typedef the struct.... However I haven't.. The struct has no identifier so dip8 is a struct variable..
Yes, this why I do not like to use typedefs (with structs). It can get confusing fast.

Struct as typedef:
C:
    // Define the typedef
    typedef struct
    {
        unsigned SW1  : 1;
        unsigned SW2  : 1;
        unsigned SW3  : 1;
        unsigned SW4  : 1;
        unsigned SW5  : 1;
        unsigned SW6  : 1;
        unsigned SW7  : 1;
        unsigned SW8  : 1;
    }dip_t;

    // Declare the variable
    dip_t dip8;
    // Use the variable
    dip8.SW1 = 1;

"Clean" struct:
C:
    // Define the struct
    struct dip
    {
        unsigned SW1  : 1;
        unsigned SW2  : 1;
        unsigned SW3  : 1;
        unsigned SW4  : 1;
        unsigned SW5  : 1;
        unsigned SW6  : 1;
        unsigned SW7  : 1;
        unsigned SW8  : 1;
    };

    // Declare the variable
    struct dip dip8;
    // Use the variable
    dip8.SW1 = 1;

Declaring without definition
C:
    // Declare the variable
    struct
    {
        unsigned SW1  : 1;
        unsigned SW2  : 1;
        unsigned SW3  : 1;
        unsigned SW4  : 1;
        unsigned SW5  : 1;
        unsigned SW6  : 1;
        unsigned SW7  : 1;
        unsigned SW8  : 1;
    }dip8;

    // Use the variable
    dip8.SW1 = 1;
 
Last edited:
Yes, this why I do not like to use typedefs (with structs).

Or, you can use both:

Code:
typedef struct dip
{
  unsigned SW1  : 1;
  unsigned SW2  : 1;
  unsigned SW3  : 1;
  unsigned SW4  : 1;
  unsigned SW5  : 1;
  unsigned SW6  : 1;
  unsigned SW7  : 1;
  unsigned SW8  : 1;
}dip_t;
 
dip_t dip8;
struct dip dip9;
 
Or, you can use both..
Oh, the horror, if somebody actually does that . Well, anonymous structs were not allowed before, so you had to declare typedef structs that way. But, the code becomes a real mess if you define same type of variables two different ways.
 
Last edited:
Oh, the horror, if somebody actually does that .

This!! Straight from the Microchip header
C:
typedef union {
  struct {
  unsigned C  :1;
  unsigned DC  :1;
  unsigned Z  :1;
  unsigned nPD  :1;
  unsigned nTO  :1;
  unsigned RP  :2;
  unsigned IRP  :1;
  };
  struct {
  unsigned  :5;
  unsigned RP0  :1;
  unsigned RP1  :1;
  };
  struct {
  unsigned CARRY  :1;
  };
  struct {
  unsigned  :2;
  unsigned ZERO  :1;
  };
} STATUSbits_t;
extern volatile STATUSbits_t STATUSbits @ 0x003;
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…