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

ホーム
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%の波形が出力されます。

APFCON PWM1 PWM2
P2SEL = 0 RC5 RC3
P2SEL = 1 RC5 RA5

APFCON の P2SEL ビットで、PWM2出力ピンをRC3からRA5に変更することができます。

PWM 信号を出力するピンは、TRIS ビットを"0"出力に設定する必要があります。

レジスタ 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 - -
TRISA - - TRISA5 TRISA4 - - - -
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
APFCON 2 P2SEL PWM2 出力ピン RA5 RC3
プリスケラ値 1/16 1/4 1/1
PR2 セット値 0xFF 0xF9 0xFF 0xF9 0xFF 0xF9
Fosc 4MHz 244Hz 250Hz 976Hz 1KHz 3.91KHz 4KHz
16MHz 976Hz 1KHz 3.91KHz 4KHz 15.6KHz 16KHz
48MHz 2.93KHz 3KHz 11.7KHz 12KHz 46.9KHz 48KHz

FoscとPWM周波数の関連

PWMのプログラム例

PushSWを押続けている間、PWMのデューティサイクルを連続的に変化させるプログラムです。 デューティサイクルの変化をLEDの明るさで確認することができます。
<回路図>

<プログラム>

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

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

#define LED    LATC2
#define PushSW RA5

#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 = 0b00110100;         // 内部クロック4Mhz
    WPUA5  = 1;                  // RA5を弱プルアップ
    nWPUEN = 0;
    TRISC  = 0b11110111;         // 入出力設定
    T2CON  = 0b00000100;         // Timer 2 PS1/1設定
    PR2    = 0xFF;               // Timer2 Period Register設定
    PWM2CON= 0b11000000;         // 正論理出力
    PWM2DCH= duty;               // デュティサイクルを設定
    while(1){                    // 繰り返しループ
        if(!RA5){                // PushSWが押されれば
            PWM2DCH = duty++;    // デュティサイクルを+1し更新
            __delay_ms(10);      // 10mS遅延(更新の速度)
        }
    }
}