|
|
View previous topic :: View next topic |
Author |
Message |
renobaron
Joined: 15 May 2013 Posts: 7 Location: México
|
Problem with CCP module in capture mode and interrupts |
Posted: Mon Oct 12, 2015 11:11 am |
|
|
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
|
|
Posted: Mon Oct 12, 2015 11:38 am |
|
|
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
|
|
Posted: Mon Oct 12, 2015 11:43 am |
|
|
Problem solved! Thank you _________________ Reno Baron |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19505
|
|
Posted: Mon Oct 12, 2015 12:20 pm |
|
|
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
|
|
Posted: Mon Oct 12, 2015 12:27 pm |
|
|
OK now I understand what was happening. Thank you very much for taking the the time to reply.
Best regards, Reno _________________ Reno Baron |
|
|
|
|
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
|