CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Question About Unions

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
csanders



Joined: 23 Apr 2005
Posts: 16

View user's profile Send private message

Question About Unions
PostPosted: Mon Nov 07, 2005 11:47 pm     Reply with quote

Hello All

I have an 8 bit variable that I would like to be able to modify either by writing a value directly to it or by modifiying individual bits in the variable. From what I understand about c is that this is what a union is used for. Here is my code--

Code:

union ier {             
   int1 rhr_int;     //RHR Interrupt Enable 0=Disable, 1=Enable
   int1 thr_int;     //THR Interrupt Enable 0=Disable, 1=Enable
   int1 rxline;      //Rx Line Status Interrupt 0=Disable, 1=Enable
   int1 msr_int;   //Modem Status Register Interrupt 0=Disable, 1=Enable
   int1 sleep;      //Sleep Mode 0=Disable, 1=Enable
   int1 xoff_int;   //XOFF Interrupt 0=Disable, 1=Enable
   int1 rts_int;     //RTS Interrupt 0=Disable, 1=Enable
   int1 cts_int;    //CTS Interrupt 0=Disable, 1=Enable
   int8  value;    //Raw Register Value
}ier_set;


When I set ier_set.sleep = 1, I expect to see ier_set.value = 0x10, however what I actually get is all of the individual bits = 1 and the ier_set.value = 1. Can anyone see what I've done wrong or suggest an alternate method of performing this task?

Thanks a bunch
Ttelmah
Guest







PostPosted: Tue Nov 08, 2005 4:36 am     Reply with quote

The key here, is that you are declaring eight _seperate_ int1 variables, which therefore are each mapped in the union, to the same space. Changing any one will change all the others (which is what a union is about!).
Effectively you need to declare a _single_ variable, containing 8 'bits', to get the behaviour you require.
There are a number of ways of doing this. The first (in CCS), is to declare a structure containing the eight bit fields, as (say)
Code:

struct bits {
   int1 rhr_int;     //RHR Interrupt Enable 0=Disable, 1=Enable
   int1 thr_int;     //THR Interrupt Enable 0=Disable, 1=Enable
   int1 rxline;      //Rx Line Status Interrupt 0=Disable, 1=Enable
   int1 msr_int;   //Modem Status Register Interrupt 0=Disable, 1=Enable
   int1 sleep;      //Sleep Mode 0=Disable, 1=Enable
   int1 xoff_int;   //XOFF Interrupt 0=Disable, 1=Enable
   int1 rts_int;     //RTS Interrupt 0=Disable, 1=Enable
   int1 cts_int;    //CTS Interrupt 0=Disable, 1=Enable
}

and then declare the union to contain one of these structures, and the int8, as:
Code:

union ier {
   struct bits b;
   int8 value;
}ier_set;

Then you can access the bits as ier_set.b.rhr_int etc..
Though this should work, it is probably better to use the 'bit field' declaration, rather than int1, since this ensures that the bits genuinely are aligned into a single integer. So:
Code:

struct bits {
   int8 rhr_int : 1;     //RHR Interrupt Enable 0=Disable, 1=Enable
   int8 thr_int : 1;     //THR Interrupt Enable 0=Disable, 1=Enable
   int8 rxline : 1;      //Rx Line Status Interrupt 0=Disable, 1=Enable
   int8 msr_int : 1;   //Modem Status Register Interrupt 0=Disable, 1=Enable
   int8 sleep : 1;      //Sleep Mode 0=Disable, 1=Enable
   int8 xoff_int : 1;   //XOFF Interrupt 0=Disable, 1=Enable
   int8 rts_int : 1;     //RTS Interrupt 0=Disable, 1=Enable
   int8 cts_int : 1;    //CTS Interrupt 0=Disable, 1=Enable
}

This declares the 'bits', to be single bit fields inside an int8 variable, which can then be mapped with the union to the same space as another normal 'int8'.
This approach is probably the most 'portable' solution.
You can though also do the same thing, by not using a union, and just using the #bit declaration in CCS. So if you declare an int8, called 'ier_set', you can declare bits as:
#bit rhr_int=ier_set.1

This is 'specific' to CCS, but does make the in-use declarations very simple.
There are a number of other similar methods of doing this, and if you look at how the port declarations are done on some of the posted code, for things like LCD I/O, you will see a number of the other solutions.

Best Wishes
csanders



Joined: 23 Apr 2005
Posts: 16

View user's profile Send private message

PostPosted: Tue Nov 08, 2005 11:41 pm     Reply with quote

Thank you

That is exactly what I was trying to do. Your help is greatly appreciated.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group