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

16 bit variables

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



Joined: 14 Mar 2004
Posts: 3
Location: Sydney, Australia

View user's profile Send private message

16 bit variables
PostPosted: Sun Mar 14, 2004 3:01 am     Reply with quote

Hi,

I am using an older version of the PCW compiler (CCS PCW C Compiler, Version 2.669, 6859) and am having a problem with 16 bit (long) variables.

I have to parse data out from an ASCII string and extract 16 bit words.
I have no problem extracting and converting the high and low bytes. The problem arises when I try to combine them into a single 16 bit variable.

I have two bytes, char bh; and char bl;. I also have a local variable which is declared as: long wd;

When I try to combine the two I get really strange looking code:

Code:
000                01057 ....................       wd = (bh << 8) | bl;
0144 0100           01058 CLRW
0145 00A0           01059 MOVWF  20
0146 01A3           01060 CLRF   23
0147 0820           01061 MOVF   20,W
0148 0479           01062 IORWF  79,W
0149 00FE           01063 MOVWF  7E


The compiler has placed the 'wd' variable at address 0x7e & 0x7f. This is perfectly good and valid, but it really appears to make a hash of the code generation for the formation of the word.

Has anyone else encountered this problem before, and if so, what is the fix or workaround for it.

Any help gratefully received.

Regards,
Gerry
Ttelmah
Guest







Re: 16 bit variables
PostPosted: Sun Mar 14, 2004 3:40 am     Reply with quote

gerryc wrote:
Hi,

I am using an older version of the PCW compiler (CCS PCW C Compiler, Version 2.669, 6859) and am having a problem with 16 bit (long) variables.

I have to parse data out from an ASCII string and extract 16 bit words.
I have no problem extracting and converting the high and low bytes. The problem arises when I try to combine them into a single 16 bit variable.

I have two bytes, char bh; and char bl;. I also have a local variable which is declared as: long wd;

When I try to combine the two I get really strange looking code:

Code:
000                01057 ....................       wd = (bh << 8) | bl;
0144 0100           01058 CLRW
0145 00A0           01059 MOVWF  20
0146 01A3           01060 CLRF   23
0147 0820           01061 MOVF   20,W
0148 0479           01062 IORWF  79,W
0149 00FE           01063 MOVWF  7E


The compiler has placed the 'wd' variable at address 0x7e & 0x7f. This is perfectly good and valid, but it really appears to make a hash of the code generation for the formation of the word.

Has anyone else encountered this problem before, and if so, what is the fix or workaround for it.

Any help gratefully received.

Regards,
Gerry

Unions.
If you declare your variable as:

[code]
union {
int b[2];
long w;
} val;
[code]
Then you can just write your low and high bytes into val.b[0], and
val.b[1] directly (potentially you don't need the seperate 'char' variables. The whole 16bit word is available as val.w
This generates nice 'tight' code, and avoids the compiler in having to worry about the implications of rotations etc..
The code being generated, may be 'right'. It'd be worth looking at the previous few lines to see if 79, may have been used as a 'scratch' variable and hold a duplicate of the high byte allready. If so the code then makes sense.

Best Wishes
Guest








PostPosted: Sun Mar 14, 2004 5:27 pm     Reply with quote

Hi,

Thanks for the response. I tried your suggestion and it worked well.
The only problem is that I now need to assign the value to an entry in an array of longs. This fails miserably.
My client is insisting that I use this compiler for a job, and until now I was more than happy to do so.
I am now ready to toss the thing into the 'circular filing cabinet'.
Any compiler that cannot properly handle integral types, a really basic requirement, probably has a hell of a lot more serious problems elsewhere.

Simple constructs like the one I was originally using are as basic to C as one can get. I would rather lose the contract than have to kludge code semantics to get such basic operations to work. Life is too short.

Oh well, back to the good ole Hi-Tech compiler.

Regards,

Gerry
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 14, 2004 6:35 pm     Reply with quote

Quote:
I am using an older version of the PCW compiler (CCS PCW C Compiler, Version 2.669, 6859) and am having a problem with 16 bit (long) variables.

Vs. 2.669 came out in June 1999. It's very old.
However, even with a current version (PCM 3.184), at a minimum,
you still have to cast "bh" to a long, to make it work. Those of us
who use the compiler know this, so it's not really a problem.

Code:
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//=============================================
void main(void)
{
long wd;
char bh;
char bl;

bh = 0x12;
bl = 0x34;
wd = (bh << 8) | bl;
printf("%lx \n\r", wd);   // Gives:  0034

bh = 0x12;
bl = 0x34;
wd = ((long)bh << 8) | bl;
printf("%lx \n\r", wd);   // Gives:  1234

while(1);
}
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