Help with Simple Code Please!

Thread Starter

GammaRay86

Joined Dec 9, 2007
14
Hey guys,

I'm having some trouble with some math code used for my PIC16F684.

Rich (BB code):
int16 PV, SP;
int16 E0;
uns8 gain;
int16 output;							
uns16 temp;

SP = 128;

PV = ADRESH;	// ADC value = ADRESH (8 MSbs)

E0 = PV - SP;

output = gain*E0;

if(output > 0){
	P1M1 = 0;
	temp = output;			
	temp /= 4;		// Shift bits 3 to 10 of temp twice to the right
	CCPR1L = temp;
	}

if(output < 0){
	P1M1 = 1;			
	temp = -output;
	temp /= 4;		// Shift bits 3 to 10 of temp twice to the right
	CCPR1L = temp;	
	}
Don't worry about the A/D conversion, I just deleted the other code. The problem I'm having is that I don't believe the second if statement is working properly. I want to take the absolute value of "gain" but my compiler doesn't have the absolute function. Instead I just put "-gain" which compiles fine and I think works.

When output > 0, the PIC outputs a PWM square wave which shows up fine on the oscilloscope. It's when output should be < 0, the output on the oscilloscope is a very strange square wave, that looks noisy and has weird superimposing square waves. I think the problem is with the math though.

Can someone verify if the way I initialized the variables will properly store data? I get confused when I'm doing math with mixes of signed and unsigned numbers.

I'd appreciate the help a lot. Thanks!
 

Thread Starter

GammaRay86

Joined Dec 9, 2007
14
Gain is just given an integer value at the start. I did not put the whole code up as it would just make it harder to see and is irrelevant to the problem.

For example: gain = 2;

My concern is that because i'm using a mix of signed and unsigned integers, the sign bit might be getting lost somewhere, or even worse used as a bit that is placed inside a register such as CCPR1L.

Rich (BB code):
int16 temp;

if(output < 0){
	P1M1 = 1;			
	temp = -output;
	CCPR1L = (unsigned char)temp/4;	
	}
Would the code above guarantee that CCPR1L only gets the MSBs without the sign bit? For example, if temp is 10 bits of data + 1 sign bit (11 bits), would the CCPR1L register be given bits 2-9 (disregarding the 10th bit)? Hope this ain't too confusing lol
 

russ_hensel

Joined Jan 11, 2009
825
temp is a 16 bit value, so the cast could fail if the value is too big. I am not certain what happens if it it negative. Some of this depends upon how temp is assigned.
If you are not sure how big it is why not test it in code with at least some sort of assert?
By fail, i mean do something you do not expect, it will not directly produce a run time error.
 

Thread Starter

GammaRay86

Joined Dec 9, 2007
14
I simulated the code and the CCPR1L values are not correct in the (output < 0) part of the code. There is definitely something wrong with them but I can't figure it out. The maximum value for temp is about + or - 256, so no more than 10 bits can be placed inside temp. CCPR1L is only an 8 bit register so that is why I only want the 8 MSBs of temp.
 
Top