---
---
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; // 出力を反転
}
}