概要
現在発売されている8bit~32BitPICの数多くのマイコンにPWMモジュールが搭載されています。
単純なPWMであればアウトプットコンペアモジュールでも出力が可能ですが、このPWMモジュールはより高度なPWM波形を生成するために使用されます。
PWMとはPulse Width Modulationの略で、周期は固定でデューティ比を変化させてパルス変調させて制御する。電源やモータ制御など様々なシーンで使用される。
PRGとは Programmable Ramp Generatorの略でランプ波形を生成できる機能
スイッチング電源のピーク電流モードなどで低調波発振を防止可能
更新履歴
| 更公開/変更日 | 更新内容 |
| 2022.08.15 | 初版公開 |
| 2023.02.13 | 誤記修正 |
| 2025.04.13 | タイトル修正、リンク追加、カテゴリ変更 |
関連リンク
| 記事 | リンク | |
| 第1回 | 8bitPICシリーズ① PRGモジュールの使い方 | 8bitPICシリーズ①PRGモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第2回 | 8bitPICシリーズ② PWMモジュールの使い方 | 8bitPICシリーズ②PWMモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第3回 | 8bitPICシリーズ③ SMTモジュールの使い方 | 8bitPICシリーズ③SMTモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第4回 | 8bitPICシリーズ④ Timerモジュールの使い方 | 8bitPICシリーズ④Timerモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第5回 | 8bitPICシリーズ⑤ Angular Timer モジュールの使い方 | 8bitPICシリーズ⑤Angular Timer モジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第6回 | 8bitPICシリーズ⑥ CLB(Configurable Logic Block)モジュールの使い方 | 8bitPICシリーズ⑥CLB(Configurable Logic Block)モジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第7回 | ||
| 第8回 | ||
| 第9回 | ||
| 第10回 |
PICシリーズのPWMモジュール
各マイコンに搭載されるPWMモジュールのハードウェアの内部構成はシリーズによって異なり使用方法も大きく異なります。
1.PIC16(L)F176xシリーズなど
シンプルな構造。Dutyや周期は10Bit幅しか設定できない。
相補パルスやデッドタイムは後段に接続するCOGやCWGで生成。

Bit幅が16Bitに拡張され位相やオフセットが設定。
相補パルスやデッドタイムは後段に接続するCOGやCWGで生成。

2.PIC18FxxQ43シリーズなど
Bit幅は16Bit。単独のPWMモジュールで2出力のパルスが出力可能。
相補パルスやデッドタイムは後段に接続するCOGやCWGで生成。

以下に8BitPICシリーズの新旧PWMモジュールの比較表を転載します


3.PIC33Cシリーズなど
非常に高性能な16Bitタイマ。分解能が250psecまで設定可能。電源制御やモーター制御アプリケーション向けにフォルトや外部PWM同期など機能は多数。


今回は「PIC18F57Q43」のPWMモジュールを使用します。
ハードウェア構成と制御ブロック
PIC18FxxQ43シリーズの16BitPWMは下記のようにクロックソース、プリスケーラ、タイマー、周期レジスタ、P1,P2レジスタと出力モジュールによって構成されています。
また出力モードは大きく以下の5モードに分かれます。
- Left Aligned Mode(左詰め)
- Right Aligned Mode(右詰め)
- Center Aligned Mode(中央詰め)
- Variable Alignment Mode(可変詰め)
- Compare Modes(比較モード)
1.Left Aligned Mode
周期の開始からPWMはアクティブ(High)になりP1、P2パラメータで指定された期間継続します。その後インアクティブ(Low)になります。


2.Right Aligned Mode
周期の開始からPWMはインアクティブ(Low)になり周期値 – P1、P2パラメータで指定された期間継続します。その後アクティブ(High)になります。


3.Center Aligned Mode
周期の開始からPWMはインアクティブ(Low)になり周期値 – P1、P2パラメータで指定された期間継続します。その後アクティブ(High)になります。また次の周期では周期の開始からPWMはアクティブ(High)になりP1、P2パラメータで指定された期間継続します。その後インアクティブ(Low)になります。つまり他のモードに比べ2倍の周期になります


4.Variable Alignment Mode
タイマーとP1の値が一致した時にPWMはアクティブ(High)になり、タイマーとP2の値が一致した時にPWMはインアクティブ(Low)になります。P1出力とP2出力は同一パルスとなります。


5.Compare Modes
コンペアモードは更に2つのモードに分かれます
1.パルスコンペアモード
タイマーとP1の値が一致した時に1クロック分のパルスがP1から出力され、タイマーとP2の値が一致した時に1クロック分のパルスがP2から出力されます。


2.トグルコンペアモード
タイマーとP1の値が一致した時にP1出力が反転し、タイマーとP2の値が一致した時にP2出力が反転します。


ハードウェア構成
今回はPWM1を右詰めモードで動作させ、その生出力と出力にデッドバンド(デッドタイム)を付加させた信号を観察します。

ソースコード
ソースコードは以下の通りです。
特筆すべき点はありませんが、CWGのデッドバンドを設定した後にレジスタに反映するためはCWG1CON0bits.LDをセットしてロードすることが必要です。
#include "xc.h"
#pragma config FEXTOSC = ECH
#pragma config RSTOSC = EXTOSC
//CONFIG2
#pragma config CLKOUTEN = OFF
#pragma config FCMEN = ON
#pragma config CSWEN = ON
#pragma config PR1WAY = ON
//CONFIG3
#pragma config MVECEN = OFF
#pragma config MCLRE = EXTMCLR
#pragma config BOREN = SBORDIS
#pragma config PWRTS = PWRT_OFF
#pragma config IVT1WAY = ON
#pragma config LPBOREN = OFF
//CONFIG4
#pragma config XINST = OFF
#pragma config LVP = ON
#pragma config ZCD = OFF
#pragma config STVREN = ON
#pragma config BORV = VBOR_1P9
#pragma config PPS1WAY = ON
//CONFIG5
#pragma config WDTCPS = WDTCPS_31
#pragma config WDTE = OFF
//CONFIG6
#pragma config WDTCWS = WDTCWS_7
#pragma config WDTCCS = SC
//CONFIG7
#pragma config SAFEN = OFF
#pragma config BBEN = OFF
#pragma config BBSIZE = BBSIZE_512
#pragma config DEBUG = OFF
//CONFIG8
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config WRTAPP = OFF
#pragma config WRTSAF = OFF
//CONFIG10
#pragma config CP = OFF
int main(void)
{
/*--------------------------------------------------------------------------------*/
/* オシレータ設定 */
/*--------------------------------------------------------------------------------*/
OSCCON1 = 0x60;
OSCCON3 = 0x0;
OSCEN = 0x0;
OSCFRQ = 0x8;
OSCTUNE = 0x0;
ACTCON = 0x0;
/*--------------------------------------------------------------------------------*/
/* ピン設定*/
/*--------------------------------------------------------------------------------*/
TRISD = 0xFC;
TRISF = 0x3C;
RD0PPS = 0x0B; //RD0->CWG1:CWG1C;
RD1PPS = 0x0C; //RD1->CWG1:CWG1D;
RF0PPS = 0x18; //RF0->PWM1_16BIT:PWM11;
RF1PPS = 0x19; //RF1->PWM1_16BIT:PWM12;
/*--------------------------------------------------------------------------------*/
/* CWG設定*/
/*--------------------------------------------------------------------------------*/
CWG1CON0 = 0x84; //CWG1 ON & ハーフブリッジモード
CWG1CLKCON = 0x0;
CWG1CON1 = 0x0;
CWG1DBR = 0x23; //立ち上がりデッドバンド
CWG1DBF = 0x23; //立ち下がりデッドバンド
CWG1AS0 = 0x14;
CWG1AS1 = 0x0;
CWG1STR = 0x0;
CWG1ISM = 0x4; //CWGInput = PWM11
CWG1CON0bits.LD = 1; //デッドバンドロード(重要)
/*--------------------------------------------------------------------------------*/
/* PWM設定 */
/*--------------------------------------------------------------------------------*/
PWM1ERS = 0x0;
PWM1CLK = 0x2; //CLOCK = FOC
PWM1LDS = 0x0;
PWM1PRL = 0x7F; //周期下位8Bit
PWM1PRH = 0x2; //周期上位8Bit
PWM1CPRE = 0x0;
PWM1PIPOS = 0x0;
PWM1GIR = 0x0;
PWM1GIE = 0x0;
PWM1S1CFG = 0x1;
PWM1S1P1L = 0x40; //P1下位8Bit
PWM1S1P1H = 0x1; //P1上位8Bit
PWM1S1P2L = 0x20; //P2下位8Bit
PWM1S1P2H = 0x0; //P2上位8Bit
PIR4bits.PWM1PIF = 0;
PIR4bits.PWM1IF = 0;
PWM1GIRbits.S1P1IF = 0;
PWM1GIRbits.S1P2IF = 0;
PIE4bits.PWM1IE = 0;
PIE4bits.PWM1PIE = 0;
PWM1CON = 0x80;
while(1)
{
}
}
結果
以下のようにP1、P2の生出力とP1にデッドバンドをつけた相補PWMが出力されています。



コメント