Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

byte programming with union function with C

Status
Not open for further replies.

mechguy

Newbie level 5
Newbie level 5
Joined
Jan 17, 2012
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,355
Hello everyone,

Currently I'm doing an embedded project with byte programming with C. The following is the program:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
void main ()
{
    long velocity;
 
    union
    {
        int NUMvelo;
        int byte[2];
    } CURRENTvelo;
 
    CURRENTvelo.byte[0] = 200 * 256;
    CURRENTvelo.byte[1] = 130;
    
    velocity = CURRENTvelo.NUMvelo;
 
    printf("%u\n", velocity);
}



I expect the velocity value will be 200*256+130 = 51330

But instead, it shows result of 200*256 = 51200

Anyone knows how to solve this problem? Would kindly appreciate any help and suggestion. ;-)
 
Last edited by a moderator:

NUMvelo must have double the bit size for this to work but you use the same integer type.

If integer is 16bit use long int (32bit) for NUMvelo

Also make sure that your variables are unsigned

Alex

---------- Post added at 00:12 ---------- Previous post was at 00:10 ----------

Take a look at https://www.edaboard.com/threads/204950/#post864262
 

Hi

You probably already know that in union only one member exist at a time (sort of) while you are storing values in one type of data (byte) and trying to read other which is wrong

To get an idea how compiler is handling it look at the generated assembly code

take care



Hello everyone,

Currently I'm doing an embedded project with byte programming with C. The following is the program:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
void main ()
{
    long velocity;
 
    union
    {
        int NUMvelo;
        int byte[2];
    } CURRENTvelo;
 
    CURRENTvelo.byte[0] = 200 * 256;
    CURRENTvelo.byte[1] = 130;
    
    velocity = CURRENTvelo.NUMvelo;
 
    printf("%u\n", velocity);
}



I expect the velocity value will be 200*256+130 = 51330

But instead, it shows result of 200*256 = 51200

Anyone knows how to solve this problem? Would kindly appreciate any help and suggestion. ;-)
 

Hi

You probably already know that in union only one member exist at a time (sort of) while you are storing values in one type of data (byte) and trying to read other which is wrong

take care

I disagree with your definition of wrong, the fact that all the variables are located in the same memory space can be very useful to combine or break a variable in parts.
See https://www.edaboard.com/threads/204950/#post864603
 

The original code assumes that sizeof(int) == 2, so try this:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
void main ()
{
    long velocity;
 
    union
    {
        int NUMvelo;
        unsigned char byte[2];
    } CURRENTvelo;
 
    CURRENTvelo.byte[0] = 200; // Swap the byte values if you are on a little-endian machine.
    CURRENTvelo.byte[1] = 130;
    
    velocity = CURRENTvelo.NUMvelo;
 
    printf("%ld\n", velocity); // changed from "%u" which is for "unsigned int"
}

 
hello,


you must make an union with an integer and two unsigned bytes !
not two integer!
i tested with ultoa for printing output value
because printf doesn't work correctly with mt C18 ( even with stdio.h)

Code:
long velocity;

union
{
unsigned int NUMvelo;
unsigned char  byte[2];
} CURRENTvelo;




 //------ TESTS ----------------


CURRENTvelo.byte[0] = 130;  //LSB
CURRENTvelo.byte[1] = 200;  // MSB
velocity = CURRENTvelo.NUMvelo;

ultoa(velocity,txt);
k=PutStr_RS(txt);
CRLF();


result is 51330 !

---------- Post added 11-05-12 at 00:31 ---------- Previous post was 10-05-12 at 23:53 ----------

hello,

Yes ,as std_match wrote .
printf works OK with %ld instead %u in C18 Mplab for a long integer.
 

alexan_e you are right here but what if one union member is int and other is float. so i dont know if it is a good programming practice to split or combine int and char. i would rather use bit manipulation to split or merge bits n bytes
 

When you use a union to make an operations like I have described you are supposed to use proper types too.
Split or combine using union will use less resources and will be faster.
Anyway, there are many ways to do some operations in C and it's up to the programmer to decide the code style he feels comfortable with.
 

i dont want to over stretch it but there could be an endian issue as well. for example data received over the ethernet and transmitted to uart or spi etc
 

mmuj said:
there could be an endian issue as well. for example data received over the ethernet and transmitted to uart or spi etc
I think that this could be observed only when bitfields are used, but in this case structures also suffer from the same issue as well.
It is possible that standard C defines endianness, but in any case precompiler where available can be used to fix this and make the application portable from this aspect. Same stands for alignment and packing.
A bit dangerous to use unions if they are accessed from mulitiple points of the program, but can reduce code size, execution time, a useful tool in general.
As for protocols, in high level part of code it is possible to process the received values, but after processed data are placed in a buffer, they can be sent in another bus. Let's not forget that modern MCUs offer the ability to hardware define endianness in some cases, like SPI for instance.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top