two char to one int

Discussion in 'Embedded Systems and Microcontrollers' started by murph909, Apr 27, 2011.

  1. murph909

    Thread Starter New Member

    Apr 24, 2011
    9
    0
    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
     
  2. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    What kind of programming language do you use.
     
  3. murph909

    Thread Starter New Member

    Apr 24, 2011
    9
    0
    c programming, not c++
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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
    Code ( (Unknown Language)):
    1.  
    2. union tempdata
    3. {
    4. int temprature
    5. char rawdata[2]
    6. }
    7.  
    You modify by doing some like this as an crude example
    Code ( (Unknown Language)):
    1.  
    2. tempdata.rawdata[0]=0b0000 0101;
    3. tempdata.rawdata[1]=0b1011 0111;
    4. printf(“%d”,tempdata.temprature);
    5.  
    I guess google may fill in the rest if needed
     
  5. murph909

    Thread Starter New Member

    Apr 24, 2011
    9
    0
    Figured it out, its

    c = (a << 8) + b;
     
  6. HallMark

    Member

    Apr 3, 2011
    89
    5
    you have to shift a 8 times then oring it with B will work.
     
  7. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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
     
  8. cheezewizz

    Active Member

    Apr 16, 2009
    82
    10
    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...
     
  9. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    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.
     
  10. cheezewizz

    Active Member

    Apr 16, 2009
    82
    10
    ah that makes sense, cheers
     
  11. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    I did a simple test on the two methods this is the result. Using HI-Tech C compiler. With full compiler optimalization
    Code ( (Unknown Language)):
    1.  
    2. 1:                 #include <htc.h>
    3. 2:                 void main(void)
    4. 3:                 { // port directions: 1=input, 0=output
    5. 4:                  TRISB = 0xff;
    6.    3EA    30FF     MOVLW 0xff
    7.    3EB    1683     BSF 0x3, 0x5
    8.    3EC    0086     MOVWF 0x6
    9. 5:                  union
    10. 6:                  {
    11. 7:                   volatile int temprature;
    12. 8:                   volatile char rawdata[2];
    13. 9:                  }tempdata;
    14. 10:                    volatile int temp;
    15. 11:                    volatile char a;
    16. 12:                    volatile char b;
    17. 13:                    //Union method
    18. 14:                 tempdata.rawdata[0]=PORTB;
    19.    3ED    1283     BCF 0x3, 0x5
    20.    3EE    0806     MOVF 0x6, W
    21.    3EF    0090     MOVWF 0x10
    22. 15:                    tempdata.rawdata[1]=PORTB;
    23.    3F0    0806     MOVF 0x6, W
    24.    3F1    0091     MOVWF 0x11
    25. 16:                    //tempdata.temprature now holds the correct value
    26. 17:                    //the other way
    27. 18:                    a=PORTB;
    28.    3F2    0806     MOVF 0x6, W
    29.    3F3    008F     MOVWF 0xf
    30. 19:                    b=PORTB;
    31.    3F4    0806     MOVF 0x6, W
    32.    3F5    008E     MOVWF 0xe
    33. 20:                    temp = (a << 8) + b;
    34.    3F6    080F     MOVF 0xf, W
    35.    3F7    008D     MOVWF 0xd
    36.    3F8    018C     CLRF 0xc
    37.    3F9    080E     MOVF 0xe, W
    38.    3FA    078C     ADDWF 0xc, F
    39.    3FB    1803     BTFSC 0x3, 0
    40.    3FC    0A8D     INCF 0xd, F
    41. 21:                   //temp now holds the correct value
    42. 22:                   a=PORTB;//just some code to mark the end of test part
    43.    3FD    0806     MOVF 0x6, W
    44.    3FE    008F     MOVWF 0xf
    45. 23:                }
    46.  
    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
    Code ( (Unknown Language)):
    1.  
    2. 1:                 #include <htc.h>
    3. 2:                 void main(void)
    4. 3:                 { // port directions: 1=input, 0=output
    5. 4:                  TRISB = 0xff;
    6.    3D9    30FF     MOVLW 0xff
    7.    3DA    1683     BSF 0x3, 0x5
    8.    3DB    0086     MOVWF 0x6
    9. 5:                  union
    10. 6:                  {
    11. 7:                   volatile int temprature;
    12. 8:                   volatile char rawdata[2];
    13. 9:                  }tempdata;
    14. 10:                    volatile int temp;
    15. 11:                    volatile char a;
    16. 12:                    volatile char b;
    17. 13:                    //Union method
    18. 14:                 tempdata.rawdata[0]=PORTB;
    19.    3DC    1283     BCF 0x3, 0x5
    20.    3DD    0806     MOVF 0x6, W
    21.    3DE    008C     MOVWF 0xc
    22.    3DF    080C     MOVF 0xc, W
    23.    3E0    0092     MOVWF 0x12
    24. 15:                    tempdata.rawdata[1]=PORTB;
    25.    3E1    0806     MOVF 0x6, W
    26.    3E2    008C     MOVWF 0xc
    27.    3E3    080C     MOVF 0xc, W
    28.    3E4    0093     MOVWF 0x13
    29. 16:                    //tempdata.temprature now holds the correct value
    30. 17:                    //the other way
    31. 18:                    a=PORTB;
    32.    3E5    0806     MOVF 0x6, W
    33.    3E6    008C     MOVWF 0xc
    34.    3E7    080C     MOVF 0xc, W
    35.    3E8    0091     MOVWF 0x11
    36. 19:                    b=PORTB;
    37.    3E9    0806     MOVF 0x6, W
    38.    3EA    008C     MOVWF 0xc
    39.    3EB    080C     MOVF 0xc, W
    40.    3EC    0090     MOVWF 0x10
    41. 20:                    temp = (a << 8) + b;
    42.    3ED    0811     MOVF 0x11, W
    43.    3EE    008C     MOVWF 0xc
    44.    3EF    018D     CLRF 0xd
    45.    3F0    080C     MOVF 0xc, W
    46.    3F1    008D     MOVWF 0xd
    47.    3F2    018C     CLRF 0xc
    48.    3F3    0810     MOVF 0x10, W
    49.    3F4    070C     ADDWF 0xc, W
    50.    3F5    008E     MOVWF 0xe
    51.    3F6    3000     MOVLW 0
    52.    3F7    1803     BTFSC 0x3, 0
    53.    3F8    3001     MOVLW 0x1
    54.    3F9    070D     ADDWF 0xd, W
    55.    3FA    008F     MOVWF 0xf
    56. 21:                   //temp now holds the correct value
    57. 22:                   a=PORTB;//just some code to mark the end of test part
    58.    3FB    0806     MOVF 0x6, W
    59.    3FC    008C     MOVWF 0xc
    60.    3FD    080C     MOVF 0xc, W
    61.    3FE    0091     MOVWF 0x11
    62. 23:                }
    63.  
     
Loading...