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

Problem with CCP module in capture mode and interrupts

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



Joined: 15 May 2013
Posts: 7
Location: México

View user's profile Send private message Visit poster's website

Problem with CCP module in capture mode and interrupts
PostPosted: Mon Oct 12, 2015 11:11 am     Reply with quote

Hello

I am working with the CCP module of the PIC16F628A, in capture mode.

To test it I made a simple program:

Here is my test code (explained below):
Code:


#include <main.h>

/*
Globals
*/

long timer;
long tVal[2];

#INT_CCP1
void CCP1_isr(void)
{
   disable_interrupts(GLOBAL);
   tVal[i] = (tVal[i] >> 1) + ((CCP_1 - timer) >> 1);  //average the period
   output_toggle(PIN_B0);   //Half the freq of the signal at CCP1 pin
   timer = CCP_1;
   clear_interrupt(INT_CCP1);
   enable_interrupts(GLOBAL);
}


#INT_TIMER1
void TIMER1_isr(void)
{
    disable_interrupts(GLOBAL);
    output_toggle(PIN_B1);   //~38Hz signal
    clear_interrupt(INT_CCP1);
    clear_interrupt(INT_TIMER1);
    enable_interrupts(GLOBAL);
}



void main()
{
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);      //13.1 ms overflow
   setup_ccp1(CCP_CAPTURE_RE);
   setup_comparator(NC_NC_NC_NC);
   
   input(PIN_B3);      //CCP1 pin as input
   
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_CCP1);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {   
      delay_ms(10);
      output_toggle(PIN_A3);   //50Hz signal
   }

}




I have a 20MHz xtal oscillator. (Fosc/4 = 5MHz).
Timer 1 interrupt will fire every 13.1ms (65536/5MHz).
The CCP module is configured as capture every rising edge.

The main loop toggles the state of pin A3 each 10ms, resulting in a 50Hz signal. (10ms high, 10ms low = 20ms period).

The Timer1 interrupt routine toggles the state of pin B1, resulting in a ~38Hz signal. (13.1ms high, 13.1ms low = 26.2ms period).

The CCP1 interrupt will calculate the period of the signal and toggle pin B0 (at half the frequency of the one present at CCP1 pin).

I have a 1Khz signal connected to the CCP1 Pin through a push button as shown in the following diagram:

Code:

              ___ Push button switch 
             _|_|_
1Khz  -------o   o---------------------> CCP1 PIN
                             |
                             <
                             >  2.2K
                             <
                             |
                           ----
                            --    GND



The problem is that sometimes when I press and release the switch, the signal on pin A3 disappears, as if the main loop stopped executing, but the signal from the Timer1 interrupt on pin B1 (38Hz) and also the signal on pin B0 (500Hz) are still present.

Sometimes if I keep pressing and releasing the switch, the signal on pin A3 will come back, but not always.

Some other times, the opposite occurs; the interrupts stop executing (No signals on B0 and B1), while the main loops is running ok (signal on A3).


I have a stable power supply, and put with all decoupling and bypass capacitors.

What's be the problem here? maybe I'm missing something about the capture mode of the CCP module? The fact that I am using a push button definitely will put some very high frequency pulses in the CCP1 pin, and I think that's related with the problem, but I don't know why.


Thanks in advance!

Reno

[edit]
The failure will occur even if i keep the switch closed, or make a direct connection between the 1KHz signal and the CCP1 pin.
[/edit]
_________________
Reno Baron
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 11:38 am     Reply with quote

Quote:
Some other times, the opposite occurs; the interrupts stop executing (No
signals on B0 and B1), while the main loops is running ok (signal on A3).


At a minimum, delete the lines shown in bold below. All of this is handled
by the PIC hardware, or by the compiler. And, they do it at the
appropriate time and place.
Quote:
#INT_CCP1
void CCP1_isr(void)
{
disable_interrupts(GLOBAL);
tVal[i] = (tVal[i] >> 1) + ((CCP_1 - timer) >> 1); //average the period
output_toggle(PIN_B0); //Half the freq of the signal at CCP1 pin
timer = CCP_1;
clear_interrupt(INT_CCP1);
enable_interrupts(GLOBAL);
}


#INT_TIMER1
void TIMER1_isr(void)
{
disable_interrupts(GLOBAL);
output_toggle(PIN_B1); //~38Hz signal
clear_interrupt(INT_CCP1);
clear_interrupt(INT_TIMER1);
enable_interrupts(GLOBAL);
}
renobaron



Joined: 15 May 2013
Posts: 7
Location: México

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 12, 2015 11:43 am     Reply with quote

Problem solved! Thank you
_________________
Reno Baron
Ttelmah



Joined: 11 Mar 2010
Posts: 19505

View user's profile Send private message

PostPosted: Mon Oct 12, 2015 12:20 pm     Reply with quote

As an extra comment, to explain why it is vital to _get rid of the enable/disable interrupts in the handler_. Long term this can cause an absolute disaster.

The PIC hardware automatically disables the interrupt when the handler is called, and automatically enables it again the instruction _after_ the processor returns from the interrupt, The actual return used automatically does this so that the interrupts do not get re-enabled till _after_ the chip has returned.
If you re-enable the interrupt while inside the handler, then a second interrupt in the moment after this is done, _will_ result in the return stack getting corrupted. Ugh....
renobaron



Joined: 15 May 2013
Posts: 7
Location: México

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 12, 2015 12:27 pm     Reply with quote

OK now I understand what was happening. Thank you very much for taking the the time to reply.

Best regards, Reno
_________________
Reno Baron
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