|
|
View previous topic :: View next topic |
Author |
Message |
Bieli
Joined: 15 Sep 2003 Posts: 9
|
Interrupt on Change sometimes not triggered |
Posted: Mon Sep 06, 2021 6:56 am |
|
|
Hello,
PIC 16F18456
CCS: 5.084
I struggle with IOC because sometimes it is not triggered.
In most situation it is triggered on both edges but sometimes (1 for 100 or less) it is triggered only on rising or only on falling edge. Very rarely it is not triggered at all.
I connected B0 to oscilloscope and also C2 on second channel to be sure that interrupt signal is ok. Interrupt signal is 100ms low pulse always.
Code: |
#include <16F18456.h>
#fuses WDT_SW, LVP, PROTECT
#device ADC=10
#use delay(internal=32M)
#use fast_io (B)
#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7
#pin_select CCP5OUT= PIN_A0
#use rs232(baud=115200, UART1, stream=LCD)//rcv=PIN_C7, stream=LCD)
#include <dgus.c> //LCD Library
void RM5_Active(void);
void RM5_NotActive(void);
int16 iVP, iVAL;
int1 shCoin1;
#define LED_RM5 PIN_C2
#define RM5_EN1 PIN_B4
#define RM5_EN2 PIN_B5
#INT_IOC
void IOC_isr(void)
{
int8 portAstate;
portAstate = input_b();
if (interrupt_active(INT_IOC_B0))
{
clear_interrupt(INT_IOC_B0);
// if (input(PIN_B0)==1)
{
output_high(LED_RM5);
shCoin1=1;
}
}
}
void main(void)
{
setup_oscillator(OSC_HFINTRC_32MHZ | OSC_HFINTRC_ENABLED);
setup_adc_ports(NO_ANALOGS );
enable_interrupts(INT_IOC_B0 | INT_IOC_B1 | INT_IOC_B2 | INT_IOC_B3 |INT_IOC_C0);
restart_wdt();
set_tris_b(0b00001111);
enable_interrupts(GLOBAL);
RM5_Active();
enable_interrupts(INT_IOC);
while(1)
{ restart_wdt();
if (shCoin1==1)
{
shCoin1=0;
LCDBeep(2);
delay_ms(20);
output_low(LED_RM5);
}
}
} |
Any idea what may be the reason why sometimes it's not triggered?
Regards All |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Mon Sep 06, 2021 8:10 am |
|
|
very quick comments
1) get rid of the WDT being enabled ! Until your project/product is 'out the door ' ready, do NOT enable the WDT. ZERO need for it.
2) this....
portAstate = input_b();
...
is confusing !
pretty sure it should be
...
portBstate = input_b();
...
3) don't bother with fast_IO(), let the compiler handle the port pins. Unless you need very, very fast response/timing, standard_IO is stable and foolproof. I've only needed fast_io, 2-3 times in 25 years on 'time sensitive' custom serial I/O products.
4) LVP and PROTECT. Unless you have a Low Voltage Programmer (rare), say NOLVP. probably 99% of programmers are NOT LV. There's no need to use PROTECT, until product is ready to ship. Enabling it actually reduces the life of the PIC.
5) LED_RM5. I don't see where you reset it, it the main 'forever' loop.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Mon Sep 06, 2021 11:01 am |
|
|
You are specifying to enable INT_IOC, but you are not specifying the mask
to say which bits or edges this is to be applied to.
I'd have expected the interrupt to actually be triggering and not clearing.
You clear the B0 flag bit but no others. If any other bit gets set, nothing
will clear this, so the interrupt will keep re-triggering, The main code will
then never execute....
So your enable needs to have the mask or-ed in to say which bit the
interrupt is to be enabled on.
The interrupt itself gets set if any interrupt flag bit is set, for a bit that is
enabled. These flag bits are not cleared by reading the port. |
|
|
|
|
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
|