View previous topic :: View next topic |
Author |
Message |
swifteagle1
Joined: 25 Oct 2007 Posts: 4
|
CCP1 constantly triggering on 18F4520 |
Posted: Mon Jan 14, 2008 7:47 pm |
|
|
Hello,
I'm working on the PIC18F4520 microcontroller.
I'm using the ICDU40 for debugging.
I cant seem to find my compiler version.
I ran into the following issue with some code I was working on.
I have tried to debug it but think i need someone else to take a peek.
The following code shows the problem I am having.
I setup the CCP1 hardware and watch the CCP1IF flag through the watch window. As soon as the "setup_ccp1(CCP_CAPTURE_RE);" statement is completed, the CCP1IF register changes to 1 and will not allow me to reset it. The following code is pretty stripped down to just setup the CCP1 hardware and then try to reset the interupt flag over and over.
Is this something i am totally messing up?
Thanks in advance for your help guys.
#include <18F4520.h>
#device ICD=True //delete this line to allow this program to run on the PIC alone
#fuses HS,NOLVP,NOWDT
#use delay(clock=11059200) //11.0592Mhz
#use Fixed_IO(C_outputs=Pin_C1,Pin_C2)
//These define particular flags in the registers
#byte PIR1 = 0xF9E
#bit TMR1IF = PIR1.0 //Timer1 Interrupt flag bit
#bit CCP1IF = PIR1.2 //CCP1 Interrupt flag bit
//**************************************************Begin Main Program************************************************
//********************************************************************************************************************
void main()
{
disable_interrupts(global);
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_internal | T1_DIV_BY_8); //T1_DIV_BY_X - X = the number of clock cycles that pass before timer 1 is incremented.
enable_interrupts(global);
//**********************************************Pulse Detection ******************************************************
while(TRUE) //pulses over 500us count as valid unconfinement
{
clear_interrupt(INT_CCP1);
}
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 14, 2008 11:09 pm |
|
|
There are several problems:
1. You have no interrupt service routine for #int_ccp1.
2. You haven't enabled INT_CCP1 interrupts.
3. Pins C2 and C1 must be configured (or left as) inputs when
CCP1 and CCP2 are used. You have configured them as outputs.
4. Any time you change (or set) the CCP1 mode, it can cause the
interrupt flag to be set. You should clear the INT_CCP1 interrupt
flag before you enable global interrupts. |
|
|
swifteagle1
Joined: 25 Oct 2007 Posts: 4
|
|
Posted: Tue Jan 15, 2008 5:15 pm |
|
|
PCM Programmer, Thanks for your suggestions.
BTW I have compiler version 4.059 which I found in my .lst file that got created when i compiled my code.
Here is the modified code:
#include <18F4520.h>
#device ICD=True //delete this line to allow this program to run on the PIC alone
#fuses HS,NOLVP,NOWDT
#use delay(clock=11059200) //11.0592Mhz
//These define particular flags in the registers
#byte PIR1 = 0xF9E
#bit TMR1IF = PIR1.0 //Timer1 Interrupt flag bit
#bit CCP1IF = PIR1.2 //CCP1 Interrupt flag bit
//**************************************************Begin Main Program************************************************
//********************************************************************************************************************
void main()
{
disable_interrupts(global);
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_internal | T1_DIV_BY_8); //T1_DIV_BY_X - X = the number of clock cycles that pass before timer 1 is incremented.
clear_interrupt(INT_CCP1);
enable_interrupts(global);
//**********************************************Pulse Detection ******************************************************
while(TRUE) //pulses over 500us count as valid unconfinement
{
if(ccp1if == 1)
{
clear_interrupt(INT_CCP1);
}
}
}
I agree that I had the CCP modules configured as outputs which was wrong - fixed that
I have no ISR because for this, I wanted to watch the register value CCP1IF which triggers the ISR. Stripped down the extras from the code.
Bottom line, the code still sets CCP1IF to 1 as soon as the "setup_ccp1(CCP_CAPTURE_RE)" statement is executed and will not let me set it back to 1.
Interestingly enough if I run this code with out walking through it, the execution never enters the loop that executes when CCP1IF is 1.
i did some more reading on the forums and it seem that when you walk through the code or set breakpoints that the interrupt flags can get triggered.
Is this a known issue with the compiler/ICD? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 15, 2008 5:26 pm |
|
|
You should not enable Global interrupts without an interrupt service
routine. If you get an interrupt, the PIC will jump to the interrupt
address, but there's nothing there. The program operation will appear
to be erratic.
You can study the operation of the CCP1IF flag without enabling Global
interrupts. |
|
|
swifteagle1
Joined: 25 Oct 2007 Posts: 4
|
|
Posted: Tue Jan 15, 2008 5:32 pm |
|
|
Thanks PCM you are right, i did not need that there.
However that does not answer the question.
Say I go ahead and create a CCP1 ISR in the code I posted above.
If i step through it, the compiler will keep executing the ISR even if the CCP module is not triggered.
Now if i just run the code with no trigger events on the CCP module, it will run fine.
This makes it very hard to walk through and debug my code.
Is this a known issue?
Thanks for your quick response BTW |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 15, 2008 6:05 pm |
|
|
Quote: |
Say I go ahead and create a CCP1 ISR in the code I posted above.
If i step through it, the compiler will keep executing the ISR even if the
CCP module is not triggered. |
The Help file for the ICD2 (available inside MPLAB help) says this:
Quote: | PIC18FXXXX Limitations
You cannot single step through an interrupt.
Due to hardware restrictions the MPLAB ICD 2 cannot jump to the
interrupt vector memory location in single step or animate mode |
Quote: |
Q: When single stepping through the code, my timer times out, but why
does my timer interrupt routine not execute?
A: When single stepping, the in-circuit debugger will not allow the
PICmicro MCU to respond to interrupts. If it did, and users had external
interrupts, then single stepping would almost always end up in interrupt
routines. To debug an interrupt, set a breakpoint inside the Interrupt
Service Routine and Run to get a breakpoint after the interrupt. |
|
|
|
swifteagle1
Joined: 25 Oct 2007 Posts: 4
|
|
Posted: Tue Jan 15, 2008 6:49 pm |
|
|
Thanks PCM
So i guess i"ll have to always run to cursor one line at a time from now on. |
|
|
|