山本ワールド
PIC18F46K22 PWM(Timer2+CCP3)によるLEDの明るさ変更(アセンブラ)
概要
PIC18F46K22 のtimer2とCCP3を使用してPWMをRB5端子に出力します。
デューティ比を約0~100%を約6.4秒で変化させます。
RC1端子にLEDが接続されていますので消灯から最大明るさまで変化させることができます。
回路図を以下に示します。LEDが5個接続されていますが本プログラムに必要なLEDはRB5に接続されているLEDのみです。
回路図(PDF)
PWMの動作について
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で設定することになります。
FOSC/4=16MHz,プリスケーラー1:4,PRx=0xff,CCPRxL=25 CCPxCON<5:4>=2 時の実測波形を以下に示します。
周期が15.62kHz、hiの幅が6.32μ秒です。
計算上の値は以下の通りです。概ね実測値と一致しています。
FOSC/4/4/256=15.625kHz
CCPRxH=25*4+2=102
102/(FOSC/4)=6.375μ秒
プログラムの説明
Timer2をソースとしてCCP3をシングルPWMで初期化します。
パルスステアリングモードによりPWMの出力をCCP3→P3A(RB5)に割り当てます。(PSTR3CONレジスタ)
メモリ上の16bitカウンタcount16をクリアします。
PWMのパルス幅を設定するためにcount16の値を引数としてサブルーチンSetDCPWMxを呼び出します。
ソフトウェアディレイにより6.25m秒待機します。
count16に1を加算し、上記のPWMのパルス幅設定の処理へジャンプします。
メインプログラムでタイマー設定を行い、無限ループとする。
カウンタ値は下位10bitが有効となります。
6.25m秒×1024=6.4秒がLEDの明るさの変化の1周期となります。
arg16の下位2bitの値をCCPxCONの5~4bitにコピーします。
arg16の9~2bitの値をCCPRxLにコピーします。
パルスステアリングモードによりPWMの出力をCCP3→P3A(RB5)に割り当てます。(PSTR3CONレジスタ)
プリスケーラー 1:4 PWM周波数 FOSC/4/4/256=15.625kHzRC1をIOポートに設定し出力にします。
メモリ上の16bitカウンタcount16をクリアします。
PWMのパルス幅を設定するためにcount16の値を引数としてサブルーチンSetDCPWMxを呼び出します。
ソフトウェアディレイにより6.25m秒待機します。
count16に1を加算し、上記のPWMのパルス幅設定の処理へジャンプします。
メインプログラムでタイマー設定を行い、無限ループとする。
カウンタ値は下位10bitが有効となります。
6.25m秒×1024=6.4秒がLEDの明るさの変化の1周期となります。
SetDCPWMx
16bitの変数arg16に設定された値でパルス幅を設定します。arg16の下位2bitの値をCCPxCONの5~4bitにコピーします。
arg16の9~2bitの値をCCPRxLにコピーします。
ソースファイル
以下のファイルで構成されているpwm6a.asm ・・・ プログラム
ソースファイルのダウンロード pwm6a.zip
; timer2+CCP3(PWM P3A(RB5)よる明るさ連続変更サンプル
; 慈渓博瑞テクノロジー株式会社 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 ; 変数の定義 アクセスバンク
Tcount2 RES 1
Tcount3 RES 1
Tcount4 RES 2 ; 6.25ms
arg16 RES 2
count16 RES 2
CODE
org 0
goto start
start
BANKSEL CCPTMRS0
clrf CCPTMRS0,BANKED ; Timer2をソースとする
movlw 0ffh
movwf PR2
movlw b'00001100' ; PWM
movwf CCP3CON,BANKED
movlw b'00000101' ; PS 1:4 Timer2 On
movwf T2CON
movlw b'00000001' ; CCP3->P3A(RB5)
movwf PSTR3CON,BANKED
movlw b'00011111' ; RB5をIO
movwf ANSELB,BANKED ; bank 0Fh
movlw b'00011111' ; RB5をOut
movwf TRISB
clrf count16
clrf count16+1
loop
movff count16,arg16
movff count16+1,arg16+1
call SetDCPWM3
LOOP_MAX EQU d'1'
; wait 6.25ms*513=3.21s
movlw LOW LOOP_MAX
movwf Tcount4
movlw HIGH LOOP_MAX
movwf Tcount4+1
loop_start
call wait6_25ms
clrf WREG
decf Tcount4
subwfb Tcount4+1
bc loop_start
incf count16
clrf WREG
addwfc count16+1
goto loop
; 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
; wait 6.25ms
wait6_25ms
movlw d'130' ; 48μs*130=6.25ms
movwf Tcount2
dloop2 ; t=(12+12*count3)/64MHz 48μs
movlw d'0'
movwf Tcount3
nop
dloop3
decfsz Tcount3
goto dloop3
decfsz Tcount2
goto dloop2
return
END
Copyright (C) 2012 山本ワールド All Rights Reserved.