View previous topic :: View next topic |
Author |
Message |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
EXT_INT on 16F88 doesn’t seem to trigger the ISR |
Posted: Fri Jun 08, 2007 10:36 am |
|
|
Colleagues,
External interrupt refuses to trigger the INT_EXT ISR. I’m driving the external interrupt pin RB0 with a TTL square wave (0-5V) and monitoring a digital output that I toggle in the INT_EXT ISR. Here’s my rudimentary code:
Code: |
#include "light_source.h"
#define PROXIMITY PIN_A7 // digital output to the main controller
#define BLUE_LED PIN_B1
// Analog channels
#define PROX0 0
#define PROX1 1
#define PROX2 2
#define PROX_THRESHOLD 0xA0 // 8-bit A/D readings will be compared to this
#INT_EXT
void EXT_isr( void )
// PURPOSE: All of the proximity detection functionality is done in this ISR.
// NOTE: The ISR is a bit lengthy, however PIC isn't doing anything else, when this ISR has to run.
{
output_toggle(PROXIMITY); // <debug/>
}
#INT_RDA
void comm_isr( void )
{
}
void main()
{
setup_adc_ports(sAN0 | sAN1 | sAN2 | VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED, 0, 1);
setup_comparator(NC_NC_NC_NC);
setup_vref(VREF_LOW | -2);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ | OSC_INTRC);
while (1)
{
output_toggle(BLUE_LED);
delay_ms(500);
}
}
|
Code: |
#include <16F88.h>
#device ICD=TRUE
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES IESO //Internal External Switch Over mode enabled
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8,stream=rs232) |
Hardware: 18F88 in 28-pin QFN, Vcc = +5V, internal RC 8MHz
CCS: 3.240
I’ve checked the wiring – looks like it’s done correctly. External interrupt was working for me in the past on the 18F PICs. What could be a problem in the present case?
Thanks,
Nick _________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 08, 2007 10:52 am |
|
|
Quote: | #FUSES INTRC
#define PROXIMITY PIN_A7
output_toggle(PROXIMITY); |
Pin A7 is normally used by an external crystal. To configure pin A7
for digital i/o, you must use the INTRC_IO fuse. |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Fri Jun 08, 2007 11:09 am |
|
|
PCM programmer wrote: | Pin A7 is normally used by an external crystal. To configure pin A7
for digital i/o, you must use the INTRC_IO fuse. |
Changed INTRC to INTRC_IO, but RA7 still does not get toggled, it stays high.
The same line Code: | output_toggle(PROXIMITY); | works just fine in the main loop. _________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 08, 2007 12:15 pm |
|
|
I installed PCM vs. 3.240 and I was able to make it work on a
PicDem2-Plus board. I added a 330 ohm series resistor and an LED
to ground on Pin A7. When I press the button on Pin B0, the LED on
pin A7 toggles. I just change the fuse to INTRC_IO and commented
out the two debugger lines. I ran it in stand-alone mode.
I'm using MPLAB as the IDE and ICD2 as the programmer.
Code: | #include <16F88.h>
//#device ICD=TRUE // *** COMMENTED OUT ***
#device adc=8
#FUSES NOWDT
#FUSES INTRC_IO // *** CHANGED ***
#FUSES NOPUT
#FUSES MCLR
#FUSES BROWNOUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
//#FUSES DEBUG // *** COMMENTED OUT ***
#FUSES NOPROTECT
#FUSES FCMEN
#FUSES IESO |
Also, this is a CCS Wizard bug and you should fix it:
Code: | setup_vref(VREF_LOW | -2); |
|
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Fri Jun 08, 2007 12:41 pm |
|
|
PCM, I did your changes, but RA7 still doesn’t toggle from the ISR.
Still, you've pointed me in the right direction. I've tried to toggle RB3 (spare pin) for output (instead of RA7) and it worked just fine. _________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 08, 2007 1:53 pm |
|
|
What is the external circuit on pin A7 ? Check the voltage level on
the pin when it's at a high level. The problem with using the toggle
function on the 16F PICs is that it has to read the actual pin voltage.
If the load is too large, the output voltage on the pin might not be
readable as a logic high level. (The Vih voltage for pin A7 is 4.0v,
but it's only 2.0v on pin B3 -- that's almost certainly the reason).
In that's the case, it's better to keep the pin state in a static variable
and toggle that variable, and then output the state to the pin. It's then
completely independent of the external circuit. Example:
Code: | #INT_EXT
void EXT_isr( void )
{
static int8 state = 0; // Static variable
if(state)
output_high(PROXIMITY);
else
output_low(PROXIMITY);
state = !state; // Toggle the state to 0 or 1
} |
Note that this potential problem with the output_toggle() function doesn't
exist on the 18F PICs because they have Latch Registers. CCS toggles
the Latch Register instead of the pin register in the output_toggle()
function. It's completely internal to the PIC and isn't affected by the
external circuit on the pin. |
|
|
|