Hades logoHades applet banner
PIC16F628 Capture/Compare-Module Demonstration

applet icon

The image above shows a thumbnail of the interactive Java applet embedded into this page. Unfortunately, your browser is not Java-aware or Java is disabled in the browser preferences. To start the applet, please enable Java and reload this page. (You might have to restart the browser.)

Circuit Description

This applet demonstrates the Capture/Compare Module of the PIC16F628 microcontroller. The circuit consists of the microcontroller, a standard ASCII-mode liquid-crystal display, and a few gates used as delay lines.

The program running on the microcontroller (see below) first sets the input/output direction of the ports A and B, initializes the on-chip timer and capture/compare modules, and next calls a function to initialize the liquid-crystal display. The timer module is initialized to generate periodic interrupts about every 2.5 seconds. On each interrupt, the value of the output pin B.2 is toggled. The capture module control register is setup so that a rising-edge on the capture input (pin B.3) captures the current value of the timer register into the 'current_value' value. The main routine of the program then consists of an endless loop, which displays the current value of the 'current_value' variable on the LCD.

Once the program has finished its initialization sequence, the current value of the 'current_value' variable from the CCP module is displayed on the LC display. In the demonstration circuit, a 4:1 multiplexer allows to select one of four different inputs to the capture input of the microcontroller. Three inputs are just connected via delay-lines (two inverters each) to the timer-interrupt output pin, while the fourth input is directly connected to an interactive switch ('capture').

Use the multiplexer control inputs (via switches S1 and S0) to select one of the delay-lines or the direct input. When you select one of the delay-lines as inputs to the capture input, the rising edge on the capture input will be delayed from the rising edge of the timer-interrupt output via a constant delay. Therefore, the timer value written into the capture register will be constant (because the timer register is reset by the timer interrupt), but depends on the actual gate-delays of the delay-line. Naturally, the default gate-delays are chosen so that each of the three delay-lines has a different total delay, but you can also modify the gate-delays via the property sheets of the inverters (popup-edit, enter gate delay, press apply button).

If you select the capture input switch via S1=0 and S0=0, you should then click the capture input switch and watch the resulting values on the display.

The program running on the microcontroller is based on the following C source code and LCD control functions:

#include #include "lcd4.c"

__CONFIG(9);

/*
 * demonstration of the PIC16F627/628 capture/compare module
 *
 * Compiled by using 
 * 
 picl -16f627 capture.c -Zg -Ohex
 on Hitech Picclite Compiler - Free Edition 
*/


long current_value = 0;

main() {
  char c;
  long current_value_aux;
  int i;
  
  // ******* Input/Output Configuration ********
  TRISA = 0x00; // PORT A - Output 
  TRISB = 0x08; // PORT B: input B3, Output B0-B2,B4-B7

  TMR1CS = 0;
  TMR1IF = 0;
  TMR1H  = 0x00;  TMR1L = 0x00;
  T1CKPS1 = 0;  T1CKPS0 = 0;
  T1SYNC = 0;
  TMR1IE = 1;
  TMR1ON = 1;

  CCP1M3 = 0; CCP1M2 = 1; CCP1M1 = 0; CCP1M0 = 1;
  CCP1IE = 1;

   GIE = 1;  // Interrupt Enable 
  PEIE = 1;


  // initialize the LC Display
  lcd_init();

  // loop forever....
  while(1) {
    // LC cursor left to right moving
    put_cmd(4);     
       
    // put LC cursor at column 10, first line
    adress_ddram(0x89);

    current_value_aux = current_value;
    // Send the sample to LCD by converting into 3 digit BCD value 
    for ( i = 0; i < 3; i++ ) {
      c = (current_value_aux % 10) + 48;  
      write_lcd_char(c);
      current_value_aux = current_value_aux/10;
    }
  }  // end loop forever

} // end main


/*
 * interrupt - routine 
 */
static void interrupt isr(void) {

  // if capture/compare interrupt: update 'current_value' from CCP value
  if ( CCP1IF ) {
    current_value = (CCPR1L & 0x00ff);
    CCP1IF = 0;
  }

  // if timer interrupt: reset timer and toggle Port B.2
  if ( TMR1IF ) {
    RB2 = !RB2;
    TMR1H = 0x00;  TMR1L = 0x00;
    TMR1IF = 0;
  }
}

Print version | Run this demo in the Hades editor (via Java WebStart)
Usage | FAQ | About | License | Feedback | Tutorial (PDF) | Referenzkarte (PDF, in German)
Impressum http://tams.informatik.uni-hamburg.de/applets/hades/webdemos/95-dpi/pic16f628-ccp/exemplo_capture.html