|
|
View previous topic :: View next topic |
Author |
Message |
csanders
Joined: 23 Apr 2005 Posts: 16
|
Question About Unions |
Posted: Mon Nov 07, 2005 11:47 pm |
|
|
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
|
|
Posted: Tue Nov 08, 2005 4:36 am |
|
|
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
|
|
Posted: Tue Nov 08, 2005 11:41 pm |
|
|
Thank you
That is exactly what I was trying to do. Your help is greatly appreciated. |
|
|
|
|
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
|