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
