Experiment #10. CCP module (Capture/compare)

In this experiment I’ll try to investigate beatiful module which has name CCP (Capture/Compare/Pwm).

Let’s start!

From it’s name we can conclude, the module can:

1. To capture

2. To compare

3. To make pwm based waveform 🙂

The main register for this module is the ССP1CON:

CCP1X:CCP1Y – bits that’s I’ll talk about a bit later

CCP1M<3:0> – mode setup:

0000 = all off

0100 = capture on falling edge

0101 = capture on rising edge

0110 = capture on each 4 rising edge

0111 = capture on each 16 rising edge

1000 = compare, output pin will set in “1” if there is matching event

1001 = compare, output pin will set in “0” if there is matching event

1010 = compare, interrupt generation

1011 = compare and I don’t have final undestanding about this issue

11хх = PWM mode

Look at capture mode for the beginning:

In this mode the content of TMR1H and TMR1L copies to CCPR1H and CCP1L register in cases:

  • On each falling edge at RB3
  • On each rising edge at RB3
  • On each 4-th rising edge at RB3
  • On each 16-th rising edge at RB3

If you want your capture module works fine, you have to:

  • Pin RB3 must be configured as input
  • TMR1 must works as a timer or a counter

You can get interrupt on capture event (ССP1IF flag).

Compare: In this mode content of CCP1 compares with content of TMR1. It is possible to get interrupt event or change logical value at RB3 in case of matching.

If you want your compare module works fine, you have to:

  • Pin RB3 must be configured as output
  • Timer TMR1 has internal synchronization (Focs/4)

Lets write a small code for testing compare mode.


#include <htc.h>
#define _XTAL_FREQ 4000000

__CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS);

void main() {
unsigned char x;
__delay_ms(100);
TRISB = 0x00;
PORTB = 0x00;

CCPR1H = 0b00000011; CCPR1L = 0b11101000; // 1000 in CCPR1
CCP1M3 = 1;                               // interrupt on compare value
CCP1M2 = 0;
CCP1M1 = 1;
CCP1M0 = 0;

T1CKPS1 = 0;
T1CKPS0 = 0;  // Prescaler = 0

T1OSCEN = 0;
TMR1CS = 0;   // Fosc/4
TMR1ON = 1;
T1SYNC = 0;

GIE = 1;
PEIE = 1;
CCP1IE = 1;

for (;;) {

}

}

void interrupt isr() {
if (CCP1IF) {
RB3 = !RB3;
TMR1H = 0x00; TMR1L = 0x00;
CCP1IF = 0;
}

}

With 4 MHz clock, one count is 1 us, so 1000 counts is 1 ms.

Result:
oscil

Sources

I don't put information about the most intersting module PWM here, because I think it is so important and it have to be placed at other experiment.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.