Interrupt Problem

Hey.

We are trying to get pulse widths from the Devantech CMPS03 compass. We are using timer 3, interrupt 3, and encoder 3. We are getting values, but they are not consistent and don’t even seem to vary as the compass is turned. On unplugging the pwm from dig input 3, the printed value stays constant. We are now at a loss as to how to continue.

I have taken a look at kevin’s infrared code to see how he implements the interrupts, and my code looks the same. If anyone could shed some light on what’s going on that would be great.

My code is posted below. Thanks.

Interrupt 3 Handler


void Int_3_ISR(unsigned char state)
{
	// Encoder 3's phase a signal just changed logic level, causing this 
	// interrupt service routine to be called.
	if(state == 1)
	{
		T3CONbits.TMR3ON = 0;
		
	Temp_Buf = TMR3L;
  Timer_Snapshot = (unsigned int)TMR3H;
  //if(Temp_Buf == 0xFF)
    //Timer_Snapshot--;
  Timer_Snapshot <<= 8;
  Timer_Snapshot += (unsigned int)Temp_Buf;
  
  Readings[p] = (Timer_Snapshot - 0x4000) % 360;
		p++;
    	p %= SAMPLES;
    	
    	
		
		// rising-edge interrupt
		if(ENCODER_3_PHASE_B_PIN == 0)
		{
			// backward
			if(Encoder_3_State == 1)
			{
				Encoder_3_Count -= ENCODER_3_TICK_DELTA;
			}
		}
		else
		{
			// forward
			if(Encoder_3_State == 0)
			{
				Encoder_3_Count += ENCODER_3_TICK_DELTA;
			}
		}
	}
	else
	{
  
		TMR3H = 0x00; // MSB-TMR1		
		TMR3L = 0x00; // LSB-TMR1
		
		T3CONbits.TMR3ON = 1;
		
		// falling-edge interrupt
		//   phase b is zero if moving forward
		//   phase b is one if moving backward
		Encoder_3_State = ENCODER_3_PHASE_B_PIN;
	}
}

Timer 3 Initialize


void Initialize_Timer_3(void)  
{
	TMR3L = 0x00;			// least significant 8-bits of the timer 3 register (this is readable and writable)
	TMR3H = 0x00;			// most significant 8-bits of the timer 3 register (this is readable and writable)
							//
	T3CONbits.T3CKPS0 = 1;	// T3CKPS1 T3CKPS0
	T3CONbits.T3CKPS1 = 1;	//    0       0		1:1 prescaler (clock=10MHz/each tick=100ns)
							//    0       1		1:2 prescaler (clock=5MHz/each tick=200ns)
							//    1       0		1:4 prescaler (clock=2.5MHz/each tick=400ns)
							//    1       1		1:8 prescaler (clock=1.25MHz/each tick=800ns)
							//
	T3CONbits.TMR3CS = 0;	// 0: use the internal clock
							// 1: use an external clock on RC0/T1OSO/T13CLK (rc_dig_in14 on robot controller)
							//
	T3CONbits.T3SYNC = 1;	// 0: do not synchronize the external clock (this can cause timing problems)
							// 1: synchronize the external clock to the 18F8520/18F8722 internal clock, which is desirable
							//
	T3CONbits.RD16 = 1;		// 0: timer 3 register operations are done in two 8-bit accesses
							// 1: timer 3 register operations are done in one 16-bit access
							//    In this mode, reading TMR3L will latch a copy of TMR3H into a buffer
							//    mapped to the TMR3H memory address. Conversely, a write to the buffer
							//    followed by a write to the TMR3L register will update the entire 16-bit
							//    timer at once. This solves the problem where the timer may overflow
							//    between two 8-bit accesses. Here's an example of how to do a 16-bit read:
							//
							//    unsigned char Temp_Buf; // 8-bit temporary buffer
							//    unsigned int Timer_Snapshot; // 16-bit variable
							//
							//    Temp_Buf = TMR3L; // TMR3L must be read before TMR3H
							//    Timer_Snapshot = TMR3H;
		 					//    Timer_Snapshot <<= 8; // move TMR3H data to the upper half of the variable
							//    Timer_Snapshot += Temp_Buf; // we now have all sixteen bits  
							// 
	IPR2bits.TMR3IP = 0;	// 0: timer 3 overflow interrupt is low priority (leave at 0 on IFI controllers)
							// 1: timer 3 overflow interrupt is high priority
							//
	PIR2bits.TMR3IF = 0;	// 0: timer 3 overflow hasn't happened (set to 0 before enabling the interrupt)
							// 1: timer 3 overflow has happened
							//
	PIE2bits.TMR3IE = 0;	// 0: disable timer 3 interrupt on overflow (i.e., a transition from FFFF->0)
							// 1: enable timer 3 interrupt on overflow (i.e., a transition from FFFF->0)
							//	
	T3CONbits.TMR3ON = 1;	// 0: timer 3 is disabled
							// 1: timer 3 is enabled (running)
}