|
|
View previous topic :: View next topic |
Author |
Message |
gaminid
Joined: 27 Nov 2007 Posts: 10
|
How can I make the ISR (using int0) happen faster |
Posted: Tue Nov 27, 2007 2:12 pm |
|
|
Quote: |
Hello,
I am trying to power up a device within 2-3 usec using an external interrupt (INT0 on RB0) on 18F2520. I need to use both edges of the INT0 (to switch on and off). As a test I used the following code and found it takes about 6 usec to toggle the bit. That means it taking about 50 clock cycles as I am running the external clock at 32MHz. Then I tired using a sample code (came with the PCWH compiler) with an assembly instructions using the global interrupt. When I use that, it toggels the bit every 1.5 usec (regardless of the status of the external interrupt). Is there anyway I can improve the timing on the interrupt? I have posted both codes.
Your help is greatly appreciated.
Thanks
Gamini
|
Code: |
#define HB_LED PIN_B4 // Heat Beat Led is on RB4
void Init(void); // Hardware Initialization
void ext_isr(void); // Interrupt Service Routine
/*-----------------11/19/2007 5:26PM----------------
* Function Definitions
* --------------------------------------------------*/
// Initialize PIC Hardware
void Init(void){
//fast io direction control
set_tris_a(0b10000000);
set_tris_b(0b00100011);
set_tris_c(0b10000000);
// fast io inital port value
output_a(0b00110011); // LEDs = OFF, VCO = OFF, HIBAND = ON,
output_b(0b00111100); // LEDs = OFF
output_c(0b00000111); // HIBAND = ON, PLL Load = Enabled
setup_timer_0( RTCC_OFF);
port_b_pullups(TRUE);
SETUP_ADC(ADC_OFF);
setup_adc_ports(NO_ANALOGS);
setup_wdt(WDT_OFF);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
SETUP_CCP1(CCP_OFF);
SETUP_CCP2(CCP_OFF);
setup_low_volt_detect(FALSE);
ext_int_edge(L_TO_H); // change so interrupts on switching off High Band
enable_interrupts(INT_EXT); // enable external0 interrupt
enable_interrupts(GLOBAL); // enable any other interrupt previuosly enabled
}
/////////////////////////////////////////////
// Interrrupt Service Routine
#INT_EXT
void ext_isr() {
output_toggle(HB_LED); // take 6 usec to kicking in the ISR
}
//////////////////////////////////////////////
/*-----------------11/19/2007 5:29PM----------------
* Main Program
* --------------------------------------------------*/
void main() {
Init (); // Initialize the PIC
while(true){
// nothing happens here for now...everything happens at interrupt
}
}
|
Quote: |
Here is the assembly routine I tried with #int_global. With this routine the bit is toggled at every 1.5 usec. But if I use the #int_ext (instead of #int_global) it gives me same timing (6 usec).
|
Code: |
Here I made sure all the other interrupts are disabled
// Interrrupt Service Routine
#INT_GLOBAL
void isr() {
#asm
MOVWF save_w
SWAPF status,W
BCF status,5
BCF status,6
MOVWF save_status
// Save anything else your code may change
// You need to do something with PCLATH if you have GOTOs
// code for isr
BTG 0xf81, 4 // toggling PORTB bit4
// restore processor and return from interrupt
SWAPF save_status,W
MOVWF status
SWAPF save_w,F
SWAPF save_w,W
#endasm
}
| [/code] |
|
|
Ttelmah Guest
|
|
Posted: Tue Nov 27, 2007 3:31 pm |
|
|
Yes.
On the 18 chips, if you are not using any other interrupt you can use RETFIE 1 at the end of the interrupt, This restores the W reg, BSR, and status register automatically, meaning you don't need the ten instructions currently used to save and restore these registers.
However you need to add the code to the ISR, to clear the interrupt bit. At present you don't clear the interrupt.
Provided your routine does nothing more than toggle the output bit, this will be OK. Remember though if you do anything much else, that other registers will then need to be saved (which is what takes the time in the normal interrupt handler...).
Best Wishes |
|
|
gaminid
Joined: 27 Nov 2007 Posts: 10
|
How can I make the ISR (using int0) happen faster |
Posted: Tue Nov 27, 2007 4:45 pm |
|
|
Thanks for the reply. I changed the code with your suggestions. When I step thru I can see that once the code is in ISR it never comes out of it. It loops between clearing the interrupt and RETFIE. What am I doing wrong here?
Many thanks in advance.
Gamini
Code: |
#INT_GLOBAL
void isr() {
#asm
BCF INTCON,7 // clear Global Interrupt
BTG 0xf81, 3 // toggle PortB bit 3
// restore processor and return from interrupt
RETFIE 1
#endasm
}
|
|
|
|
gaminid
Joined: 27 Nov 2007 Posts: 10
|
|
Posted: Tue Nov 27, 2007 6:00 pm |
|
|
Thanks Ttelmah...
I wasn't clearing the interrupt correct (wasn't clearing NITCON bit2). I finally figured it out and now I can toggle the bit within 900 nsec!!
Thanks again...
Gamini |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 28, 2007 3:29 am |
|
|
Glad you have it working.
You hit the interrupt bit error 'overnight' for me.
Best Wishes |
|
|
|
|
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
|