View previous topic :: View next topic |
Author |
Message |
Benjamin
Joined: 11 Jan 2006 Posts: 21 Location: Quebec (Canada)
|
Union + Structure = me go crazy |
Posted: Wed Dec 22, 2010 8:40 am |
|
|
Short question on unions. Is this legal:
Code: |
typedef union _TYPE_DONNEES
{
unsigned char byte;
struct _BITS
{
unsigned int8 format:4; // LSB
unsigned int8 type:4; // MSB
}bits;
}TD_INFO;
|
Is there something wrong in my syntax?
I want a simple way of accessing the lower and upper 4 bits of a byte:
ex.:
Code: |
TD_INFO variable_info;
variable.byte = read_data();
switch(variable.bits.type)
{
...
}
|
I've been using this structure on a PIC18 for a while and it works. Now I'm transfering the program to DSPIC33. It compiles, but crashes when I write to "variable.byte".
Thanks,
Benjamin |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Dec 22, 2010 8:53 am |
|
|
I am sure it's just a typo but shouldn't that be
variable_info.byte
and
switch(variable_info.bits.type)
NOT variable ! |
|
|
Benjamin
Joined: 11 Jan 2006 Posts: 21 Location: Quebec (Canada)
|
|
Posted: Wed Dec 22, 2010 8:59 am |
|
|
Yes it's a typo, the example is just something I typed in my question.
Should of been:
Code: |
TD_INFO variable_info;
variable_info.byte = read_data();
switch(variable_info.bits.type)
{
...
}
|
|
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Dec 22, 2010 9:13 am |
|
|
Just as a comment, I think it's pretty dangerous to use the word byte as a
variable since it is used as a keyword in many compilers. The same thing is
true for the variable type. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Dec 22, 2010 11:14 am |
|
|
dyeatman wrote: | Just as a comment, I think it's pretty dangerous to use the word byte as a
variable since it is used as a keyword in many compilers. The same thing is
true for the variable type. |
Amen -- definitely avoid using compiler keywords in your code where they don't belong.
What you're asking about, I do all the time (and Microchip does in their code as well.)
Code: |
union {
unsigned int16 w;
unsigned int8 v[2];
struct {
unsigned int8 lsb;
unsigned int8 msb;
} byte;
} WORD_VAL;
|
With this, you can say:
WORD_VAL.w = 0x1234 (now v[0] & byte.msb = 0x34 and v[1] and byte.lsb= 0x12 while )
you can access word_val.v[0], word_val.v[1], word_val.byte.lsb, word_val.byte.msb
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
RayJones
Joined: 20 Aug 2008 Posts: 30 Location: Melbourne, Australia
|
|
Posted: Sun Dec 26, 2010 2:15 pm |
|
|
The big potential problem I see is the use of a bit field within a structure, within the union.
Have you tried looking at the generated ASM for the various types of access methods?
Does it look like the upper or lower 4 bits of your bit field are being masked appropriately?
Are they in the correct order?
Certainly the use of a union to work with two 8 bit values as a 16 bit value is my favourite technique, but I have never tried bit fields for nibble data. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sun Dec 26, 2010 3:41 pm |
|
|
thankfully, the 8bit PIC's have a bytesize swap command.
SWAPF
I looked at both the 18F and 16F LST output from doing a struct/union based swap and the compiler picks up on it.
Code: | #include <16F876.h>
#fuses HS
#use delay (clock =4M)
static union {
unsigned int8 v;
struct {
unsigned int8 hi:4;
unsigned int8 lo:4;
} nibbles;
} byte_val;
void main (void ) {
byte_val.v = 0x0F;
byte_val.nibbles.hi = byte_val.nibbles.lo;
while (1);
} |
Turns into (with extraneous code removed.
Code: | ....................
.................... byte_val.v = 0x0F;
*
000F: MOVLW 0F
0010: MOVWF byte_val
....................
.................... byte_val.nibbles.hi = byte_val.nibbles.lo;
0011: MOVF byte_val,W
0012: SWAPF byte_val,W
0013: ANDLW 0F
0014: ANDLW 0F
0015: MOVWF @77
0016: MOVLW F0
0017: ANDWF byte_val,W
0018: IORWF @77,W
0019: MOVWF 20
....................
.................... while (1);
001A: GOTO 01A
.................... }
001B: SLEEP |
EDIT: I noticed the 18F code does not have the MOVF byte_val, W
SWAPF doesn't appear to need it... so PCM seems to include an extra instruction that maybe PCH has optimized out? _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|