Topic : Structs & union

Forum : 8051

Original Post
Post Information Post
May 30, 2011 - 3:34pm
Guest

Hi, My question is that this code have been working for IAR and other compilers but it doesn’t work with Rkit(80C51)
Or maybe it is some kind of setup that I have missed. The project is running under Silabs IDE where Raisonance
Is invoked with parameters etc..

The code is quit simple and to begin with this header file where I declare my struct/union

---------------------------------------------------------------------------------------------------------------------------------------------
struct spibytes // struct containing 2 bytes
{
unsigned char lo; // low byte
unsigned char hi; // high byte
};
union spi_
{ // high + low byte
unsigned int w; // 1 unsigned integer
struct spibytes b; // that will contain 2 bytes
};

extern idata union spi_ spi; // declare union extern(must be declared once)

Now in my c file I declare

#include "data_struct.h" // the file above
idata union spi_ spi; // declare union extern(must be declared once)

and everything is working when compiled and linked !.

but in my code where I wan’t to split an integer I for instance write it like spi.w = adr;(adr is an unsigned integer ex 0x02E0)
At this point the value of spi.w is the same as for adr. So that’s ok BUT when looking at spi.b.hi = 0 and also spi.b.lo = 0
And it should be spi.b.hi = 0x02 and spi.b.lo = 0xE0.

On the other hand when assigning spi.b.hi = 0x02 and spi.b.lo = 0xE0 the I see that spi.w = 0xE002(swapped byte)

As stated this is working but not here so any suggestions ?

Regards
cks

Replies
Post Information Post
+1
0
-1
May 30, 2011 - 3:53pm
Raisonance Support Team

Hi Claes,

Thanks for your report.

Maybe there is some misunderstanding concerning the byte ordering on different architectures.
On 8051 you have a big endian architecture, meaning that the bytes ordering in memory is "natural": The most significant byte of an object comes first (with the lowest address).

So in your code the lo and hi fields come inverted.

I set up a quick example that works:

struct spibytes                         // struct containing 2 bytes
{
    unsigned char lo;                   // low byte
    unsigned char hi;                   // high byte
};

union spi_
{                                       // high + low byte
    unsigned int    w;                  // 1 unsigned integer
    struct spibytes b;                  // that will contain 2 bytes
};

volatile idata union spi_ spi;          // volatile prevents some optimisations for easier debug

unsigned long l = 0x01020304;

void main(void)
{
    spi.w = 0x1234;
    while(spi.w != 0x1234);
    spi.b.lo = 0x55;
    while(spi.w != 0x5534);
    spi.b.hi = 0x66;
    while(spi.w != 0x5566);
        
    while(1);
}

The code runs to completion, meaning that all the lines have been properly executed.

If you have further questions on this issue, can you please send us a project that shows the problem?

Best Regards,

+1
0
-1
May 30, 2011 - 5:36pm
Guest

Hi,

Well, the main problem remaines even though the swap between hi & lo was explained.
When spi.w = 0x1234 then spi.b.hi = 0x00 and spi.b.lo = 0x00 but if I write directely

spi.b.hi = 0x12 and spi.b.lo = 0x34 then spi.w = 0x1234;

Regards
CKS

+1
0
-1
May 31, 2011 - 10:17am
Raisonance Support Team

Claes,

The example in my reply above clearly shows that assigning values to spi.b.hi and spi.b.lo does work!
In the example we have "spi.b.lo = 0x55;" and "spi.b.hi = 0x66;" which work perfectly so for me there is no problem.

Bruno wrote:
If you have further questions on this issue, can you please send us a project that shows the problem?

Best Regards,