動作原理
前述した設計上の制約により、CCPモジュールが機能を実行するには8ビットまたは 16ビットタイマが必要です。
CCPモジュールと奇数(16ビット)タイマを組み合わせると、16ビットのキャプチャを実行し て入力パルスの幅を計測できます。
また、CCPモジュールと奇数(16ビット)タイマを組み合わせると、16ビットのコンペア機能 を実行して必要な幅の出力パルスを生成できます。
CCPモジュールと偶数(8ビット)タイマを組み合わせると、周期分解能が8ビットでデュー ティ サイクル分解能が10ビットの出力PWM信号を生成できます。
一部のモデル(PIC16F19xx等)ではPWMモードが強化されており(ECCP)、単純なパル ス/PWM矩形 波 で は な く 、 相 補 出 力 信 号 ペ ア を生成 で き ま す 。 こ れ は 、 相 補 的 な
MOSFETデバイスペアを負荷に接続する、多くの電源制御アプリケーションで便利です。
大きなゲート寄生容量により、転流中に両方の電源デバイスが同時に有効になる事(結果 として生じる貫通電流)を防止するため、デッドバンド制御(遅延)を追加できます。
さらに最近の設計では、相補出力を制御する回路がCCPモジュールから分離されており、
完全に独立したモジュールとして使えます。(第2章の「CWG」および「COG」セクション参 照)。
図2.6: PWMの概略ブロック図
PWM 専用モジュール
同様に、最近のマイクロコントローラ ファミリでは、PWM機能のみを備えたモジュールが 追加されています。これは、CCPモジュールの用途としてPWM機能が圧倒的に多い事 が分かったためです。
アプリケーション
パルスの計測/生成(キャプチャ/コンペア)は、各種組み込みアプリケーションで使われて おり、その用途はセンサとの接続と簡単なアクチュエータの制御です。
PWM出力はサーボ制御に使われており、電源およびモータ制御アプリケーションで一般 的です。
また、D/A変換ツールとして使う事もできます。実際には、10ビットまでの分解能では 、 PWM出力からアナログ出力信号への変換は単純なRCフィルタで十分です。
制限事項
公称分解能(デューティ サイクル コンパレータ回路で使用可能なビット数)がいくつであっ ても、PWMの実効(DC)分解能は使用可能なクロック源によって常に制限されます。以下 にその計算式を示します。
a)
Fosc = 2PWMresolution * PWMfreq
b) PWM分解能を求める:
PWMresolution = log2( Fosc / PWMfreq)
計算式 2. 1 - 実効 PWM 分解能
計算式2.1bに示した通り、クロック周波数(Fosc)が一定の場合、PWM周波数が高くなれ ば、結果的にPWMの実効分解能は低くなります。
例えば、32 MHzのシステムクロックで10ビットの分解能を達成できるのは、PWM周波数
が32 kHz未満の時だけです。
MCC が生成する API
MCCは適切なタイマを選択してCCPモジュールへ接続するプロセスを完全に自動化す る事で、CCPおよびPWMモジュールが簡単に使えるようにしています。割り込みベクタ が有効の場合、これもInterrupt Managerモジュールに追加されます。
既定値のCCPx_Initialization()関数以外に、MCCは選択した機能に応じて各種 APIを生成します。
• キャプチャ: CCPx_IsCapturedDataReady()は使いやすく、キャプチャ イベント をポーリングし、CCPx_CaptureRead()はパルス/イベント継続時間を返します。
• コ ン ペ ア: CCPx_CompareCountSet()は必要 な パ ル ス 出 力幅を設定 し 、 CCPx_IsCompareComplete()関数はパルス生成シーケンスが完了したかどう かをポーリングします。
• PWM: PWMx_LoadDutyValue()関数を使うと、10ビットのデューティ サイクル レジスタを簡単に設定できます。
ピン配置
初期のPIC16F18xxおよびPIC16F19xxモデルでは、CCP/PWMモジュール用の入出力 ピン選択が固定されていました。
PIC16F150xファミリでは、全てのCCP-PWMピンをCLCモジュールに再割り当てし、こ
れを介してさらにより多くのI/Oおよび周辺モジュールに再割り当てする事ができます。
最新ファミリ(例: PIC16F16xx、PIC16F17xx)にはペリフェラル ピンセレクト(PPS)機能が追 加されており、これを使うと、使用可能な全てのデジタルI/OにCCP=PWM信号を出力で きます。
ホームワーク
• CCPまたはPWMモジュールを使ってサーボを制御する方法を調べましょう。
• PWMを使ってアナログ出力を生成する方法を調べ、DACを使った場合と比較 しましょう。
• 複数のPWM出力が同じタイマを共有できる場合と、別々のタイマが必要になる 場合を調べましょう。
オンライン リソース
『AN1175 - Sensorless Brushless DC Motor Control with PIC16』
『AN1261 - Dimming Power LEDs Using a SEPIC Converter and MCP1631 - PWM Controller』
『AN1305 - PIC16FXXXを使用するセンサレス3相ブラシレスモータ制御』
『AN1562 - 高分解能RGB LEDの色調制御』
『AN594 - Using the CCP Module』
例
CCPまたはPWMモジュールを使ってサーボモータを制御する例を以下に示します。
/* Project:ADC to PWM Servo * Device: PIC16F1509 */
#include "mcc_generated_files/mcc.h"
#define TCLK _XTAL_FREQ / 4
#define TPERIOD (unsigned char)(TCLK/4 * 0.008) // 125Hz period (8ms)
#define SERVO_MIDDLE (unsigned)(TCLK * 0.0014) // 1.4ms
#define SERVO_MIN (unsigned)(TCLK * 0.0004) // 0.4ms
#define SERVO_MAX (unsigned)(TCLK * 0.0024) // 2.4ms void main(void)
{
// configure ADC to trigger from Timer2 and generate an interrupt // configure PWM1 for an 8ms period
SYSTEM_Initialize();
// Enable Interrupts
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
while (1) {
} }
/* edited in the adc.c file
*/
void ADC_ISR( void)
{ // read potentiometer value and translate to servo angle uint16_t duty;
duty = SERVO_MIN + ( ADC_GetConversion( Potentiometer));
if ( duty > SERVO_MAX)
duty = SERVO_MAX;
PWM1_LoadDutyValue( duty);
// Clear the ADC interrupt flag PIR1bits.ADIF = 0;
}