Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

C18 Confusion

Status
Not open for further replies.

Wilksey

Member
Hi,

Can somebody please explain to me why the following works using DEV-C++:

Code:
char bit1=0x01;
long whole = bit1 << 8;
printf("WHOLE = %x\r\n",whole);

And the result is WHOLE = 100

But when I run it in C18 all I get is 0? Even tried changing the long to an int and the char to unsigned etc, just returns 0!

Code:
whole = (0x01 << 8);
printf("WHOLE = %x\r\n",whole);
prints WHOLE = 0 to the UART!

And, if I have a function like this:
Code:
void get_val(char *sp)
//assume that (sp[0] = 0x68 and sp[1] = 0x01)
whole = (sp[1] << 8);
printf("WHOLE = %x\r\n",whole);
I get WHOLE = 8

Anybody see anything wrong with what I am doing?

Regards

Wilksey
 
This is due to the way C18 does calculations with constants. It assumes that they are 8 bit and does the whole calculation in 8 bit mode. You can fig it by adding a compiler switch (-Oi). See post 4 of this thread for more info. Note, casting will produce smaller code than the command line switch.

edit, this should work,
Code:
char bit1=0x01;
long whole = [COLOR="red"](int)[/COLOR]bit1 << [COLOR="red"](int)[/COLOR]8;
printf("WHOLE = %x\r\n",whole);

Mike.
 
Last edited:
Hi Mike,

Thanks for the reply!

Unfortunately casting or adding the -Oi- option worked, still displays either 8 or 0, not 100 as the Dev-C++ Code.

Wilksey
 
Turns out, you cant just add the -Oi option, this doesn't work.

You have to select the promote integer option, maybe it's because it adds the command line option to the beginning of the command line?

Anyways, seems to be working a bit better now! So thanks again Mike.

It wont seem to do negative values now, they are all signed variables, but the negatives just come back as fffe for example.

Wilksey
 
Ok, last problem, for now! lol.

I am trying to read the temperature from the DS1822 sensor, the temperature seems to be reading back, although on the C18 and the Swordfish code I dont get a correct reading until the 2nd pass of the reading, maybe it's cause it's being simulated on Proteus? Read HW samples comming soon hopefully!

Anyway, the problem now is that i cant get the code to return negative values!

Posted below the code from the function, the sp data input is the 2 temperature bytes that get read in sp[0] sp[1].

Code:
	unsigned char tempC[] = "000.0\r\n";
	unsigned char tempF[] = "000.0\r\n";
	signed int whole = 0, temp = 0;
	signed int LSB = 0;
	signed int frac = 0;
	int CNeg = 0;
	whole = ((sp[1] << 8) + (sp[0] & 0xff) >> 4);
	LSB = sp[0] & 0xF;
	frac = LSB * 625;
	if (whole & 0x8000) { 
		tempC[0] = '-'; 
		// Negative temp values are stored in 2's complement form 
		whole = ~whole + 1; 
		CNeg = 1;
	}
	else tempC[0] = ' ';
	if ((whole/100) && CNeg == 0)
	{	
		tempC[0] = whole/100 + 48;
		temp = (int)(whole / 100) * 100;
		whole -=temp;
	}
	tempC[1] = (whole/10) + 48;
	temp = (int)(whole / 10) * 10;
	whole -= temp;
	tempC[2] = whole + 48;
	tempC[4] = (frac / 1000) + 48;
	PutString(tempC);

I got the negative checking code from somewhere else, though the Dev-C++ version of this code can work without that check!

On Dev-C++
Code:
     char bit1 = 0xC0; 
     char bit2 = 0xFE; 
     long bigbit = (bit2 << 8) + (bit1 & 0xff) >> 4;
     char LSB = bit1 & 0xF;
     long frac = LSB * 625;
returns bigbit as -20 and frac as 0, which is -20.0, which is correct.

The same code in C18 produces:

Wilksey
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top