Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

CCP1 + CCP2 + timer1 interrupts (compare match mode)

Status
Not open for further replies.

Anniyan_x

Member
hi i have timer1 as the time base for CCP1 and CPP2 module and the CCP module are configured in compare mode, generate software interrupts only.
the timer1 is also configured in timer overflow interrupt mode.

1)if i disable the CCP1 and CCP2 interrupts, the timer overflow interrupts is working fine.
2)CCP1 and CCP2 both are working fine if either one of teh module interrupts is disable and the timer1 interuppts also disable.

but if all the interrupts are enable, the program goes wrongly.

as per my understanding, i set CCP1 to a value, let say A, and CCP2 to another value, let say B and configured it to compare match mode with timer1, and timer overflow interrupts is also enabled. CCP are high priority and timer1 overflow is low priority. so when first match occurs in CCP1 module, a interrupts should generate and then timer continues counting and when the second match occures in CCP2, another interrupts should generate, and timer1 continues counting untill it overflow and the timer1 overflow interrupts is generated. the flow is not as above, timer1 interrupts get missed i guess, and the CCP2 interrupts is always generated
 
You need to post your code.

Edit, you do realise in special trigger mode it resets the timers.

Mike.
 
Last edited:
Just tried it and it works exactly as expected.

This was the code,
Code:
#include <p18f2620.h>

#pragma config OSC = INTIO67, WDT = OFF, LVP = OFF, PWRT = OFF, BOREN = OFF

void high_isr();                    

#pragma code high_vector=0x08    //setup the ISR vector
void low_interrupt (){
  _asm GOTO high_isr _endasm    //jump to interrupt handler
}
#pragma code

#pragma interrupt high_isr   //the ISR
void high_isr(){
    if(PIR1bits.TMR1IF){
    	PIR1bits.TMR1IF=0;
    }
    if(PIR1bits.CCP1IF){
    	PIR1bits.CCP1IF=0;
    }
    if(PIR2bits.CCP2IF){
    	PIR2bits.CCP2IF=0;
    }
}
#pragma code

void main(void)
{	
    OSCCON=0x72;         //set for 8Mhz
    T1CON=0X01;         //pre=1 and ON
    PIE1bits.TMR1IE=1;
    CCP1CON=0x0a;
    CCPR1=0x1234;
    PIE1bits.CCP1IE=1;
    CCP2CON=0x0a;
    CCPR2=0x2234;
    PIE2bits.CCP2IE=1;
    T3CON=0;
    INTCON=0xc0;
    while(1){
    }
}

Mike.
 
my code

Code:
#include <p18f45k20.h>					// Register definitions
#include <stdlib.h>
#include <string.h>

#include <timers.h>					// Timer library functions


void ISR_handler_TMR1_OVF (void);
void ISR_handler_compare1 (void);
void ISR_handler_compare2 (void);
void high_isr (void);
void low_isr (void);

/*
* For PIC18 devices the high interrupt vector is found at
* 00000008h. The following code will branch to the
* high_interrupt_service_routine function to handle
* interrupts that occur at the high vector.
*/
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
#pragma code /* return to the default code section */
#pragma interrupt high_isr
void high_isr (void)
{
if(PIR1bits.CCP1IF) 
	  {
    	PIR1bits.CCP1IF=0;//clear flag
		ISR_handler_compare1();
	  }
if(PIR2bits.CCP2IF) // input capture int occured
	  {
    	PIR1bits.CCP1IF=0;//clear flag
		ISR_handler_compare2();
	  }
}

/*
* For PIC18 devices the low interrupt vector is found at
* 00000018h. The following code will branch to the
* low_interrupt_service_routine function to handle
* interrupts that occur at the low vector.
*/
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
_asm GOTO low_isr _endasm
}
#pragma code /* return to the default code section */
#pragma interruptlow low_isr
void low_isr (void)
{
if(PIR1bits.TMR1IF) // tmr1 overflow
  {
  PIR1bits.TMR1IF = 0; //clear flag
  ISR_handler_TMR1_OVF();
  }	
}

void main (void)
{

//timer1 ccp1 and ccp2 init

  INTCONbits.GIE = 1;      // enable global interrupt
  INTCONbits.PEIE = 1;     // enables all peripheral interrupts
  RCONbits.IPEN = 1;        // enable priority levels



/***INITIALIZATION OF CCP1 AND CCP 2 with TIMER1 as time base********/
	
    CCP2CONbits.CCP2M0 = 0; // set CCP2 to output compare mode
    CCP2CONbits.CCP2M1 = 1;
    CCP2CONbits.CCP2M2 = 0;
    CCP2CONbits.CCP2M3 = 1;

    CCP1CONbits.CCP1M0 = 0; // set CCP1 to output compare mode,
    CCP1CONbits.CCP1M1 = 1;
    CCP1CONbits.CCP1M2 = 0;
    CCP1CONbits.CCP1M3 = 1;
	
    T3CONbits.T3CCP1 = 0;  	
    T3CONbits.T3CCP2 = 0; 	// timer1 is time base for CCP1 and CCP2
	
    T1CONbits.RD16 		= 1;    // enable 16bit Read/Write
    T1CONbits.T1RUN 	= 0;    // main sys clck frm another source
    T1CONbits.T1CKPS0 	= 1;
    T1CONbits.T1CKPS1 	= 1;    //1:8 prescale value
    T1CONbits.T1OSCEN 	= 0;    //tmr1 osc shut off
    T1CONbits.TMR1CS 	= 0;    //int clk (fosc/4)

	
//interupts

/********************************/
    PIE1bits.CCP1IE = 1; //CCP1 interrupt enable-
    PIE2bits.CCP2IE = 1; //CCP2 interrupt enable
/********************************/
	
    IPR1bits.CCP1IP = 1; // 0 low, 1 high for CCP
    IPR2bits.CCP2IP = 1; // 0 low, 1 high
	
    PIR2bits.CCP2IF = 0;
    PIR1bits.CCP1IF = 0;
	
		
/********************************/
PIE1bits.TMR1IE = 1; // enable timer1 int overflow
/********************************/


    IPR1bits.TMR1IP = 0; // tmr1 ovrflw int low priority
    
     CCPR2L = 0xFE;     // 44030 0.35224, 4mhz
     CCPR2H = 0xAB;
    
     CCPR1L = 0xFF;
     CCPR1H = 0x64;     //25855 0.20684
     
     TMR1L = 0;
     TMR1H = 0; // clear timer
     
     T1CONbits.TMR1ON 	= 1; //started timer 

while(1)
    {
     while(1);
    }

}

void ISR_handler_TMR1_OVF (void)
{
  unsigned int x;  // just simply
  
  x= x+1;
}
 
void ISR_handler_compare1 (void)
{
   unsigned int x;  // just simply
  
  x= x+1;
}

void ISR_handler_compare2 (void)
{
  unsigned int x;
  
  x= x+1;
}
 
yes i do realize in special trigger mode it will clear the tmr1 but im not using the special trigger mode, stime although i didnt set CCP2 to interrupt but just set CCP1, i get a interrupt in the CCP2 vector also.... all only works fine only 1 interrupt of the 3 (CCP1,CCP2,TMR1,) is enabled.. maybe i need go through the stimulations again and reply soon.
 
I guezz the problems solved, i didnt clear the CCP2IF and in that isr i clear CCP1F, so the CCP2IF interrupts was always generating and made all the problems
 
Your code is continually interrupting due to a typo in your ISR,
Code:
    if(PIR2bits.CCP2IF) // input capture int occured
    {
        PIR[COLOR="red"]1[/COLOR]bits.CCP[COLOR="red"]1[/COLOR]IF=0;//clear flag
        ISR_handler_compare2();
    }

The red bits should be 2.

Edit, also, this code should be after you set everything up, not first,
Code:
  INTCONbits.GIE = 1;      // enable global interrupt
  INTCONbits.PEIE = 1;     // enables all peripheral interrupts

Mike.
 
Last edited:
yup thanks, by the way sometimes, but very rarely, i still miss the TMR1 overflow interrupt, the interrupts is always in CCP1 and CCP2 only.. and never goes into the tmr1 overflow but after few resets it works fine all the while.. im just stimulating using the stimulator
 
Did you move where you set the global interrupt bit. This will cause problems that would disappear after a few resets.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top