PIC18F46K22 PWM half bridge(Timer2+CCP3)サンプル(アセンブラ)

icon 項目のみ表示/展開表示の切り替え

概要

PIC18F46K22 のtimer2とCCP3を使用してPWMをRB5,RE1端子に出力します。出力はHalf-Bridgeです。
デューティ比を約20%に固定です。
回路図を以下に示します。LEDが5個接続されていますが本プログラムに必要なLEDはRB5,RE1に接続されているLEDのみです。
../pwm3a/pwm3a.svg
回路図(PDF)

PWMの動作について

../pwm3a/ccpx.svg ../pwm3a/ccpxtime.svg
TMRx(上位8bit)は8bitのカウントでFOSC/4をプリスケーラー(1:1,1:4,1:16)で分周したクロックで増加方向にカウントします。
PRxとTMRx(上位8bit)の値が一致した場合、TMRxカウンターを0クリアします。またCCPRxL,CCPxCONレジスタをCCPRxHレジスタに転送します。SがセットされるのでQはHiになります。
TMRx(上位8bit+下位2bit)とCCPRxHレジスタと一致したとき出力がRがセットされ、QはLowになります。
TMRx(下位2bit)はTMRx(上位8bit)に入力されたクロックの4倍の周波数でカウントされる2bitのカウンターです。
PRxを0xffに設定した場合、PWMのHiの幅は10bit(1024)の分解能が得られることになります。
PWMの周期がPRxレジスタ、パルス幅はCCPRxL,CCPxCONで設定することになります。
実測波形を以下に示します。
 
CH1が黄色でRB5端子、CH2が紫色でRE1端子です。
周期が62.50kHz、hiの幅が3.2μ秒です。
計算上の値は以下の通りです。概ね実測値と一致しています。
FOSC/4/256=62.5kHz
CCPRxH=208
208/FOSC=3.25μ秒

プログラムの説明

Timer2をソースとしてCCP3をHalf-Bridgeモードで初期化します。
デットタイムはPWM3CONレジスタで設定します。ここでは0にしています。PWM3CONレジスタの下位7bitがデットタイムの値であり、単位はCPUの命令サイクル数(FOSC/4)となります。
プリスケーラー 1:1
PWM周波数 FOSC/4/256=62.5kHz
Half-Bridgeモードでは出力端子はパルスステアリングモードの設定ができませんのでP3A,P3Bに固定されます。
RB5,RE1をIOポートに設定し出力にします。
PWMのパルス幅を設定するためにサブルーチンSetDCPWMxを呼び出します。
無限ループで待機します。

SetDCPWMx

16bitの変数arg16に設定された値でパルス幅を設定します。
arg16の下位2bitの値をCCPxCONの5~4bitにコピーします。
arg16の9~2bitの値をCCPRxLにコピーします。

ソースファイル

以下のファイルで構成されている
pwm_half1a.asm ・・・ プログラム

ソースファイルのダウンロード pwm_half1a.zip

; timer2+CCP3(PWM half bridge P3A(RB5) P3B(RE1)よるデューティ比 20% 15.6kHz 2017/01/04
; 慈渓博瑞テクノロジー株式会社 PIC18F46K22 マイコンキット Ver2013.12.08用
;   http://akizukidenshi.com/catalog/g/gK-07231/
;   水晶は16MHzに交換してPICを64MHzで駆動
; MPLAB X IDE v3.45 Microchip MPASM(v5.70)
; PicKit 3

        #INCLUDE <p18f46k22.inc>
        ; 水晶発振(16MHz) クロック分周無 PLL有効(*4) プライマリクロック有効  ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
        CONFIG FOSC = HSHP,PLLCFG=ON,PRICLKEN=ON,WDTEN=OFF,LVP=OFF

bank0   UDATA_ACS   ; 変数の定義 アクセスバンク
arg16   RES     2

        CODE
        org     0
        goto    start

start
        BANKSEL CCPTMRS0
        clrf    CCPTMRS0,BANKED  ;   Timer2をソースとする
        movlw   0ffh
        movwf   PR2
        movlw   b'10001100'      ;   PWM Half-Bridge
        movwf   CCP3CON,BANKED
        ;       movlw   b'00000110'      ;   PS 1:4 Timer2 On 16MHz/16/256/4=3.90625kHz
        ;       movlw   b'00000101'      ;   PS 1:4 Timer2 On 16MHz/4/256/4=15.6kHz
        movlw   b'00000100'      ;   PS 1:1 Timer2 On 16MHz/256/4=62.5kHz
        movwf   T2CON

        movlw   b'00000000' ;   デットタイム
        movwf   PWM3CON,BANKED

        movlw   b'00011111'     ;   RB5をIO
        movwf   ANSELB,BANKED   ;   bank 0Fh
        movlw   b'00011111'     ;   RB5をOut
        movwf   TRISB

        movlw   b'00000101'     ;   RE1をIO
        movwf   ANSELE,BANKED   ;   bank 0Fh
        movlw   b'00000101'     ;   RE1をOut
        movwf   TRISE
        
CCP3_VALUE  EQU d'208'
        
        movlw   LOW CCP3_VALUE
        movwf   arg16
        movlw   HIGH CCP3_VALUE
        movwf   arg16+1
        call    SetDCPWM3
        bra     $

;        PWM設定 arg16:パルス幅
SetDCPWM3
        movlw   b'11001111'
        andwf   CCP3CON,BANKED 
        movf    arg16,W
        andlw   b'00000011'
        swapf   WREG
        iorwf   CCP3CON,BANKED 
        bcf     STATUS,C
        rrcf    arg16+1
        rrcf    arg16
        bcf     STATUS,C
        rrcf    arg16+1
        rrcf    arg16
        movf    arg16,W
        movwf   CCPR3L,BANKED 
        return

        END