View previous topic :: View next topic |
Author |
Message |
ECACE
Joined: 24 Jul 2006 Posts: 94
|
INT_RA0 get's stuck |
Posted: Wed Oct 23, 2013 9:39 am |
|
|
Having a problem with a simple encoder wheel and interrupt on the RA lines.
In the setup section, I have turned on the interrupts like such:
Code: | enable_interrupts(INT_TIMER1); //Int for TMR1 -- Fires after X pulses from the SPI_Step_Clock
enable_interrupts(INT_TIMER4); //1mS timer for multiple uses fires every 1mS
disable_interrupts(INT_SSP); //Interrupt for SPI Communications
enable_interrupts (INT_RA0_L2H); //Enable Encoder interrupts
enable_interrupts (INT_RA1_L2H); //Enable Encoder interrupts
enable_interrupts(GLOBAL); //Enable all interrupts globally
setup_oscillator(OSC_16MHZ); //Use internal 16Mhz clock |
Then in the interrupt vector, I have the following:
Code: | #INT_RA
void SupplyEncoderInt(void)
{
//Supply Encoder has recieved a pulse
/*Encoders
//#define SUP_ENCODER PIN_A0 // Input -- Encoder wheel 1 for motor 1
//#define TAK_ENCODER PIN_A1 // Input -- Encoder wheel 2 for motor 2
*/
if(input_state(SUP_ENCODER))
{
currentStepsSupplyActual = currentStepsSupply; //Make a copy of how many steps occured from one encoder pulse
currentStepsSupply = 0; //Zero it out so it is always refreshed
}
if(input_state(TAK_ENCODER))
{
currentStepsTakeupActual = currentStepsTakeup; //Make a copy of how many steps occured from one encoder pulse
currentStepsTakeup = 0; //Zero it out so it is always refreshed
}
} |
I've had this happen in the recent past, and actually had to manually clear the interrupts, but that doesn't seem to work either. I have disabled all the other interrupts to narrow it down to the RA0 and RA1 interrupt. As soon as either of the wheels are turned, it get's into the int and can't get out.
I've put a heartbeat LED on an unused line, sitting in main, and just have to turn either encoder, then the heartbeat stops and she's locked up.
Is there something really simple I am missing here?
The PIC being used is a 16F1829, compiler is PCWHD 5.012. _________________ A HW Engineer 'trying' to do SW !!! Run!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 23, 2013 11:20 am |
|
|
Quote: |
I've had this happen in the recent past, and actually had to manually clear
the interrupts.
|
You do have to manually clear the IOCAF register bit that caused the
interrupt. The compiler doesn't do it for you. |
|
|
ECACE
Joined: 24 Jul 2006 Posts: 94
|
|
Posted: Wed Oct 23, 2013 11:24 am |
|
|
So if I added:
Code: | clear_interrupt(INT_RA0_L2H);
clear_interrupt(INT_RA1_L2H); |
Would that clear it out? I added them and it did not make a difference.
I even went as far as adding:
Code: | clear_interrupt(INT_RA); |
But it still get's stuck in it. _________________ A HW Engineer 'trying' to do SW !!! Run!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 23, 2013 11:35 am |
|
|
You need to post a small but complete test program so I can see what you're doing.
Also describe the external signals on pins A0 and A1 - The voltage levels
(high and low), and the frequency and duration of the pulses. Also say
if it's a continuous waveform or just occassional pulses. Describe the
circuits on those pins.
Also post the Vdd voltage of the PIC. |
|
|
ECACE
Joined: 24 Jul 2006 Posts: 94
|
|
Posted: Wed Oct 23, 2013 4:34 pm |
|
|
Ok, I'm not sure what I was doing wrong before, but it is working now. Manually clearing the interrupts fixed the problem.
Interrupt code:
Code: | #INT_RA
void SupplyEncoderInt(void)
{
//Supply Encoder has recieved a pulse
/*Encoders
//#define SUP_ENCODER PIN_A0 // Input -- Encoder wheel 1 for motor 1
//#define TAK_ENCODER PIN_A1 // Input -- Encoder wheel 2 for motor 2
Both the takeup and supply encoders work the same way. The tension applied to a
spindle is proportional to the number of full steps counted between encoder interrupts
*/
delay_us(5); //Debounce delay for ESD
if(input_state(SUP_ENCODER))
{
currentStepsSupplyActual = currentStepsSupply; //Make a copy of how many steps occured from one encoder pulse
currentStepsSupply = 0; //Zero it out so it is always refreshed
}
if(input_state(TAK_ENCODER))
{
currentStepsTakeupActual = currentStepsTakeup; //Make a copy of how many steps occured from one encoder pulse
currentStepsTakeup = 0; //Zero it out so it is always refreshed
}
clear_interrupt(INT_RA0);
clear_interrupt(INT_RA0_L2H); //Clear the RA0/RA1 interrupt flags
clear_interrupt(INT_RA1);
clear_interrupt(INT_RA1_L2H);
output_toggle(PIN_B5);
} |
From the Setup Code:
Code: | enable_interrupts(INT_TIMER1); //Interrupt for TIMER1
enable_interrupts(INT_TIMER4); //1mS timer for multiple uses fires every 1mS
disable_interrupts(INT_SSP); //Interrupt for SPI Communications
enable_interrupts(INT_RA0_L2H);
enable_interrupts(INT_RA1_L2H);
enable_interrupts(GLOBAL); |
Thank you all for your help!!! _________________ A HW Engineer 'trying' to do SW !!! Run!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 23, 2013 4:45 pm |
|
|
Look at your .LST file. You have duplicate code in there that you don't need:
Code: | .................... clear_interrupt(INT_RA0);
0028: MOVLB 07
0029: BCF IOCAF.0
.................... clear_interrupt(INT_RA0_L2H);
002A: BCF IOCAF.0
.................... clear_interrupt(INT_RA1);
002B: BCF IOCAF.1
.................... clear_interrupt(INT_RA1_L2H);
002C: BCF IOCAF.1 |
Look at the ASM code. |
|
|
ECACE
Joined: 24 Jul 2006 Posts: 94
|
[SOLVED] INT_RA0 get's stuck |
Posted: Fri Oct 25, 2013 7:11 am |
|
|
Another good catch. Thanks again for your help. _________________ A HW Engineer 'trying' to do SW !!! Run!!! |
|
|
|