  | 
	  | 
		 
	 
	
		| 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
  
		 |