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

Union + Structure = me go crazy

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



Joined: 11 Jan 2006
Posts: 21
Location: Quebec (Canada)

View user's profile Send private message Visit poster's website

Union + Structure = me go crazy
PostPosted: Wed Dec 22, 2010 8:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 22, 2010 8:53 am     Reply with quote

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)

View user's profile Send private message Visit poster's website

PostPosted: Wed Dec 22, 2010 8:59 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 22, 2010 9:13 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 22, 2010 11:14 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Dec 26, 2010 2:15 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Dec 26, 2010 3:41 pm     Reply with quote

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
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