View previous topic :: View next topic |
Author |
Message |
umka
Joined: 28 Aug 2007 Posts: 99 Location: New Zealand
|
external interrupt starting timer |
Posted: Wed Jul 23, 2008 8:19 pm |
|
|
I want to turn on and off a transistor with the pin setup as IGBT_ON and IGBT_OFF. Kind of like PWM but the want it controlled by an external interrupt.
An external interrupt is triggered which should turn on the transistor, set a timer reload value as it is changing depending on the main code result, start the timer and then exit the interrupt and go do other stuff.
Once the timer interrupts I want the transistor to turn off, the timer not to interrupt again until it has been through the external interrupt routine again and then exit the interrupt.
This is a repeating cycle with the max time period for timer being about 13ms.
Is this code going to work correctly or is there a better way to do this as I am a bit concerned about having the timer setup each time I call the external isr?
Code snippet
Code: | #INT_EXT // External interrupt on Pin RB0/INT
void Zero_ISR()
{
IGBT_ON; // Turn on the IGBT
Timer_Value = Wave_Duty; // Set timer0 reset value from main code
setup_timer_2(T2_DIV_BY_16, Timer_Value, 1);
enable_interrupts(INT_TIMER2);
}
#INT_TIMER2
void Timer2_ISR()
{
IGBT_OFF; // Turn off the IGBT;
disable_interrupts(INT_TIMER2);
} |
|
|
|
bwhiten
Joined: 26 Nov 2003 Posts: 151 Location: Grayson, GA
|
Also interested |
Posted: Thu Jul 24, 2008 11:01 am |
|
|
Sorry, I have no answer for you, but I am also looking to perform a similar function, using an external interrupt to trigger an internal timer that triggers an ADC reading on time out. So this is a bump to get the question to the top again. |
|
|
umka
Joined: 28 Aug 2007 Posts: 99 Location: New Zealand
|
|
Posted: Mon Jul 28, 2008 5:08 am |
|
|
Anyone got any input for us? |
|
|
Ttelmah Guest
|
|
Posted: Mon Jul 28, 2008 10:08 am |
|
|
I'd use a CCP.
You can program this to turn it's output off after a count.
You don't even need to interrupt. It is a hardware control, that will trigger an interrupt if required, but this doesn't have to be used. You start it in an interrupt, by resetting it's counter, and setting the line, then just exiting the interrupt. The line will turn off for you the programmed time latter.
I have used exactly this for such an application in the past.
Best Wishes |
|
|
umka
Joined: 28 Aug 2007 Posts: 99 Location: New Zealand
|
|
Posted: Mon Jul 28, 2008 2:15 pm |
|
|
the circuit i need it for is an AC phase controller using a IGBT to turn on the power and then off after a certain timer period (before the half sine wave of AC is complete). this is why i have the interupt so i know when the AC has just crossed the + to - half waves using a zero crossing circuit. |
|
|
Ttelmah Guest
|
|
Posted: Mon Jul 28, 2008 2:45 pm |
|
|
Exactly. But you don't need a _second_ interrupt for the turn off.
You just tell the CCP to turn it's output line 'off' at the specified count, set the count, and the line automatically goes off the specified time latter.
The problem with using the interrupt, is that it takes a lot of time. Typically at least 30 instructions to enter the interrupt. Also, since it takes this long to get out of the first interrupt,your 'minimum' period, typically becomes something like 70 instruction times. With the CCP, the switch off is automatic, and the CCP can just be left running till the next time it is needed. Used like this, the CCP, can be thought of like a programmable monostable multivibrator, with you able to program the pulse width it generates.
You either reset the timer being used, and put the required count into the CCP, or just add the required count to the current timer value, and put this into the CCP. Set the line. Do this in your zero-crossing interrupt, and the hardware does the rest for you...
Best Wishes |
|
|
umka
Joined: 28 Aug 2007 Posts: 99 Location: New Zealand
|
|
Posted: Tue Jul 29, 2008 4:43 am |
|
|
Cheers for the help Ttelmah
I am not totally sure if I am doing this right but do i want to use code similar to that in EX_CCP1S?
Code: | setup_ccp1(CCP_COMPARE_SET_ON_MATCH); // Configure CCP1 to set
CCP_1=0; // C2 high now
set_timer1(0);
CCP_1 = 500; // Set high time limit
// to 100 us
// limit is time/(clock/4)
// 500 = .0001*(20000000/4)
setup_ccp1(CCP_COMPARE_CLR_ON_MATCH); // Configure CCP1 in COMPARE
// mode and to pull pin C2
// low on a match with timer1 |
With this code as i understand it i will set the value CCP_1 to whatever value i want for the on time period and it will switch low when timer and CCP_1 are equal.
So your advise is to put this in the zero-crossing interupt which makes sence. If the above code is only called once will i only get one high peak or will it carry on like a PWM? once the code has exited the interupt and is doing other stuff and the timer and CCP value become equal does it switch low without affecting the micros current instruction set. |
|
|
Ttelmah Guest
|
|
Posted: Tue Jul 29, 2008 9:03 am |
|
|
The code you show, uses the CCP to set, the line, then the CCP again, to clear it. All you do, is put just the _clear_part into the zero crossing interrupt, and manually _set_ the line yourself here. The line goes high when you set it (logical), and clears automatically the required interval later. Since the only function is to clear the line, and the line is low, there is no re-triggering, till you yourself set the line in the next zero crossing interrupt. Hence no multiple pulses.
Best Wishes |
|
|
umka
Joined: 28 Aug 2007 Posts: 99 Location: New Zealand
|
|
Posted: Tue Jul 29, 2008 2:07 pm |
|
|
So the code would look something like this?
Code: | #EXT_int
void isr()
{
output_high(CCP1); // Output_high on CCP pin
set_timer1(0); // Reset timer 1
CCP_1 = ON_Period; // set CCP compare value
}
void main()
{
setup_ccp1(CCP_COMPARE_CLR_ON_MATCH); // Configure CCP1 in COMPARE mode
setup_timer_1(T1_INTERNAL); // Set up timer to instruction clk
while(TRUE)
{
// Calculate ON_Period
// Do stuff
}
} |
|
|
|
umka
Joined: 28 Aug 2007 Posts: 99 Location: New Zealand
|
|
Posted: Tue Jul 29, 2008 6:14 pm |
|
|
Ok i tryed the above code and it doesnt work. i think problem is with the output_high. |
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 30, 2008 2:53 am |
|
|
Can you accept a pulse that goes high, rather than low?. Otherwise it is just a 'tad' harder to do.
If you program the CCP to 'set on match', the code is:
[code]
#byte CCP1CON=0xFBD
#EXT_int
void isr()
{
int8 dummy;
dummy=CCP1CON;
CCP1CON=0;
set_timer1(0); // Reset timer 1
CCP1CON=dummy;
CCP_1 = ON_Period; // set CCP compare value
}
void main()
{
setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
setup_timer_1(T1_INTERNAL); // Set up timer to instruction clk
while(TRUE)
{
// Calculate ON_Period
// Do stuff
}
}
{/code]
I have used this for basically exactly this application.
If you need to have the pulse positive going, then you set the pin, by using the code shown in your original example.
Best Wishes |
|
|
|