Search code examples
cstructmicrocontrollerpicmplab

How to address all fields in a struct like these registers?


If you've programmed a microcontroller, you're probably familiar with manipulating select bits of a given register, or writing a byte to the whole thing. On a PIC using C for example, I can write an entire byte to PORTA to set all the bits, or I can simply address PORTAbits.RA# to set a single bit. I'm trying to mimic the way these structs/unions are defined so I can do the same thing with a variable in my program. Specifically, when the microcontroller turns on I want to be able to reset a register I myself have defined with something like

REGISTER = 0;

versus

REGISTERbits.BIT0 = 0;
REGISTERbits.BIT1 = 0; 
...
//or
REGISTERbits = (0,0,0,0,0,0,0,0);

etc.

Obviously the former is more elegant and saves a lot of line space. The header file of the microcontroller does it like this:

#ifndef __18F2550_H
#define __18F2550_H
....

extern volatile near unsigned char       LATA;
extern volatile near struct {
  unsigned LATA0:1;
  unsigned LATA1:1;
  unsigned LATA2:1;
  unsigned LATA3:1;
  unsigned LATA4:1;
  unsigned LATA5:1;
  unsigned LATA6:1;
} LATAbits;

...for each and every register, and registers with multiple bytes use unions of structs for their Registerbits. Since my initialization/declaration is in the main source file and not a header, I've dropped the extern and near off mine:

volatile unsigned char InReg;
volatile struct{
    unsigned NSENS:1;   //One magnetic sensor per direction
    unsigned SSENS:1;
    unsigned ESENS:1;
    unsigned WSENS:1;
    unsigned YBTN:1;    //One crosswalk button input per axis
    unsigned XBTN:1;    //(4 buttons tied together each)
    unsigned :2;
} InRegbits;

...but on compile, InReg and InRegbits are defined as two separate locations in memory, which means I can't write to InReg to change InRegbits. How do I change this so that it works? Does the one I'm trying to copy only work because it's a special microcontroller register?

Thanks for any help


Solution

  • volatile union InReg {
        unsigned char InRegAll;
        struct near {
            unsigned NSENS:1;   //One magnetic sensor per direction
            unsigned SSENS:1;
            unsigned ESENS:1;
            unsigned WSENS:1;
            unsigned YBTN:1;    //One crosswalk button input per axis
            unsigned XBTN:1;    //(4 buttons tied together each)
            unsigned :2;
        } InRegbits;
    }
    

    Be aware that this code may not be portable.