|
|
View previous topic :: View next topic |
Author |
Message |
Petar
Joined: 30 Jan 2004 Posts: 7
|
how to capture 3 signals (CCP1, CCP2, Int0) ?? |
Posted: Wed Feb 25, 2004 10:48 am |
|
|
Hello,
I'm trying to capture 3 inputs from my motorbike.
CCP1 and CCP2 are working fine.
But the 3rd input with Int0 hase a to big range (about 10%)
How can I capture a signal (rpm till 1 KHz) with a timer in a propper way (like CCP)??
Thanks a lot!
#include <18F452.h>
#device ICD=TRUE
#use delay(clock=20000000)
#fuses HS,NOWDT,WDT1,NOPROTECT
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
int16 s_rpm[120]; //array for rpm data
int32 current_s_rpm; //current values of RPM
unsigned int data_set_cntr = 0; //counter for 120 sets of data
int shaft_rolls; //variable to track timer1 roll-overs
#int_TIMER0
void TIMER0_isr()
{
set_timer0(26473); //reload for the next 250 ms, DIV 32
if (data_set_cntr < 120)
{
s_rpm[data_set_cntr] = current_s_rpm;
data_set_cntr ++;
}
}
#int_TIMER1
void TIMER1_isr()
{
++shaft_rolls;
}
int16 previous_shaft_time; //variable to save shaft start time
#int_EXT
void EXT_isr()
{
int32 current_shaft_time;
current_shaft_time = get_timer0(); //read current timer1 count
current_s_rpm = ((int32)shaft_rolls * (int32)0xffff) + (int32)current_shaft_time - (int32)previous_shaft_time;
previous_shaft_time = current_shaft_time; //save value for next calculation
shaft_rolls = 0; //cear timer1 roll over counter
}
void main()
{
setup_wdt(WDT_OFF); //WDT off
setup_timer_0(RTCC_DIV_32); //Timer0 enabled with a 64 prescaler
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);//Timer1 enabled using system clock/4/2
enable_interrupts(INT_TIMER0); //unmask timer0 overflow interrupt
enable_interrupts(INT_TIMER1); //unmask timer1 overflow interrupt
enable_interrupts(INT_EXT); //unmask external interrupt 0
enable_interrupts(global); //enable all unmasked interrupts
data_set_cntr = 0; //start recording data sets at 0
while(1)
{}
}
|
|
|
Ttelmah Guest
|
|
Posted: Wed Feb 25, 2004 11:59 am |
|
|
A couple of comments, that may be having an effect. The 'rollover', is from 0xffff to 0, so the factor required is 0x10000 in the arithmetic.
Seriously, multiplication is quite slow, so it'd be neater and a lot faster in the interrupt routine, to have declared a union, to contain a 32bit value, and an array of 8 bit values, then use the third array entry to contain the rollover counter, and increment this, and just use the whole 32bit variable when you need the current value (no maths involved at all).
The biggest problem is going to be the interrupt latency. If the processor is just starting one of the timer interrupts, when the external interrupt occurs, there will be the delay while the timer interrupt executes, followed by the time to restore the registers, and exit the global handler, before the external interrupt is processed. This unfortunately is pretty unavoidable. You can effect the behaviour, by using the #priority setting, and if you removed all arithmetic from your external interrupt routine, having it just set a flag, and store the current timer value, you could possibly use the #fast ability, but (unfortunately), on the 18F452, this has problems with an asynchronous interrupt event...
Best Wishes |
|
|
Petar
Joined: 30 Jan 2004 Posts: 7
|
|
Posted: Thu Feb 26, 2004 1:44 am |
|
|
Hello Ttelmah,
many thanks for your reply. I'll try your suggestions.
Best wishes,
Petar |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|