山本ワールド
PIC18F46K22 PWM(Timer2+CCP2)によるLEDの明るさ変更(アセンブラ)
概要
PIC18F46K22 のtimer2とCCP2を使用してPWMをRC1端子に出力します。
デューティ比を約0~100%を約6.4秒で変化させます。
RC1端子にLEDが接続されていますので消灯から最大明るさまで変化させることができます。
回路図を以下に示します。LEDが5個接続されていますが本プログラムに必要なLEDはRC1に接続されている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をソースとしてCCP2を初期化します。
RC1をIOポートに設定し出力にします。
メモリ上の16bitカウンタcount16をクリアします。
PWMのパルス幅を設定するためにcount16の値を引数としてサブルーチンSetDCPWM2を呼び出します。
ソフトウェアディレイにより6.25m秒待機します。
count16に1を加算し、上記のPWMのパルス幅設定の処理へジャンプします。
メインプログラムでタイマー設定を行い、無限ループとする。
カウンタ値は下位10bitが有効となります。
6.25m秒×1024=6.4秒がLEDの明るさの変化の1周期となります。
arg16の下位2bitの値をCCP2CONの5~4bitにコピーします。
arg16の9~2bitの値をCCPR2Lにコピーします。
プリスケーラー 1:4 PWM周波数 FOSC/4/4/256=15.625kHzパルスステアリングモードによりPWMの出力をP2A(RC1)に割り当てます。(PSTR2CONレジスタ)
RC1をIOポートに設定し出力にします。
メモリ上の16bitカウンタcount16をクリアします。
PWMのパルス幅を設定するためにcount16の値を引数としてサブルーチンSetDCPWM2を呼び出します。
ソフトウェアディレイにより6.25m秒待機します。
count16に1を加算し、上記のPWMのパルス幅設定の処理へジャンプします。
メインプログラムでタイマー設定を行い、無限ループとする。
カウンタ値は下位10bitが有効となります。
6.25m秒×1024=6.4秒がLEDの明るさの変化の1周期となります。
SetDCPWM2
16bitの変数arg16に設定された値でパルス幅を設定します。arg16の下位2bitの値をCCP2CONの5~4bitにコピーします。
arg16の9~2bitの値をCCPR2Lにコピーします。
ソースファイル
以下のファイルで構成されているpwm3a.asm ・・・ プログラム
ソースファイルのダウンロード pwm3a.zip
; timer2+CCP2(PWM P2A(RC1)出力)よるLEDの明るさ変更サンプル
; 慈渓博瑞テクノロジー株式会社 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 ; 変数の定義 バンク0
Tcount2 RES 1
Tcount3 RES 1
arg16 RES 2
count16 RES 2
CODE
org 0
goto start
start
movlb 0fh
clrf CCPTMRS0,BANKED ; Timer2をソースとする
movlw 0ffh
movwf PR2
movlw b'00001100' ; PWM
movwf CCP2CON
movlw b'00000101' ; PS 1:4 Timer2 On
movwf T2CON
movlw b'00000001' ; CCP2->P2A(RC1)
movwf PSTR2CON,BANKED
movlw b'11111101' ; RC1をIO
movwf ANSELC,BANKED
movlw b'11111101' ; RC1をOUT
movwf TRISC
clrf count16
clrf count16+1
loop
movff count16,arg16
movff count16+1,arg16+1
call SetDCPWM2
call wait6_25ms
incf count16
clrf WREG
addwfc count16+1
goto loop
; PWM設定 arg16:パルス幅
SetDCPWM2
movlw b'11001111'
andwf CCP2CON
movf arg16,W
andlw b'00000011'
swapf WREG
iorwf CCP2CON
bcf STATUS,C
rrcf arg16+1
rrcf arg16
bcf STATUS,C
rrcf arg16+1
rrcf arg16
movf arg16,W
movwf CCPR2L
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.