MPLAB IDE v8.92 MPASM v5.51 PICKit3の環境で、PIC16F648AのPWM(Pulse Width Modulation)の使い方を勉強します。
このPICでPWMを出力するには、CCP1モジュールを使います。PWMのブロックダイアグラムです。(PIC16F648Aの取説より)
PWM信号発生の原理は、私のホームページ(JH7UBCホームページ)のこちらのページで説明していますので、参照してください。
PWM信号は下の図のようにPWM PeriodとDuty Cycleで決まり、それぞれ下の式のように、PR2,Tosc,TMR2 prescale value,CCP1RL,CCP1CON<5:4>で計算できます。
例として、1000Hz,デューティ比50%のPWM信号を発生させてみます。
クロックは、内蔵クロック4MHz(4000000Hz)とし、TMR2 prescale valueは4(1:4)とします。
以上の値でPR2の値を計算すると
PR2 =( 4000000 / 1000 ・4・4) - 1 = 249
デューティ比50%なので、CCPRL1=(RP2+1)・0.5=125 となります。
これらの値でプログラミングするわけですが、それぞれのレジスタ(SFR)に値をセットするときに注意しなければならないのがBANK切り替えです。
PIC16F648AのBANKマップは次のようになっていますので注意します。
プログラムです。
------------------------------------------
LIST P=PIC16F648A
INCLUDE P16F648A.INC
__CONFIG _INTOSC_OSC_NOCLKOUT & _CP_OFF & _CPD_OFF & _WDTE_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _MCLRE_OFF
;入出力設定
BSF STATUS,RP0 ;BANK1
CLRF TRISA ;PORTAはすべて出力、ただし、RA5は入力
CLRF TRISB ;PORTBはすべて出力
BCF STATUS,RP0 ;BANK0
MOVLW b'00000111'
MOVWF CMCON ;コンパレータOFF
;PWM設定
MOVLW b'00001100'
MOVWF CCP1CON ;PWMモード
MOVLW b'00000101'
MOVWF T2CON ;TMR2 ON,プリスケーラ1:4
BSF STATUS,RP0 ;BANK1
MOVLW 0F9h ;249
MOVWF PR2
;カウンタ、レジスタ初期値
BCF STATUS,RP0 ;BANK0
CLRF CCPR1L
CLRF CCPR1H
CLRF TMR2
;デューティサイクルセット
MOVLW 07Dh ;デューティ比50% 250/2=125=07Dh
MOVWF CCPR1L
LOOP
GOTO LOOP
END
------------------------------------------
テストした回路図です。
アセンブルしてPICにプログラムを書き込むと、PWM信号は、RB3から出力されます。
出力されたPWM信号をPicoScopeで見てみました。約1000Hz(周期約1ms)でデューティ比50%の信号が確かに出力されました。
周波数を測定してみました。1028Hzで若干高めの周波数が出力されました。内部クロックの誤差と思われます。
CCPR1Lの値をPR2の1/4(25%)にした時のPWM波形です。
デューティ比25%のPWM信号が出力されました。
次に、500Hz、デューティ比50%の信号を発生させてみましょう。
TMR2のプリスケーラ値が4のままですと、PR2の値が255を超えてしまいますので、プリスケーラ値を16とします。プリスケーラ値を決めるのは、T2CONレジスタのbit1とbit0で、これを11とします。つまり
MOVWL b'00000111'
MOVWF T2CON
とします。PR2とCCP1RLの値は
PR2 =( 4000000 / 500 ・4・16) - 1 = 124
CCP1RL = (PR2+1)・0.5 = 62 となります。
512HzのPWMが出力されました。