Capture/Compare/PWM(CCP)モジュールは、さまざまなイベントの時間を計測制御し、パルス幅変調(PWM)信号を生成する周辺機器です。ここではこのモジュールのPWM機能について説明します。
PWMモードでは、さまざまな周波数とデューティサイクルのパルス幅変調信号を生成できます。このデバイスには、4つの標準CCPモジュール(CCP1、CCP2、CCP3、およびCCP4)が搭載されています。
PIC16F18325デバイスでは、各CCPモジュールが使用するタイマーソースをそれぞれ個別に選択することができます。3つの8ビットタイマー(Timer2、Timer4、Timer6)のどれを使用するかをCCPTMRSで指定します。
なお、このページでは、Timer2を選択したとして説明をしていますが、他のタイマーモジュールを選んだ時は、適宜読み替えてください。
*注意*
複数のCCPモジュールを備えたプログラムする時は、使用するレジスタ名に細心の注意を払うことが重要です。モジュールの頭字語の後に付けられた番号は、個別のモジュールを区別するために使用されます。たとえば、CCP1CONとCCP2CONは、2つの異なるCCPモジュールの同じ動作を制御します。
一般的に参照は、指定子「x」を使用して、モジュールを区別します。
パルス幅変調(PWM)は、完全にオンの状態と完全にオフの状態をすばやく切り替えることにより、負荷に電力を供給する方式です。PWM信号は方形波で、信号の高い部分がオン状態、信号の低い部分がオフ状態です。パルス幅とも呼ばれる高い部分は、時間とともに変化し、ステップ数と定義されます。パルス幅を長くするステップ数が多いほど、負荷により多くの電力が供給されます。ステップ数を減らすと、パルス幅が短くなり、供給される電力が少なくなります。PWM周期は、1サイクルの持続時間、またはオン時間とオフ時間の合計として定義されます。
PWM分解能は、単一のPWM周期に存在できる最大ステップ数と定義します。より高い分解能により、パルス幅時間のより正確な制御が可能になり、負荷に適用される電力がさらに正確に制御されます。
デューティサイクルという用語は、オン時間とオフ時間の比率を表し、パーセンテージで表されます。ここで、0%は完全にオフで、100%は完全にオンです。低いデューティサイクルは、適用される電力が少ないことに対応し、高いデューティサイクルは、適用される電力が多いことを意味します。
図13a-3に、PWM信号の代表的な波形を示します。
標準のPWMモードは、最大10ビットの分解能でCCPxピンにパルス幅変調(PWM)信号を生成します。周期、デューティサイクル、および分解能は、次のレジスタによって制御されます。
図13a-4に、PWM動作の簡略化したブロック図を示します。
*注意*
1. CCPRレジスタからの10ビットのアラインメントは、CCPxFMTビットによって決定されます。
2. 8ビットタイマーは、Foscによって生成された2ビットまたは内部プリスケーラーの2ビットと連結され、
10ビットのタイムベースを作成します。
標準PWM動作にCCPモジュールを構成する場合は、次の手順を実行します。
*注意*
最初のPWM出力で完全なデューティサイクルと周期を送信するには、上記の手順を設定シーケンスに含める必要があります。最初の出力で完全なPWM信号から開始することが重要でない場合は、ステップ6を無視できます。
PWM周期は、Timer2のPR2によって決定され、式13a-1の式を使用して計算できます。
式13a-1: PWM周期
PWM周期 = (PR2 + 1) x 4 x Tosc
PR2 : TMR2プリスケラー値
Tosc : 1/Fosc
TMR2がPR2と一致すると、次の3つのイベントが次の増分クロックサイクルで発生します。
*注意*
タイマーポストスケーラは、PWM周波数の決定には使用されません。
PWMデューティサイクルは、CCPRxH:CCPRxLペアに10ビット値を書き込むことで指定します。10ビット値のアラインメントは、CCPxCONのCCPRxFMTビットによって決定します(図13a-5を参照)。デューティサイクル値は、CCPRxH:CCPRxLペアに、いつ書き込んでも構いませんが、PR2とTMR2が一致するまで、10ビットバッファに転送されません。
図13a-5:PWM10ビットアライメントブロック図
式13a-2: パルス幅
パルス幅 = (CCPRxH:CCPRxLペア) x Tosc x(TMR2プリスケール値)
式13a-3: デューティサイクル比
| デューティサイクル比 = | (CCPRxH:CCPRxLペア) |
| 4 x (PR2 + 1) |
CCPRxH:CCPRxLペアと2ビットの内部ラッチは、PWMデューティサイクルをダブルバッファリングするために使用されます。このダブルバッファリングは、グリッチのないPWM動作を提供します。
8ビットタイマーTMR2は、2ビット内部システムクロック(Fosc)またはプリスケーラの2ビットのいずれかと連結されて、10ビットタイムベースを作成します。Timer2プリスケーラが1:1に設定されている場合は、システムクロックが使用されます。
10ビットのタイムベースがCCPRxH:CCPRxLペアと一致すると、CCPxピンがクリアされます(図13a-4を参照)。
ビット数で表されるPWM分解能は、単一のPWM周期に存在できるステップの最大数をで定義されます。たとえば、10ビットの解像度では1024個のステップになりますが、8ビットの解像度では256個のステップになります。PR2が255の場合、最大PWM分解能は10ビットです。分解能は、式13a-4に示すように、PR2レジスタ値の関数です。
式13a-4: PWM分解能
| 分解能 = | log {4(PRx + 1)} | bits |
| log(2) |
*注意*
パルス幅の値が周期よりも大きい場合、割り当てられたPWMピンは変更されません。
| PWM周波数 | 1.22 kHz | 4.88 kHz | 19.53 kHz | 78.12 kHz | 156.3 kHz | 208.3 kHz |
|---|---|---|---|---|---|---|
| プリスケラ値 | 16 | 4 | 1 | 1 | 1 | 1 |
| PR2値 | 0xFF | 0xFF | 0xFF | 0x3F | 0x1F | 0x17 |
| 最大解像度(bits) | 10 | 10 | 10 | 8 | 7 | 6.6 |
| PWM周波数 | 1.22 kHz | 4.90 kHz | 19.61 kHz | 76.92 kHz | 153.85 kHz | 200.0 kHz |
|---|---|---|---|---|---|---|
| プリスケラ値 | 16 | 4 | 1 | 1 | 1 | 1 |
| PR2値 | 0x65 | 0x65 | 0x65 | 0x19 | 0x0C | 0x09 |
| 最大解像度(bits) | 8 | 8 | 8 | 6 | 5 | 5 |
スリープモードでは、TMR2はインクリメントせず、モジュールの状態は変化しません。CCPxピンの値も変化しません。デバイスがウェイクアップすると、TMR2は以前の状態から続行します。
PWM周波数は、システムクロック周波数をもとにしています。システムクロック周波数を変更すると、PWM周波数も変更されます。
リセットを行うと、すべてのポートが強制的に入力モードになり、CCPレジスタがリセット状態になります。
| レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
|---|---|---|---|---|---|---|---|---|
| CCPxCON | CCPxEN | - | CCPxOUT | CCPxFMT | CCPxMODE<3:0> | |||
| CCPRxL | CCPRx<7:0> | |||||||
| CCPRxH | CCPRx<7:0> | |||||||
| CCPTMRS | C4TSEL<1:0> | C3TSEL<1:0> | C2TSEL<1:0> | C1TSEL<1:0> | ||||
| RxyPPS | - | - | - | RxyPPS<4:0> | ||||
| レジスタ | BIT | 名 | 説明 | 1 | 0 |
|---|---|---|---|---|---|
| CCPxCON | 7 | CCPxEN | CCPx モジュール ON/OFF | ON | OFF |
| 5 | CCPxOUT | CCPx 出力値 (Read only) | 1 | 0 | |
| 4 | CCPxFMT | CCPx デュティーサイクル位置アライメント | 上位 | 下位 | |
| <3:0> | CCPxMODE | PWMモード : 1111 | |||
| CCPRxL | <7:0> | CCPRxL | CCPRx デュティサイクル 下位 8 bit | ||
| CCPRxH | <7:0> | CCPRxH | CCPRx デュティサイクル 上位 8 bit | ||
| CCPTMRS | <7:6> | C4TSEL | CCPR4 連携タイマー 00 - 01 : TMR2, 10 : TMR4, 11 : TMR6 | ||
| <5:4> | C3TSEL | CCPR3 連携タイマー 00 - 01 : TMR2, 10 : TMR4, 11 : TMR6 | |||
| <3:2> | C2TSEL | CCPR2 連携タイマー 00 - 01 : TMR2, 10 : TMR4, 11 : TMR6 | |||
| <1:0> | C1TSEL | CCPR1 連携タイマー 00 - 01 : TMR2, 10 : TMR4, 11 : TMR6 | |||
PushSWを押続けている間、PWMのデューティサイクルを連続的に変化させるプログラムです。 デューティサイクルの変化をLEDの明るさで確認することができます。
<回路図>
<プログラム>
/*************************************
* File: PWM sample
* System ClockはConfigで内部1MHzに設定
* PushSWを押続けている間、PWMのデューティサイクルを連続的に+1し、
* LEDの明るさを連続的に変化させる。
* PushSWの接続される RA5は、Week Pull Upされている。
* LED RC3
* PushSW RA5
*
* PIC16F18325
* Created on Sep 2, 2017, 2:37 PM
**************************************/
#include <xc.h>
#define _XTAL_FREQ 1000000 // delay_ms(x) のための定義
#define LED LATC3
#define PushSW RA5
#pragma config FEXTOSC = OFF,RSTOSC = HFINT1 // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = OFF,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = OFF,CP = OFF,CPD = OFF
// ******************* main *************************************
void main() {
TRISA = 0b111111; // Port すべて入力
TRISC = 0b110000; // RC0-RC3 出力
ANSELA = 0; // すべてデジタル
ANSELC = 0; // すべてデジタル
WPUA5 = 1; // RA5を弱プルアップ
RC3PPS = 12; // CCP1をRC3に出力
//------------ Initialize PWM ----------------------------------
T2CON = 0b00000100; // Timer 2 PS1/1設定
PR2 = 0xFF; // Timer2 Period Register設定
CCP1CON= 0b10011111; // Duty 上位 PWM
CCPR1H = 0x80; // デュティサイクルを設定
while(1){ // 繰り返しループ
if(!PushSW){ // PushSWが押されれば
CCPR1H += 1; // デュティサイクルを+1し更新
__delay_ms(5); // 遅延(更新の速度)
}
}
}
PPS機能で、出力をどのpinにするか指定します。
CCP1をRC3に指定するなら、
RC3PPS = 12;
↑CCP1 を示す
PWM 信号を出力するピンは、TRIS ビットを"0"出力に設定する必要があります。