16F18325には、分解能10ビットのPWM専用モジュールが2組(PWM5,PWM6)あり、タイマー2と連携してPWM信号を発生させることができます。2本あるCCPモジュールにも、同機能のPWMモジュールがあるため合計4組のPWMモジュールがあります。
PWMの繰り返し周期は、タイマー2のPR2の設定値で決定し、デューティーサイクルは PWMxDCH と PWMxDCL に分けて保存されています。タイマー(TMR2)とPR2の値が一致するとTMR2をリセットします。同時に、PWM出力を”1”にセットし、PWMxDCH と PWMxDCLの値を、コンパレータ内部レジスタにコピーします。この値が、TMR2の値と一致するとPWM出力を”0”にリセットします。つまり、PR2の設定値の半分の値をPWMxDCHにセットすればデューティー50%の波形が出力されます。
				| レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | 
|---|---|---|---|---|---|---|---|---|
| PWM5CON | PWM5EN | - | PWM5OUT | PWM5POL | - | - | - | - | 
| PWM5DCH | PWM5DCH<7:0> | |||||||
| PWM5DCL | PWM5DCL<7:6> | - | - | - | - | - | - | |
| PWM6CON | PWM6EN | - | PWM6OUT | PWM6POL | - | - | - | - | 
| PWM6DCH | PWM6DCH<7:0> | |||||||
| PWM6DCL | PWM6DCL<7:6> | - | - | - | - | - | - | |
| RxyPPS | - | - | - | RxyPPS<4:0> | ||||
| レジスタ | BIT | 名 | 説明 | 1 | 0 | 
|---|---|---|---|---|---|
| PWMxCON | 7 | PWMxEN | PWMx モジュール ON/OFF | ON | OFF | 
| 5 | PWMxOUT | PWMx 出力値 (Read only) | 1 | 0 | |
| 4 | PWMxPOL | PWMx 出力極性 | 負論理 | 正論理 | |
| PWMxDCH | <7:0> | PWMxDCH | PWMx デュティサイクル 上位 8 bit | ||
| PWMxDCL | <7:6> | PWMxDCL | PWMx デュティサイクル 下位 2 bit | 
| プリスケラ値 | 1/64 | 1/16 | 1/4 | 1/1 | |||||
|---|---|---|---|---|---|---|---|---|---|
| PR2 セット値 | 0xFF | 0xF9 | 0xFF | 0xF9 | 0xFF | 0xF9 | 0xFF | 0xF9 | |
| Fosc | 1MHz | 15.3Hz | 15.6Hz | 61Hz | 62.5Hz | 244Hz | 250Hz | 976Hz | 1KHz | 
| 4MHz | 61Hz | 62.5Hz | 244Hz | 250Hz | 976Hz | 1KHz | 3.91KHz | 4KHz | |
| 16MHz | 244Hz | 250Hz | 976Hz | 1KHz | 3.91KHz | 4KHz | 15.6KHz | 16KHz | |
| 32MHz | 488Hz | 500Hz | 1.95KHz | 2KHz | 7.82KHz | 8KHz | 31.2KHz | 32KHz | |
FoscとPWM周波数の関連
PushSWを押続けている間、PWMのデューティサイクルを連続的に変化させるプログラムです。 デューティサイクルの変化をLEDの明るさで確認することができます。
<回路図>
			
			<プログラム>
/*************************************
 * File: PWM sample
 * System ClockはConfigで内部1MHzに設定
 * PushSWを押続けている間、PWMのデューティサイクルを連続的に+1し、
 *  LEDの明るさを連続的に変化させる。
 *  PushSWの接続される RA5は、Week Pull Upされている。
 *        LED RA5
 *        PushSW RA3
 *
 * PIC16F18313
 * Created on 2020-06-14
 **************************************/
#include <xc.h>
#define _XTAL_FREQ 1000000      // delay_ms(x) のための定義
#define LED    LATA5
#define PushSW RA3
#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  = 0b011111;          // RA5 Output
    ANSELA = 0;                 // すべてデジタル
    RA5PPS = 2;                 // PWM RA5
//------------ Initialize PWM ----------------------------------
    T2CON  = 0b00000100;         // Timer 2 PS1/1設定
    PR2    = 0xFF;               // Timer2 Period Register設定
    PWM5CON= 0b11000000;         // 正論理出力
    PWM5DCH= 0x80;               // デュティサイクルを設定
    while(1){                    // 繰り返しループ
        if(!PushSW){             // PushSWが押されれば
            PWM5DCH += 1;        // デュティサイクルを+1し更新
            __delay_ms(5);       // 遅延(更新の速度)
        }
    }
}
			
PPS機能で、出力ピンをどのpinにするか指定します。
PWM5をRA5に指定するなら、
RA5PPS = 2;
↑PWM5 を示す
PWM 信号を出力するピンは、TRIS ビットを"0"出力に設定する必要があります。