Help with union.

Status
Not open for further replies.

MrNobody

New Member
Code:
void main()
{
    union
    {
        int Full;
        struct
        {
            bit ADRES0;
            bit ADRES1;
            unsigned char ADRESH;
        } Part;
    }ADCValue;

    int Value = ADCValue.Full;
}

Hi.. Above are some code for Hi-Tech C.
What I'm trying to do is to get the 10 bit ADC value in one go and store it in Value. I know that there is another way to do it ((ADRESH << 2) + (ADRESL >> 6)) but I'm also hoping to learn assign/read from different PIC registers in one go using union.

In C18, similar things can be done for PORT. the code below are found in PIC header file.
Code:
extern volatile near unsigned char       PORTB;
extern volatile near union {
  struct {
    unsigned RB0:1;
    unsigned RB1:1;
    unsigned RB2:1;
    unsigned RB3:1;
    unsigned RB4:1;
    unsigned RB5:1;
    unsigned RB6:1;
    unsigned RB7:1;
  };
  struct {
    unsigned INT0:1;
    unsigned INT1:1;
    unsigned INT2:1;
  };
  struct {
    unsigned AN12:1;
    unsigned AN10:1;
    unsigned AN8:1;
    unsigned AN9:1;
    unsigned AN11:1;
    unsigned PGM:1;
    unsigned PGC:1;
    unsigned PGD:1;
  };
  struct {
    unsigned :2;
    unsigned VMO:1;
    unsigned VPO:1;
    unsigned KBI0:1;
    unsigned KBI1:1;
    unsigned KBI2:1;
    unsigned KBI3:1;
  };
} PORTBbits;

Any idea how I can do similar things in Hi-Tech C for ADC..? thanks alot.
 
Last edited:
I would not define this inside main. Make it global by putting it outside main.

The other thing is this has to be external, meaning that the compiler should not allocate space for it. This memory already exists as a register. I do not use this compiler and do not know how to setup the var here to point to the existing register.

3v0
 
The easiest way to do this is,

#define ADCValue (ADRESH*256+ADRESL)

Then you can do,

result=ADCValue;

I don't know of anyway to make the compiler use two non consecutive bytes as an integer.

Mike.
 
@Mike
ADRESL and ADRESH are consecutive resigers at 0xFC3 and 0xFC4 so I expect you could do a union between an int and these two bytes. There is still the problem of associating the definition with the memory address. It is easier to do it as you suggested.

@MrNobody
Most of us would use the method suggested by Mike.

As he pointed out the union method will only work for consecutive registers.
The MikroC manaul says all SFR are declared as volitale unsigned short "with external linkages". These are defined in a def file. I expect the easiest way to do what you want is to modify the definitions in the def file. But if you do not know what you are doing you could/will cause the SFR's names to point to the wrong registers and that could be very confusing. This is not a good place to learn to use unions.
 
I assumed that he was using a 16 series chip. With consecutive registers in BoostC you can do,
Code:
unsigned int adres @ADRESL;
  .
  .
  .
unsigned int temp;
    temp=adres;
Note, this will only work on an 18 series chip.

Mike.
 
Oh.. ok.. i might have bitten off more than what i can chew when I intend to do it using union..
Ok then, I'll do it as what Mike suggected in post #3..
Thanks..

Mike, I'm assuming that you are formatting the ADRES as right justified so that the 2 MSB are in ADRESH, am I right..?
Thanks..
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…