16F18346には、分解能10ビットのPWM専用モジュールが2組 PWM5,PWM6 あり、タイマー2、4または6と連携してPWM信号を発生させることができます。4本あるCCPモジュールにも、同機能のPWMモジュールがあるため合計6組のPWMモジュールがあります。
PWMモジュールがどのタイマーと連携するかは、PWMTMRSで変更することができますが、ここではタイマー2との連携例で動作を説明します。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> | - | - | - | - | - | - | |
PWMTMRS | - | - | - | - | P6TSEL<1:0> | P5TSEL<1:0> | ||
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 | ||
PWMTMRS | 3 | P6TSEL1 | PWM6 連携タイマー 01:TMR2 10:TMR4 11:TMR6 |
||
2 | P6TSEL0 | ||||
1 | P5TSEL1 | PWM5 連携タイマー 01:TMR2 10:TMR4 11:TMR6 |
|||
0 | P5TSEL0 |
プリスケラ値 | 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 S1 を押続けている間、PWMのデューティサイクルを連続的に変化させるプログラムです。 デューティサイクルの変化をLED D7 の明るさで確認することができます。
<プログラム>
/************************************* * File: PWM sample * System ClockはConfigで内部1MHzに設定 * PushSWを押続けている間、PWMのデューティサイクルを連続的に+1し、 * LEDの明るさを連続的に変化させる。 * LED RC5 * PushSW RC4 * * Language: MPLABX XC8 v2.10 * PIC16F18346 on Curiosity * Created on Sep 2, 2020, 2:37 PM **************************************/ #include <xc.h> #define _XTAL_FREQ 1000000 // delay_ms(x) のための定義 #define LED LATC5 #define PushSW RC4 #pragma config FEXTOSC = OFF,RSTOSC = HFINT1 // HFINTOSC (1MHz) #pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF #pragma config MCLRE = ON,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 = ON,CP = OFF,CPD = OFF // ******************* main ************************************* void main() { TRISC4 = 1; // RC4 入力 TRISC5 = 0; // RC5 出力 ANSELC = 0; // すべてデジタル RC5PPS = 2; //------------ 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機能で、6出力ピンをどのpinにするか指定します。
PWM5をRC3に指定するなら、
RC3PPS = 2;
↑PWM5 を示す
PWM 信号を出力するピンは、TRIS ビットを"0"出力に設定する必要があります。