CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

INT_RA0 get's stuck

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ECACE



Joined: 24 Jul 2006
Posts: 94

View user's profile Send private message

INT_RA0 get's stuck
PostPosted: Wed Oct 23, 2013 9:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 23, 2013 11:20 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 23, 2013 11:24 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 23, 2013 11:35 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 23, 2013 4:34 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 23, 2013 4:45 pm     Reply with quote

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

View user's profile Send private message

[SOLVED] INT_RA0 get's stuck
PostPosted: Fri Oct 25, 2013 7:11 am     Reply with quote

Another good catch. Thanks again for your help.
_________________
A HW Engineer 'trying' to do SW !!! Run!!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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