|
|
View previous topic :: View next topic |
Author |
Message |
gerryc
Joined: 14 Mar 2004 Posts: 3 Location: Sydney, Australia
|
16 bit variables |
Posted: Sun Mar 14, 2004 3:01 am |
|
|
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 |
Posted: Sun Mar 14, 2004 3:40 am |
|
|
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
|
|
Posted: Sun Mar 14, 2004 5:27 pm |
|
|
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
|
|
Posted: Sun Mar 14, 2004 6:35 pm |
|
|
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);
} |
|
|
|
|
|
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
|