|
|
View previous topic :: View next topic |
Author |
Message |
Deej Guest
|
Interrupt delay/latency problem with 18F1330 |
Posted: Tue Mar 10, 2009 6:21 am |
|
|
Hi. I'm currently trying to use the PIC18F1330 as the control unit for a Power Factor corrected SMPS, and I'm having issues witht the length of time the PIC is taking to begin servicing an interrupt after it is called. I am using the PWM timebase as the interrupt trigger as can be seen in the code below. To try and work out where the delay was coming from I stripped out almost all of the control code and wrote a very simple program whereby the a/d reads a value from a potentiometer and uses this to set the pwm duty ratio. the interrupt is triggered by the pwm signal internally, and as far as i'm aware, should begin executing the handler code within four instruction cycles. At 32MHz this corresponds to 0.5us. however the pulse on pin B2 does not appear for approximately 7us or about 56 instruction cycles.
I also tried using an external interrupt with the pwm output hard-wired to the external interrupt pin, but the same delay could be seen on the oscilloscope.
I hope I have provided sufficient information for someone to answer my question. Thank you in advance for your help.
Code: |
#include <18F1330.h>
#device adc=10
#FUSES NOWDT, WDT128, INTRC_IO, FCMEN, NOBROWNOUT, BORV20, NOPUT, NOCPD, STVREN, NODEBUG, NOXINST, NOWRT, NOWRTD, NOWRTC, IESO, NOEBTR, NOEBTRB, MCLR, NOPROTECT, NOCPB, NOWRTB, BBSIZ1K, TO, T1OSCA6, PWMPIN, HPOL_HIGH, LPOL_HIGH
#use delay(clock=32000000)
long dutycycle;
long dutycycletemp;
long vouttemp;
long vout1;
long vout2;
long i;
long currenttemp;
long current;
long vintemp;
long iref;
#int_PWMTB
void PWMTB_isr(void)
{
output_high(PIN_B2);
delay_us(1);
output_low(PIN_B2);
}
void main()
{
setup_adc_ports(ALL_ANALOG|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_DISABLED);
setup_comparator(NC_NC_NC);
enable_interrupts(INT_PWMTB);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ|OSC_NORMAL|OSC_31250|OSC_PLL_ON);
setup_power_pwm_pins(PWM_ODD_ON, PWM_OFF, PWM_OFF, PWM_OFF);
setup_power_pwm(PWM_CLOCK_DIV_4 | PWM_UP_DOWN 1,65535,200,0,1,0);
do
{
set_ADC_channel( 3 ); //pot
delay_us(10);
vintemp = read_adc();
dutycycle = vintemp/5;
set_power_pwm0_duty(dutycycle);
} while (TRUE);
} |
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Mar 10, 2009 7:43 am |
|
|
I count 23 instructions involved with the global interrupt handler before calling #int_PWMTB. |
|
|
Deej Guest
|
|
Posted: Tue Mar 10, 2009 8:37 am |
|
|
I apologise for my ignorance but could you explain how I should have written the code to avoid this problem? I'm essentially aiming for the interrupt to be serviced as quickly as possible, but ideally without using the fast interrupt function. I'm very new to programming and so I'm trying to keep it fairly simple. |
|
|
Ttelmah Guest
|
|
Posted: Tue Mar 10, 2009 8:57 am |
|
|
Look at ex_glint.c
The time delay, is worse than 23 instruction times. On the PIC18, a lot of the instructions used are double cycle ones, so the total delay is typically over 30+ instruction times _minimum_, for the first defined interrupt.
56, sounds long, unless you have a lot of other interrupts defined ahead of the one you are using.
A search here, will find a lot of posts about this in the past, including an example I did, which saves more than the glint example. On the PIC18, you save work, by using the internal copy of the basic W, BSR etc., by using the RETFIE 1 instruction, so with a bit of ingenuity, you can get the time for a single interrupt down to only a handful of instruction times. How much time you can get it down to, will depend on how many registers you have to save (what you are doing in the ISR), and if any other interrupts are in use. If you only have one things requiring quick servicing, then declare this using the 'FAST' keyword, and add the HIGH_INTS=TRUE definition to your code. Then _provided you are not using INT_EXT_, you only need to save any extra registers, perform your code, clear the interrupt, and restore the saved registers. If you are using INT_EXT as well, it gets more complex, since this will always vector to the high priority handler, meaning you have to add code to identify this.
Best Wishes |
|
|
Deej Guest
|
|
Posted: Tue Mar 10, 2009 9:35 am |
|
|
It sounds as though getting the interrupt latency down to 1-2us is unrealistic then. I'm getting quite confused trying to use the fast interrupt function and saving relevant registers etc as I have virtually no knowledge of assembler or any idea which registers need to be saved. |
|
|
|
|
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
|