View previous topic :: View next topic |
Author |
Message |
ashrau
Joined: 25 Feb 2009 Posts: 9
|
Interrupts disabled warning. Why ? |
Posted: Fri Mar 13, 2009 12:54 am |
|
|
Hi. I wrote the following code to use a signal from a 1-axis compass. I'm using interrupts to sample the compass signal upon a Lo-Hi edge of a clock signal (also from the compass). Here is the code:
Code: |
/*
PIN A1: Right indicator
PIN A2: Left indicator
PIN A0: Compass signal for A/D sampling
PIN B0: Clock signal from compass for triggering interrupt on Lo-Hi edge
Port C: For displaying A/D conversion values
*/
#include <18F2525.h>
#device adc=8
#include<stdio.h>
#include<stdlib.h>
#fuses NOWDT,INTRC_IO, NOPUT, NOMCLR, BROWNOUT, LVP, NOCPD, NOWRT, NODEBUG
#use delay(clock=4000000)
int target, heading; //target stores initial heading
#INT_EXT //external interrupt
compass_clock_isr() {
delay_ms(5); //to provide for rise time of signal pulse
heading = read_adc(); //current heading
delay_us(100);
output_c(heading); // ***!!!*** for debugging
delay_ms(3000); // ***!!!*** for debugging
if((abs(target-heading)>5)&&(target>heading)){ //see [1] below
output_low(PIN_A2);
output_high(PIN_A1);
//will replace pin toggles with PWM routines
}
else if ((abs(target-heading)>5)&&(target<heading)){
output_low(PIN_A1);
output_high(PIN_A2);
//will replace pin toggles with PWM routines
}
else {
output_low(PIN_A1);
output_low(PIN_A2);
//will replace pin toggles with PWM routines
}
clear_interrupt(INT_EXT);
}
void main (void){
delay_ms(5000); // ***!!!*** for debugging
set_tris_b(0x01); //set PIN_B0 as input for use with external interrupt
//Setup ADC
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(100); // ***!!!*** reduce later
target = read_adc(); //acquire initial reading
output_c(target);
delay_ms(5000); // ***!!!*** for debugging
//Enable external interrupt
ext_int_edge(L_TO_H); //interrupt routine called on Lo-Hi edge
enable_interrupts(INT_EXT);
clear_interrupt(INT_EXT);
enable_interrupts(GLOBAL);
while(TRUE); //leaves this loop only for interrupt calls
}//end main
/*
[1] Difference of 5 b/w target and heading sometimes caused turning signals due to minor fluctuations while adc conversions. Need to increase to something like 8 or 10 to make it to stop responding to noise
*/ |
When i compile this code, it gives me the following warning messages:
>>> Warning 208 "external_interrupt_v2.c" Line 19(1,18): Function not void and does not return a value compass_clock_isr
>>> Warning 216 "external_interrupt_v2.c" Line 78(0,1): Interrupts disabled during call to prevent re-entrancy: (@delay_ms1)
Memory usage: ROM=1% RAM=1% - 1%
0 Errors, 2 Warnings.
When i tested the PIC, it seemed to be working as expected.
a) Why does the warning message say that the interrupts have been disabled? How can I fix this?
b) If the interrupts have been disabled, how does my PIC seem to be working fine?
I will really appreciate some quick help on this, as I have a university project deadline approaching soon. Thanks a lot in advance! _________________ ashrau |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Fri Mar 13, 2009 1:27 am |
|
|
I dont think those delays in the isr are really necessary are they? |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Fri Mar 13, 2009 3:52 pm |
|
|
It is best to never use delays inside of an ISR.... |
|
|
ashrau
Joined: 25 Feb 2009 Posts: 9
|
|
Posted: Sat Mar 14, 2009 1:51 am |
|
|
Thanks for the replies. I guess it makes sense to not have delays inside an isr. But the 5 ms delay I have, because right after the LO-HI edge of the clock signal, there is a 5 ms rise time in the output signal that I want to sample. How do I incorporate that delay time, if not in the isr ? Would it work if I disabled the external interrupt as soon as I entered the isr and enabled it again while exiting the isr ?
The program I made works, but is kind of fishy. I'm assuming its something to do with how the isr has delays in it. I'm using another program that came with the compiler called EX_PULSE.C. It essentially uses the while(input(PIN_B0)) and while(!input(PIN_B0)) approach to finding the HI-LO and LO-HI edges of a pulse on the clock signal. That program seems to be working a lot better than my external interrupt approach. But using external interrupts seems to be a more refined and sophisticated approach to this problem. What would you guys suggest?
Thanks A LOT, again. _________________ ashrau |
|
|
ashrau
Joined: 25 Feb 2009 Posts: 9
|
|
Posted: Sat Mar 14, 2009 1:55 am |
|
|
P.S. the 5000 ms and 3000 ms delays I had in the code were for debugging, so that I have enough time to read the adc conversion values that are output on port_c. I intend on removing them in my final implementation, but I do need the 5 ms delay. The 100 us delay, i just put it there to allow for the adc to stabalize after conversion, just in case. I'm not really sure if i need that there or not. _________________ ashrau |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Sat Mar 14, 2009 3:10 am |
|
|
ashrau wrote: | Would it work if I disabled the external interrupt as soon as I entered the isr and enabled it again while exiting the isr ? |
The compiler does this automagically, the problem being the interrupt wont get serviced while you are running a delay in the main loop, the quick dirty fix is in the link I posted, see:
Code: | #use delay(clock=4000000)
void main(void) |
|
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Sat Mar 14, 2009 3:19 am |
|
|
ashrau wrote: | The 100 us delay, i just put it there to allow for the adc to stabalize after conversion, just in case. I'm not really sure if i need that there or not. |
If you set the adc up properly then no you probably wouldn't, ADC_CLOCK_INTERNAL is for device frequencies 1mhz and lower, its all in the datasheet along with the aquisition time setting. |
|
|
ashrau
Joined: 25 Feb 2009 Posts: 9
|
|
Posted: Sat Mar 14, 2009 12:14 pm |
|
|
Thanks! Very helpful _________________ ashrau |
|
|
|