View Single Post
  #15   Spotlight this post!  
Unread 29-10-2006, 13:35
yongkimleng yongkimleng is offline
deus ex programmeur
AKA: James Yong
FTC #0747
Team Role: Mentor
 
Join Date: Aug 2006
Rookie Year: 2004
Location: Singapore, West
Posts: 134
yongkimleng is a jewel in the roughyongkimleng is a jewel in the roughyongkimleng is a jewel in the rough
Send a message via MSN to yongkimleng
Re: Help needed timing a pulse (2004 Robovation)

Quote:
Originally Posted by Josh Siegel
Thanks guys,
I think I understand the concept now!
I wrote some code that (should) work, but doesn't. It reads random values, even if the sensor is still. I can understand how it might read the same error each time, but if the pulse is right, it shouldn't vary every loop, should it? So I guess, I'm trying to figure out of it's something to do with my wiring, or something in the program itself. I don't have access to an oscilliscope to check it, sadly.
Here's the code:
From interrupts.c
Code:
void Initialize_Timer_1(void)  
{
	TMR1L = TMR1H = 0x00;		           	// LSB-TMR1 (read/write) = MSB-TMR1 (read/write) = 0
	T1CONbits.T1CKPS0 = T1CONbits.T1CKPS1 = 1;	// 1,1: 1:8 prescaler (clock=1.25MHz/each tick=800ns)
	T1CONbits.T1OSCEN = 0;	                        // 0  : timer 1 oscillator disabled
	T1CONbits.TMR1CS = 0;	                        // 0  : use the internal clock
	T1CONbits.RD16 = 1;                             // 1  : timer 1 register operations are done in one 16-bit access							
	IPR1bits.TMR1IP = 0;				// 0  : timer 1 overflow interrupt is low priority (leave at 0 on IFI controllers)
	PIR1bits.TMR1IF = 0;				// 0  : timer 1 overflow hasn't happened (set to 0 before enabling the interrupt)
	PIE1bits.TMR1IE = 0;				// 0  : disable timer 1 interrupt on overflow (i.e., a transition from FFFF->0)
	T1CONbits.TMR1ON = 1;				// 1  : timer 1 is enabled (running)
}
............................................................................................
void Int_6_Handler(unsigned char RB7_State)
{
if (RB7_State == 1) {//Clear the timer on the rising edge.
	TMR1L = 0x00; // LSB-TMR1
	TMR1H = 0x00; // MSB-TMR1
}
if (RB7_State == 0) {//Read the timer on the falling edge
	Timer1_Buffer = TMR1L; //Read LSB to 8 bit
	Timer1_Instant = TMR1H; //Read MSB to 16 bit
	Timer1_Instant <<=8; //Shift MSB 8 bits
	Timer1_Instant += Timer1_Buffer; //Append LSB
	//Now convert this into another value (degrees) based upon time.
	//With the 8:1 prescale, a value of 1 on the timer = 800nS.
	//1000nS = 1uS
	//1000uS = 1mS
	//10000nS = .01mS
	//800nS = .008mS = 1 "click"
	//# clicks * .008 = mS
	//(mS - 1)*10 = degrees
	//((Clicks * .008) - 1) * 10 = degrees
	//1mS to 36.99mS (0-360 degrees, 1mS offset)
	Timer1_Readable = ((Timer1_Instant * .008) - 1) * 10; //Copy to the reader variable, after processing the value (converting to degrees).
}
}
The logic seems OK, I think...

Timer1_Readable is an extern variable declared in interrupts.h. I am using a simple printf of an int from my user_routines.

Could it be that the timer is not resetting as it should? I'm going to look for a pattern now...
ehh 2 points:
1. get a signal generator/constant pulse source to test, if possible
2. Timer1_Readable is declared as what? Try to avoid things like multiplying by 0.008 .. you may need to define Timer1_Readable as a float or single..
As much as possible when it comes to complex calculations, I'd use a lookup table to speed things up and increase reliability
__________________
| jamesyong.net |
FVC2007, FTC2008