Jump to content
Sign in to follow this  
Heimdall

Problems With Int*?

Recommended Posts

Hey everyone. I have an unsigned int*, and if the value there is 0x00E7, this evaluates as true:

 

*myThing == 0x13E7

 

Is there any reason why BoostC isn't bothering to compare the upper byte?

Share this post


Link to post
Share on other sites

Can't reproduce the problem. In the test code expression is evaluated as false (target 16F648A):

 

void main()
{
unsigned int val = 0x00E7, *ptr = &val;

char res = *ptr == 0x13E7;

while(1);
}

 

Maybe if you can provide code that demonstrates the problem we can be more helpful.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

void main()
{
unsigned int i;
unsigned int *settingHolder;
Init();

i = 200;

for (i = 200; i < 1000; i++)
{		
	settingHolder = &i;
	if (*settingHolder == 0x13E7) 
	{
		SetDisplayToNumber(0);
		break;
	}
	SetDisplayToNumber(i);
	delay_ms(250);
}


while (1);
}

 

 

Right after my display reads 230, it goes to 0. So *settingHolder is 231, or 0xE7, and the *settingHolder == 0x13E7 must be evaluating as true.

Share this post


Link to post
Share on other sites

I still can't reproduce the problem. I run your code (with some added stuff to make it compile) under debugger and the if-expression was never evaluated as true and as result line SetDisplayToNumber(0); was never executed:

 

#include <system.h>

void Init( void )
{
}

void SetDisplayToNumber( char a )
{
}

void main()
{
unsigned int i;
unsigned int *settingHolder;
Init();

i = 200;

for (i = 229; i < 1000; i++)
{		
	settingHolder = &i;
	if (*settingHolder == 0x13E7) 
	{
		SetDisplayToNumber(0);
		break;
	}
	SetDisplayToNumber(i);
	delay_ms(250);
}


while (1);
}

 

As I posted before you need to provide code that demonstrates the problem (what means that code should compile without any changes and also specify what compiler and what target you use). In many cases problem is somewhere else than people think it is.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Here's everything that I'm running on a PIC16F882 sitting right in front of me:

 

#include <system.h>

#pragma CLOCK_FREQ 4000000 //4MHz
#pragma DATA _CONFIG1, _LVP_ON & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT
#pragma DATA _CONFIG2, _WRT_OFF & _BOR40V


void main()
{   
unsigned int i;
unsigned int *sh;

trisa = 0;
porta = 0xFF;

i = 0x00E7;

sh = &i;

delay_s(2);

if (*sh == 0x13E7)
{
	porta.7 = 0;
}

while(1);

}

 

 

I have an LED on RA7. When i give the PIC power, it immediately turns on, as expected. Then, two seconds later, it shuts off.

 

If I replace the 'unsigned int's with 'int's, then the LED simply stays on.

 

It behaves the exact same way in the simulator.

Edited by Heimdall

Share this post


Link to post
Share on other sites
Here's everything that I'm running on a PIC16F882 sitting right in front of me:

 

#include <system.h>

#pragma CLOCK_FREQ 4000000 //4MHz
#pragma DATA _CONFIG1, _LVP_ON & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT
#pragma DATA _CONFIG2, _WRT_OFF & _BOR40V


void main()
{   
unsigned int i;
unsigned int *sh;

trisa = 0;
porta = 0xFF;

i = 0x00E7;

sh = &i;

delay_s(2);

if (*sh == 0x13E7)
{
	porta.7 = 0;
}

while(1);

}

 

 

I have an LED on RA7. When i give the PIC power, it immediately turns on, as expected. Then, two seconds later, it shuts off.

 

If I replace the 'unsigned int's with 'int's, then the LED simply stays on.

 

It behaves the exact same way in the simulator.

 

There is definitely a problem here. The problem is the high byte of *sh is compared with itself:

 

002E  1383	  BCF STATUS,IRP
002F  1823	  BTFSC main_1_sh+D'1',0
0030  1783	  BSF STATUS,IRP
0031  0822	  MOVF main_1_sh, W
0032  0084	  MOVWF FSR
0033  0800	  MOVF INDF, W
0034  3AE7	  XORLW 0xE7

0035  3013	  MOVLW 0x13						; High byte of constant

0036  1D03	  BTFSS STATUS,Z
0037  283D	  GOTO	label4

0038  0A84	  INCF FSR, F
0039  0800	  MOVF INDF, W					 ; High byte of constant is trashed!
003A  00A4	  MOVWF CompTempVar519
003B  0384	  DECF FSR, F

003C  0624	  XORWF CompTempVar519, W; Compares high byte of *sh with itself
003D		label4
003D  1903	  BTFSC STATUS,Z
003E  1385	  BCF gbl_porta,7

 

The 'int' case has problems too. It trashes the compare result of the low byte by testing the sign bit of *sh.

 

002E  1383	  BCF STATUS,IRP
002F  1823	  BTFSC main_1_sh+D'1',0
0030  1783	  BSF STATUS,IRP
0031  0822	  MOVF main_1_sh, W
0032  0084	  MOVWF FSR
0033  0800	  MOVF INDF, W
0034  3AE7	  XORLW 0xE7

0035  0A84	  INCF FSR, F		; Result of low byte compare is lost
0036  1B80	  BTFSC INDF,7
0037  283A	  GOTO	label4
0038  0384	  DECF FSR, F

0039  3013	  MOVLW 0x13
003A		label4
003A  1D03	  BTFSS STATUS,Z
003B  2841	  GOTO	label5

003C  0A84	  INCF FSR, F
003D  0800	  MOVF INDF, W
003E  00A4	  MOVWF CompTempVar519
003F  0384	  DECF FSR, F
0040  0624	  XORWF CompTempVar519, W; High byte is compared with itself as for unsigned case
0041		label5
0041  1903	  BTFSC STATUS,Z
0042  1385	  BCF gbl_porta,7

 

If you force the constant to be int [if (*sh == (int)0x13E7)], then the code generated is the same as the unsigned int case and fails to compare the high byte.

 

Orin.

Share this post


Link to post
Share on other sites

Workaround:

 

Assign your constant to a variable and use it in the compare. It even generates shorter code!

 

Orin.

 

unsigned int j;

void main()
{   
 unsigned int i;
 unsigned int *sh;

trisa = 0;
porta = 0xFF;

j = 0x13E7;


i = 0x00E7;


sh = &i;

delay_s(2);

if (*sh == j)
{
	porta.7 = 0;
}

while(1);

}

Share this post


Link to post
Share on other sites

Ok, good. I thought I was going crazy. Thanks! (I need to brush up on my assembly. I've got some HC12 in my brain from a Microprocessor Systems class, but that's about it.)

 

So. Compiler bug, I guess?

Share this post


Link to post
Share on other sites
Ok, good. I thought I was going crazy. Thanks! (I need to brush up on my assembly. I've got some HC12 in my brain from a Microprocessor Systems class, but that's about it.)

 

So. Compiler bug, I guess?

 

 

Can reproduce the problem now:

 

void main()
{   
unsigned int i = 0x00E7;
unsigned int *sh = &i;

if (*sh == 0x13E7)
{
	asm nop
}

while(1);	
}

 

Looks like compiler prob. Will investigate.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Is there a compiler problem with the 16F882? I'm trying to use it, but am getting nowhere and I'm not sure if it's the programmer or the compiler.

 

This is the code I'm using to test the chip - compiles fine, programs fine, but produces no output, all ports except Vdd are 0.

 

#include <system.h>
#pragma DATA _CONFIG, _MCLRE_OFF & _WDT_OFF & _INTOSC & _PWRTE_OFF & _LVP_OFF

void main()
{

trisa = 0b00000000;
trisb = 0b00000000;
trisc = 0b00000000;
porta = 0b11111111;
portb = 0b11111111;
portc = 0b11111111;
ansel = 0b00000000;
anselh = 0b00000000;

while(1)
{
	portb.5 = 1;
}
}

Edited by dersk

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...