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.

Two 8-bit chars into a 16-bit number

Status
Not open for further replies.

brucelee2

Member level 2
Joined
Aug 22, 2009
Messages
49
Helped
6
Reputation
12
Reaction score
3
Trophy points
1,288
Location
on a PCB
Activity points
1,638
Hi,

I have a HMI which sends two 8-bit chars which represent a 16-bit touch screen coordinate.
So in an example, the HMI sends:
0X03 then 0X0E (both seperate) which represent the coordinate 030E (782).

How can i combine the two into a single variable to represent the number 782? I was thinking of creating a 'int' and shifting each into it some how.

ie.

char first = 0x03;
char second = 0x0E;
int number;

number=first;
number=number<<8;
---Now im stuck---



Any Ideas?
Thanks a lot.:D
 

C has bitwise OR operation for similar purposes
Code:
number = (int)first << 8 | second;
Declaring a union is another common way, some compilers have special functions for it, e.g. CCS C make16().
 

    brucelee2

    Points: 2
    Helpful Answer Positive Rating
Oh ok. Im using MikroC, so ill consult the manual to see if there is such a function in the compiler.

thanks again
 

better if you declare all unsigned (unsigned char and unsigned int) on data declaration and data casting... so

Code:
unsigned char first = 0x03;
unsigned char second = 0x0E;
unsigned int number; 

...


number = (unsigned int)first << 8 | second;

will have less problems...
{problem arise when you cast a signed char to int like 0xe0 for 'second', will be casted to 0xFFE0 and not 0x00E0... try it!}
 

    brucelee2

    Points: 2
    Helpful Answer Positive Rating
alternatively, you can use union - which requires no coding on your part.

or a macro:
Code:
#define WORD(msb, lsb)  (((msb) << 8) | (lsb))

Code:
number = (unsigned int)first << 8 | second;

you probably want to use more brackets there to prevent the '|' operator to be executed before the left shift.
 

    brucelee2

    Points: 2
    Helpful Answer Positive Rating
you probably want to use more brackets there to prevent the '|' operator to be executed before the left shift.
Only if you're not aware of ANSI C operator precedence rules, I think.
problem arise when you cast a signed char to int like 0xe0 for 'second'
It's not correctly handled by all compilers, but arithmetic type conversion is required for bitwise OR by the specification. Thank you for the correction.
 

    brucelee2

    Points: 2
    Helpful Answer Positive Rating
As you use mikroC

unsigned int myInt ;

hi(myInt) = 0x03 ;
lo(myInt) = 0x0E ;

Its whole lot easier that way.

jack
 

you can store First(Low Byte) at the base address of the int variable then store second byte @ (int base address +1) then call/use 16 bit integer
use these macros

#define Low(c) (*(unsigned char *)&(c))
#define High(c) (*((unsigned char *)&(c)+1))

char a=0x30;
char b=0x53;
int data;
Low(data)=a;
High(data)=b;

now use data as 16 bit number

Hope you find the answer
 

use the Union,like below:
union
{
char a[2];
int b;
}number;

number.a[0]=0x03;number.a[1]=0x0E;

then, number.b=0x030E,
it just costs two bytes of ram , not four bytes.
 

if you have some free bits? try this:

number = 0;
number |=first;
number<<8;
number |=second;
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top