CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Convert decimal to hex and then change the msb/lsb

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
iman_zahari



Joined: 20 Jul 2010
Posts: 15

View user's profile Send private message Yahoo Messenger

Convert decimal to hex and then change the msb/lsb
PostPosted: Sun Oct 10, 2010 2:33 am     Reply with quote

Good day all,

I'm using 16f877a for voltage/current measurement. However, to feed it into modbus, I need to convert to hex and then change the position of the msb with lsb.

It is a 10 bit adc resulting 1024 samplings. Say convert 502 decimal to 0x01F6 and then change it to 0xF601? It can't be done by shift position command. Lol. I know it's a stupid idea. Anyone got any good suggestion? Thanks in advance :D
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Oct 10, 2010 3:59 am     Reply with quote

ADC values are neither decimal nor hexadecimal, they are just binary. Decimal or hexadecimal are printable reprentations of the binary value.

Exchanging MSB and LSB of a 16 bit value can be done in different ways, with CCS C, it can be best done with built-in functions
Code:
outvar = make16(make8(invar,0),make8(invar,1));
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Sun Oct 10, 2010 4:59 am     Reply with quote

However there may be no point!.... Smile

I suspect the actual requirement, is to output the bytes in reverse order in hex, using printf/sprintf. In which case, just send the value as bytes with the order reversed, rather than 're-assembling' the number with the bytes swapped.
So:
Code:

    int16 val;
    val=502;

    printf("%02X%02X",make8(val,0),make8(val,1));


So you output the LSB first as a 2 digit hex value, then the MSB second, rather than changing the number itself.

Best Wishes
iman_zahari



Joined: 20 Jul 2010
Posts: 15

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Oct 10, 2010 5:18 am     Reply with quote

Ttelmah wrote:
However there may be no point!.... Smile

I suspect the actual requirement, is to output the bytes in reverse order in hex, using printf/sprintf. In which case, just send the value as bytes with the order reversed, rather than 're-assembling' the number with the bytes swapped.
So:
Code:

    int16 val;
    val=502;

    printf("%02X%02X",make8(val,0),make8(val,1));


So you output the LSB first as a 2 digit hex value, then the MSB second, rather than changing the number itself.

Best Wishes


Ohh, I see. Very efficient. I'll try first. Thanks for the suggestion. Really appreciate it.
iman_zahari



Joined: 20 Jul 2010
Posts: 15

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Oct 10, 2010 5:31 am     Reply with quote

FvM wrote:
ADC values are neither decimal nor hexadecimal, they are just binary. Decimal or hexadecimal are printable reprentations of the binary value.

Exchanging MSB and LSB of a 16 bit value can be done in different ways, with CCS C, it can be best done with built-in functions
Code:
outvar = make16(make8(invar,0),make8(invar,1));


Thanks for reminding me FvM. Totally forgot about it Smile. Thanks for the suggestion, I'll try it too.
iman_zahari



Joined: 20 Jul 2010
Posts: 15

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Oct 10, 2010 7:55 am     Reply with quote

FvM wrote:
ADC values are neither decimal nor hexadecimal, they are just binary. Decimal or hexadecimal are printable reprentations of the binary value.

Exchanging MSB and LSB of a 16 bit value can be done in different ways, with CCS C, it can be best done with built-in functions
Code:
outvar = make16(make8(invar,0),make8(invar,1));



YESSSSS! FvM, I love you so much. You're method worked!!! For Ttelmah, I tried yours but its a bit complicated. A bit mending and it looked similar to FvM's code. Thank you all!~
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sun Oct 10, 2010 9:00 am     Reply with quote

One of the favorite ways in the microchip libraries of manipulating data around like that is to use a structure:

Keep in mind, these are for Microchip compilers, so a little editing might be needed. (like the WORD == unsigned in16 for CCS instead of unsigned short int
Code:

typedef unsigned char           BYTE;                           /* 8-bit unsigned  */
typedef unsigned short int      WORD;                           /* 16-bit unsigned */


typedef union {
    WORD Val;
    BYTE v[2] __PACKED;
    struct __PACKED    {
        BYTE LB;
        BYTE HB;
    } byte;
    struct __PACKED    {
        BYTE b0:1;
        BYTE b1:1;
        BYTE b2:1;
        BYTE b3:1;
        BYTE b4:1;
        BYTE b5:1;
        BYTE b6:1;
        BYTE b7:1;
        BYTE b8:1;
        BYTE b9:1;
        BYTE b10:1;
        BYTE b11:1;
        BYTE b12:1;
        BYTE b13:1;
        BYTE b14:1;
        BYTE b15:1;
    } bits;
} WORD_VAL, WORD_BITS;


And then in their code they'll declare a var:

WORD_VAL adc_result;

And then

adc_result.Val = (command to read ADC)


Then for your printf,

printf("%02X%02X", adc_result.LB, adc_result.HB );
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Sun Oct 10, 2010 10:14 am     Reply with quote

Not actually the structure that matters here, it is the union.
Make8 is as efficient, but is 'CCS specific', and it makes it very easy to see what is going on, with something like:
Code:

union {
    int16 word;
    int8 b[2];
} value;
#define LSB (0)
#define MSB (1)

value.word=502;

printf("%02X%02X",b[LSB],b[MSB]);


The big advantage of this, is that it should work on any C, that defines an int8, and int16 type, and by just swapping LSB/MSB, will still work the same with chips that already have a reversed byte order.

The only advantage of doing it directly (my approach), over FvM's approach, is that you don't need another variable, and potentially it is a 'smidgeon' faster.

Best Wishes
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sun Oct 10, 2010 10:54 am     Reply with quote

Yep.

I just thought I'd toss it in so he has additional options, AND in case he looks at Microchip libraries anytime.

CCS makes some things very nice - but not exactly portable. Sometimes that's ok - sometimes it's a rear-cheek biter. But it's all about the tradeoff. So I'm not complaining. Just noting.

Cheers,

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group