PIC18F14K50の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
CCP コンペア

PECCP (Enhanced Capture/Compare/PWM)のCompareモードは、タイマー1またはタイマー3を常時モニターしています。タイマーがCCPR1H / CCPR1Lで定められたカウントに達すると、以下の5種類のいずれかの動作を行います。

Special Eventを利用すると連携するタイマーカウンターを16ビットまでの任意の分周カウンターにすることができます。なお、CCP1(RC5)をCCPの出力に使用する場合には、TRISCのビットを"0"出力に設定する必要があります。 この機能を活用することで、精度の高いクロックを分周し時計や、周波数カウンターの基準時間を定期的に発生させることが可能です。注意点として、Special Event が発生しタイマーをゼロにリセットするので、CCPR1H / CCPR1Lにプリセットする値は(必要分周数ー1)となります。

関連するレジスター一覧を下表に示します。

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
RCON IPEN SBOREN RI TO PD POR BOR
INTCON GIE/GIEH PEIE/GIEL TMR0IE INTIE RABIE TMR0IF INT0IF RABIF
PIR1 - ADIF RCIF TXIF SSP1IF CCP1IF TMR2IF TMR1IF
PIE1 - ADIE RCIE TXIE SSP1IE CCP1IE TMR2IE TMR1IE
IPR1 ADIP RCIP TXIP SSPIP CCP1IP TMR2IP TMR1IP
CCP1CON P1M < 1 - 0 > DC1B < 1 - 0 > CCP1M < 3 - 0 >
TRISC TRISC7 TRISC6 TRISC5 TRISC4 TRISC3 TRISC2 TRISC1 TRISC
CCPR1L CCP Register 1, Low Byte
CCPR1H CCP Register 1, High Byte
レジスタ BIT 説明 1 0
RCON 7 IPEN 2レベルのインタラプト優先度 使用
INTCON 7 GIEH 高優先度インタラプトを使用許可 許可
6 GIEL 低優先度インタラプトを使用許可 許可
PIR1 1 CCP1IF CCP1 発生フラグ 発生  
PIE1 1 CCP1IE CCP1 インタラプトを使用許可 許可
IPR1 1 CCP1IP CCP1 インタラプト優先度
CCP1CON 3 CCP1M3 0000 =モジュール全体をOFF (初期値)
0010 =CCP1をトグル, 1000 =CCP1をLow→Hi, 1001 =CCP1をHi→Low
1010 =CCP1は変化せず、CCP1IFセット
1011 =Special Event を発生
2 CCP1M2
1 CCP1M1
0 CCP1M0

割り込みのプログラム例

タイマー1でシステムクロックをカウントし、CCPR1H / CCPR1Lで定められたカウントに達すると、Special Eventを発生させるプログラムを作成しました。Special Eventの発生でタイマー1をリセットし同時にンタラプトを発生させ出力を反転(LEDを点滅)させています。比較する値を可変するためにVRの値をAD変換し、CCPR1H にセットしています。

<回路図>

<プログラム>

//---------------------------------------------------------
//  CCPコンペア機能の確認
//  VRの値で出力する周波数が変化する  約 240Hz-1Hz
//
//  CCP    → 高優先インタラプトで signalOut を反転
//  VR     → VRの値をAD変換しTimer1と比較する値とする
//
//  Notes:  4MhzM内部クロック
//          AN11(RB5)  VR入力
//          RC5        signalOut
//    Language: MPLABX XC8
//    Target: PIC18F14K50
//--------------------------------------------------------

#include <xc.h>
#define _XTAL_FREQ 4000000      // delay_ms(x) のための定義

#define  signalOut   LATCbits.LATC5

//-------------- コンフィグレーション ----------------------
#pragma config FOSC = IRC        //  内部クロック
#pragma config USBDIV = OFF, CPUDIV = NOCLKDIV
#pragma config IESO  = OFF, FCMEN = OFF, PLLEN  = ON
#pragma config BORV  = 30,  BOREN = OFF, PWRTEN = OFF
#pragma config WDTPS = 32768, WDTEN = OFF
#pragma config MCLRE = OFF, HFOFST = OFF, XINST  = OFF
#pragma config BBSIZ = OFF, LVP    = OFF, STVREN = ON
#pragma config CP1  = OFF, CP0  = OFF, CPD  = OFF, CPB  = OFF
#pragma config WRT1 = OFF, WRT0 = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR1 = OFF, EBTR0 = OFF, EBTRB  = OFF


//----------------メインプログラム------------------
void main(void){
    OSCCON = 0b01010010;        // 内部クロック4Mhz
    TRISC = 0b11011111;         // PortC RC5出力
// ---------------- ADCの 設定 -------------------------
    ADCON2 = 0b00101100;        // 左詰め出力,AD変換クロックFosc/4
                                // チャージ時間 12_TAD
    ADCON1 = 0b00000000;        // 正基準電圧 VDD, 負基準電圧 VSS
    ADCON0 = 0b00101101;        // アナログ入力 AN11(RB5),ADC ON

    ANSELHbits.ANS11 = 1;       // AN11はアナログ入力に設定
// ------------ Timer 1 設定 ----------------------------
// システムクロックをカウントし、 CCPのCompare機能で、
// 一定時間ごとにインタラプトする。 
// ------------------------------------------------------
    T3CONbits.T3CCP1 = 0;      // Timer1 をCCPの信号源とする
    T1CON  = 0b00110001;       // Timer1 設定(262mSecごと)
                               // 8BITRW モード PS_1/8
                               // 内部クロックをカウント
// ---------------- CCPの 設定 ------------------------
    CCP1CON = 0b00001011;      // スペシャルイベント
    CCPR1H = 0xFF;             // 繰返し周期の暫定設定
    CCPR1L = 0xFF;             //
    IPR1bits.CCP1IP = 1;       // 高優先割り込み
    PIE1bits.CCP1IE = 1;       // 割り込みを使用する。
    PIR1bits.CCP1IF = 0;
    RCONbits.IPEN=1;           // 2段階のインタラプトに設定
    INTCONbits.GIEH=1;         // 高優先インタラプトを許可
    INTCONbits.GIEL=0;         // 低優先インタラプトは不使用
    while(1){
        ADCON0bits.GO = 1;     // AD変換開始
        while(ADCON0bits.GO);  // AD変換終了待ち
        CCPR1H = ADRESH;       // AD変換結果をCCP繰返周期に
        __delay_ms(100);        // LEDちらつき防止の遅延
    }
}

//----------------------高優先割込み------------------------
void interrupt Hi_Isr(void){
    if (PIR1bits.CCP1IF == 1) {     // CCPからの割り込みか
        PIR1bits.CCP1IF = 0;        // CCP割込フラグをOFF
        signalOut = ! signalOut;    // 出力を反転
    }
}