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

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

ECCP (Enhanced Capture/Compare/PWM)のPWM(Pulse Width Modulation) モードは、分解能10ビットのPWM 信号をタイマー2と連携して発生させることができます。PWM 出力モードには、以下の4 種類がありますが、ここでは、 シングルPWMの説明です。

シングル出力モードを選択 (CCP1CON レジスタの CCP1M<3:2> = 11 および P1M<1:0> = 00) した上で、 PSTRCON レジスタの該当する STR<D:A> ビットを設 定する事で、同じ PWM 信号 を1~4本の出力ピンに出力できます。

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

PWM名称 TRIS PinNo
CCP1/P1A RC5 5
P1B RC4 6
P1C RC3 7
P1D RC2 14
レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
RCON IPEN SBOREN RI TO PD POR BOR
INTCON GIE/GIEH PEIE/GIEL TMR0IE INTIE RABIE TMR0IF INT0IF RABIF
PIR1 - ADIF RCIF TXIF SSP1IF CCP1IF TMR2IF TMR1IF
PIE1 - ADIE RCIE TXIE SSP1IE CCP1IE TMR2IE TMR1IE
IPR1 ADIP RCIP TXIP SSPIP CCP1IP TMR2IP TMR1IP
CCP1CON P1M < 1 - 0 > DC1B < 1 - 0 > CCP1M < 3 - 0 >
PSTRCON STRSYNC STRD STRC STRB STRA
TRISC TRISC7 TRISC6 TRISC5 TRISC4 TRISC3 TRISC2 TRISC1 TRISC
CCPR1L CCP Register 1, Low Byte
CCPR1H CCP Register 1, High Byte
レジスタ BIT 説明 1 0
RCON 7 IPEN 2レベルのインタラプト優先度 使用
INTCON 7 GIEH 高優先度インタラプトを使用許可 許可
6 GIEL 低優先度インタラプトを使用許可 許可
PIR1 1 CCP1IF CCP1 発生フラグ 発生  
PIE1 1 CCP1IE CCP1 インタラプトを使用許可 許可
IPR1 1 CCP1IP CCP1 インタラプト優先度
CCP1CON 7 P1M1 00 = シングル出力(規定値)、01 = フルブリッジ順方向出
10 = ハーフブリッジ出力、  11 = フルブリッジ逆方向出
6 P1M0
5 DC1B1 PWM デューティ サイクル値の下位 ビット    
4 DC1B0 PWM デューティ サイクル値の最下位 ビット    
3 CCP1M3 0000 =CCPモジュール全体をOFF(規定値)
1100 = P1A-P1Cを正論理  1101 = P1A,P1Cを正論理、P1B,P1Dを負論理
1111 = P1A-P1Cを負論理  1110 = P1A,P1Cを負論理、P1B,P1Dを正論理
2 CCP1M2
1 CCP1M1
0 CCP1M0
PSTRCON 4 STRSYNC 出力をPWM周期に同期 する しない
3 STRD P1D PinにPWM波形を出力 する しない
2 STRC P1C PinにPWM波形を出力 する しない
1 STRB P1B PinにPWM波形を出力 する しない
0 STRA P1A PinにPWM波形を出力 する しない
プリスケラ値 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のプログラム例

タイマー2とCCPでPWM波形を発生させるプログラムを作成しました。繰り返し周波数は、976Hzで固定ですが、デューティーサイクルをVRで可変できます。

<プログラム>

//---------------------------------------------------------
//  CCP PWM機能の確認
//  VRの値で出力するデューティサイクルが変化する
//      CCP  →  PWM機能で signalOut のDutyを変化させる
//      VR   →  VRの値をAD変換しDuty値とする
//  Notes:  4MhzM内部クロック
//          AN11(RB5)  VR入力
//          RC5        signalOut
//  Language: MPLABX XC8   Target: PIC18F14K50
//--------------------------------------------------------

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

#define  signalOut   LATCbits.LATC5

//-------------- コンフィグレーション ----------------------
#pragma config FOSC = IRC        //  内部クロック
#pragma config USBDIV = OFF, CPUDIV = NOCLKDIV
#pragma config IESO  = OFF, FCMEN = OFF, PLLEN  = ON
#pragma config BORV  = 30,  BOREN = OFF, PWRTEN = OFF
#pragma config WDTPS = 32768, WDTEN = OFF
#pragma config MCLRE = OFF, HFOFST = OFF, XINST  = OFF
#pragma config BBSIZ = OFF, LVP    = OFF, STVREN = ON
#pragma config CP1  = OFF, CP0  = OFF, CPD  = OFF, CPB  = OFF
#pragma config WRT1 = OFF, WRT0 = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR1 = OFF, EBTR0 = OFF, EBTRB  = OFF

//------------------メインプログラム------------------------------
void main(void){
    OSCCON = 0b01010010;        // 内部クロック4Mhz
    TRISC  = 0b11011111;        // PortC  RC5出力
// ---------------- ADCの 設定 -----------------------------------
    ADCON2 = 0b00101100;        // 左詰め出力,AD変換クロックFosc/4
                                // チャージ時間 12_TAD
    ADCON1 = 0b00000000;        // 正基準電圧 VDD, 負基準電圧 VSS
    ADCON0 = 0b00101101;        // アナログ入力 AN11(RB5),ADC ON

    ANSELHbits.ANS11 = 1;       // AN11はアナログ入力に設定
// --------------- CCPの 設定 ------------------------------------
// システムクロック(4Mhe/4)をカウントする
// Prescalerでさらに1/4にした250KHzをカウントする

    CCP1CON = 0b00001100;      // PWM P1A-P1Cを正論理で出力
    CCPR1L  = 0b01111111;      // PWM Dutyの仮設定1
    PSTRCON = 0b00000001;      // P1Aを出力
    T2CON   = 0b00000101;      // Prescalerでさらに1/4

    while(1){
        ADCON0bits.GO = 1;     // AD変換開始
        while(ADCON0bits.GO);  // AD変換終了待ち
        CCPR1L = ADRESH;       // AD変換結果をCCP繰返周期に
        __delay_ms(100);       // LEDちらつき防止の遅延
    }
}