CCP compare module interrupt not triggering -pic16f887 - XC8

Thread Starter

nitz49

Joined Mar 9, 2016
1
I am using pic16f887 compiler xc8 to count 20 pulses from external source by using Timer1 and compare module and on compare match, a software interrupt will enable to toggle RA6 pin.
i am unable to execute this code and interrupt is not triggering.

C:
[SIZE=3]#include <xc.h>

#define _XTAL_FREQ 4000000
#define LED1 RA0

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF  // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF  // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON  // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF  // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF  // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF  // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF  // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF  // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF  // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V  // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF  // Flash Program Memory Self Write Enable bits (Write protection off)

void main(void){
  TRISC0=1;  //input pin external Pulse
  TRISC2=0;
  TRISA0=0;  // LED1
  TRISA6=0;  // output pin

  RC0=0;
  RC2=0;
  LED1=0;
  RA6=0;

  CCP2CON=0x0A;
  T1CON=0x02;
  CCP2IE=1;
  GIE=1;
  PEIE=1;
  CCPR2L=20;
  CCPR2H=0;
  TMR1H=0;
  TMR1L=0;

  while(1) { 
  CCP2IF=0;
  TMR1ON=1;
  while(CCP2IF==0); // On match when CCP1IF=1, generate software interrupt
  }

}

void interrupt compare_isr(void)
{
  if(CCP2IF==1){ 
  TMR1ON=0;
  TMR1H=0;
  TMR1L=0;
  CCP2IF=0;
  LED1=1;
  RA6=~RA6;
  LED1=0; 
  }
}[/SIZE]
Mod edit: used CODE tags for readable code - removed excessive line breaks.
 

Attachments

Last edited by a moderator:

JohnInTX

Joined Jun 26, 2012
4,787
A few things:
You are clearing CCP2IF in a 'while' loop. CCP2IF should only be cleared in the interrupt routine when the interrupt is serviced. The way you have written the interrupt code, the work is done there. Remove this from main - that is not a software interrupt. Replace it with a while(1) to hold the code there while the interrupt does the work.
C:
while(1) {
  CCP2IF=0;
  TMR1ON=1;
  while(CCP2IF==0); // On match when CCP1IF=1, generate software interrupt
Enable interrupts only after configuring the CCP.
Visit the I/O port descriptions in the datasheet, particularly ANSEL.
If you are going to count transitions like this, be sure the switch is debounced and makes clean transitions from low to high for each press of the button.
You should always initialize unused ports to output 0.

What textbook are you using?

Good luck.
 
Top