PIC16F1459の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
PWM (Pulse Width Modulation)

16F145xには、分解能10ビットのPWMモジュールが2組あり、タイマー2と連携してPWM信号を発生させることができます。 PWMの繰り返し周期は、タイマー2のPR2の設定値で決定し、デューティーサイクルは PWMxDCH と PWMxDCL に分けて保存されています。タイマー(TMR2)とPR2の値が一致するとTMR2をリセットします。同時に、PWM出力を”1”にセットし、PWMxDCH と PWMxDCLの値を、コンパレータ内部レジスタにコピーします。この値が、TMR2の値と一致するとPWM出力を”0”にリセットします。つまり、PR2の設定値の半分の値をPWMxDCHにセットすればデューティー50%の波形が出力されます。

*注意*
PWM 信号を出力するピンは、TRIS ビットを"0"出力に設定する必要があります。
 PWM1 Out: RC5
 PWM2 Out: RC6

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
PWM1CON PWM1EN PWM1OE PWM1OUT PWM1POL - - - -
PWM1DCH PWM1DCH<7:0>
PWM1DCL PWM1DCL<7:6> - - - - - -
PWM2CON PWM2EN PWM2OE PWM2OUT PWM2POL - - - -
PWM2DCH PWM2DCH<7:0>
PWM2DCL PWM2DCL<7:6> - - - - - -
APFCON CLKRSEL SDOSEL SSSEL - T1GSEL P2SEL - -
TRISC TRISC7 TRISC6 TRISC5 TRISC4 TRISC3 TRISC2 TRISC1 TRISC
レジスタ BIT 説明 1 0
PWMxCON 7 PWMxEN PWMx モジュール ON/OFF ON OFF
6 PWMxOE 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 4MHz 61Hz 62.5Hz 244Hz 250Hz 976Hz 1KHz 3.91KHz 4KHz
16MHz 244Hz 250Hz 976Hz 1KHz 3.91KHz 4KHz 15.6KHz 16KHz
48MHz 733Hz 750Hz 2.93KHz 3KHz 11.7KHz 12KHz 46.9KHz 48KHz

FoscとPWM周波数の関連

PWMのプログラム例

PushSWを押続けている間、PWMのデューティサイクルを連続的に変化させるプログラムです。 PWM2(RC6)にLEDを接続すれば、デューティサイクルの変化をLEDの明るさで確認することができます。

<プログラム>

//  File name:  PWM
//  Description: PWM example
//  PushSWを押続けている間、PWMのデューティサイクルを連続的に+1し、
//  PWM2(RC6)に接続したLEDの明るさを連続的に変化させる。
//  PushSW(RA3)は、Week Pull Upされている。、
//  Notes: 4MHz内部クロック
//        LED PWM2(RC6)
//        PushSW RA3
//    Language: MPLABX XC8
//    Target:   PIC16F1459
// -------------------------------------------------------------------------

#include <xc.h>
#define _XTAL_FREQ 4000000      // delay_ms(x) のための定義
#define PushSW RA3

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 3x
#pragma config PLLEN = DISABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

void main(void){
    unsigned char duty = 0x80;
    OSCCON = 0b00110110;         // 内部クロック4Mhz
    WPUA3  = 1;                  // RA3を弱プルアップ
    nWPUEN = 0;
    TRISC  = 0b10111111;         // 入出力設定
    T2CON  = 0b00000100;         // Timer 2 PS1/1設定
    PR2    = 0xFF;               // Timer2 Period Register設定
    PWM2CON= 0b11000000;         // 正論理出力
    PWM2DCH= duty;               // デュティサイクルを設定
    while(1){                    // 繰り返しループ
        if(!RA3){                // PushSWが押されれば
            PWM2DCH = duty++;    // デュティサイクルを+1し更新
            __delay_ms(10);      // 10mS遅延(更新の速度)
        }
    }
}