two char to one int

Thread Starter

murph909

Joined Apr 24, 2011
9
i am writing a c program using mplab and pic16f887, with the pickit2. I have a tc77, which outputs a temperature in 16 bits. I have it outputing two sets of 8 bits each, and each set will go to char a or char b. I need to take char a and char b and combine them, but not add them.

Example:
Char a: 0000 0101
Char b: 1011 0111
I need to take both char's, and put them to an int so that int c looks like this:
Int c: 0000 0101 1011 0111

I cant figure out exactly how to do this.
Any ideas?

Thanks
 

t06afre

Joined May 11, 2009
5,934
Ah.. check out the Union Declaration. Unions like structure contain members whose individual data types may differ from one another. However the members that compose a union all share the same storage area within the memory where as each member within a structure is assigned its own unique storage area.
It should be something like this
Rich (BB code):
union tempdata
{
int temprature
char rawdata[2]
}
You modify by doing some like this as an crude example
Rich (BB code):
tempdata.rawdata[0]=0b0000 0101;
tempdata.rawdata[1]=0b1011 0111;
printf(“%d”,tempdata.temprature);
I guess google may fill in the rest if needed
 

t06afre

Joined May 11, 2009
5,934
you have to shift a 8 times then oring it with B will work.
That will depend on the compiler. Many modern compilers are quite smart and can recognize and optimize. So they do not translate your code literally. Then writing code for MCUs it is important to look at the generated assembler code. The code I presented will work directly on the memory. With no such thing as integral promotion or other forms cycle wasting. It is not given that the shortest code in C will give smallest code footprint on the MCU
 

AlexR

Joined Jan 16, 2008
732
Correct me if i'm wrong, but won't shifting a char left 8 places just leave you with 0? t06afre has a good solution...
You are not shifting the character, you are loading the char a into the lower byte of the integer c and shifting that 8 places so it ends up in the upper byte of c, then adding char b puts it in the lower byte of c.
 

t06afre

Joined May 11, 2009
5,934
I did a simple test on the two methods this is the result. Using HI-Tech C compiler. With full compiler optimalization
Rich (BB code):
1:                 #include <htc.h>
2:                 void main(void)
3:                 { // port directions: 1=input, 0=output
4:                  TRISB = 0xff;
   3EA    30FF     MOVLW 0xff
   3EB    1683     BSF 0x3, 0x5
   3EC    0086     MOVWF 0x6
5:                  union 
6:                  {
7:                   volatile int temprature;
8:                   volatile char rawdata[2];
9:                  }tempdata;
10:                    volatile int temp;
11:                    volatile char a;
12:                    volatile char b;
13:                    //Union method
14:                 tempdata.rawdata[0]=PORTB;
   3ED    1283     BCF 0x3, 0x5
   3EE    0806     MOVF 0x6, W
   3EF    0090     MOVWF 0x10
15:                    tempdata.rawdata[1]=PORTB;
   3F0    0806     MOVF 0x6, W
   3F1    0091     MOVWF 0x11
16:                    //tempdata.temprature now holds the correct value
17:                    //the other way
18:                    a=PORTB;
   3F2    0806     MOVF 0x6, W
   3F3    008F     MOVWF 0xf
19:                    b=PORTB;
   3F4    0806     MOVF 0x6, W
   3F5    008E     MOVWF 0xe
20:                    temp = (a << 8) + b; 
   3F6    080F     MOVF 0xf, W
   3F7    008D     MOVWF 0xd
   3F8    018C     CLRF 0xc
   3F9    080E     MOVF 0xe, W
   3FA    078C     ADDWF 0xc, F
   3FB    1803     BTFSC 0x3, 0
   3FC    0A8D     INCF 0xd, F
21:                   //temp now holds the correct value
22:                   a=PORTB;//just some code to mark the end of test part
   3FD    0806     MOVF 0x6, W
   3FE    008F     MOVWF 0xf
23:                }
If I turn off optimation, so the compiler works in "free mode". Notice the difference between the two methods. The union method is much the same but that is not the case for the temp = (a << 8) + b method. So as I said it is not always the smallest C code that gives the smallest code footprint
Rich (BB code):
1:                 #include <htc.h>
2:                 void main(void)
3:                 { // port directions: 1=input, 0=output
4:                  TRISB = 0xff;
   3D9    30FF     MOVLW 0xff
   3DA    1683     BSF 0x3, 0x5
   3DB    0086     MOVWF 0x6
5:                  union 
6:                  {
7:                   volatile int temprature;
8:                   volatile char rawdata[2];
9:                  }tempdata;
10:                    volatile int temp;
11:                    volatile char a;
12:                    volatile char b;
13:                    //Union method
14:                 tempdata.rawdata[0]=PORTB;
   3DC    1283     BCF 0x3, 0x5
   3DD    0806     MOVF 0x6, W
   3DE    008C     MOVWF 0xc
   3DF    080C     MOVF 0xc, W
   3E0    0092     MOVWF 0x12
15:                    tempdata.rawdata[1]=PORTB;
   3E1    0806     MOVF 0x6, W
   3E2    008C     MOVWF 0xc
   3E3    080C     MOVF 0xc, W
   3E4    0093     MOVWF 0x13
16:                    //tempdata.temprature now holds the correct value
17:                    //the other way
18:                    a=PORTB;
   3E5    0806     MOVF 0x6, W
   3E6    008C     MOVWF 0xc
   3E7    080C     MOVF 0xc, W
   3E8    0091     MOVWF 0x11
19:                    b=PORTB;
   3E9    0806     MOVF 0x6, W
   3EA    008C     MOVWF 0xc
   3EB    080C     MOVF 0xc, W
   3EC    0090     MOVWF 0x10
20:                    temp = (a << 8) + b; 
   3ED    0811     MOVF 0x11, W
   3EE    008C     MOVWF 0xc
   3EF    018D     CLRF 0xd
   3F0    080C     MOVF 0xc, W
   3F1    008D     MOVWF 0xd
   3F2    018C     CLRF 0xc
   3F3    0810     MOVF 0x10, W
   3F4    070C     ADDWF 0xc, W
   3F5    008E     MOVWF 0xe
   3F6    3000     MOVLW 0
   3F7    1803     BTFSC 0x3, 0
   3F8    3001     MOVLW 0x1
   3F9    070D     ADDWF 0xd, W
   3FA    008F     MOVWF 0xf
21:                   //temp now holds the correct value
22:                   a=PORTB;//just some code to mark the end of test part
   3FB    0806     MOVF 0x6, W
   3FC    008C     MOVWF 0xc
   3FD    080C     MOVF 0xc, W
   3FE    0091     MOVWF 0x11
23:                }
 
Top