MPLAB IDE v9.82, MPASM v5.51, PICKit3の環境で、PIC16F1827のPWMのテストをします。
PIC16F1827でPWM信号を発生するのは、CCP(Capture/Compare/PWM)モジュールです。この品種では、ECCP1,ECCP2,CCP3,CCP4が利用できます。なお、EがつくCCPモジュールは機能が拡張されています。
今回は、CCP3を使い、タイマーはTMR2を使ってテストします。回路図です。ICSPでプログラミングし、電源5VはPICKit3から供給します。PWM信号はRA3(PWM3)から出力します。
PIC16F1827でのPWM発生のしくみは、私のホームページ(JH7UBCホームページ)のこちらのページで詳しく解説しています。
今回テストとして、PWM3で周波数500HzのPWMを発生し、DutyCycleを変化させ、RA3に接続したLEDの明るさを周期的に変化させてみます。
CCP3でPWMに設定するには、CCP3CONレジスタのbit3:bit2(CCP3M3:CCPM2)を11の設定します。他のbitは0でOKです。説明書では、下のようにCCPXCONとなっています。Xはモジュールの番号1,2,3,4です。
つまり、CCP3CON=b'00001100'とします。
次に、CCPTMRSレジスタで、CCP3でTMR2を使うという設定をします。
bit5:bit4(C3TSEL1:C3TSEL0)を00とします。他のbitは適当でよいの、すべて0にします。
つまり、CCPTMRS=b'00000000'とします。
PWMの周波数(周期)とDuty比(DutyCycle)を設定するのはPR2レジスタの値とCCPR3L+CCP3CON<5:4>で、次のような式で計算されます。
今回、PICのクロックは内蔵の4MHzとしますので、Tosc=1/4000000 (sec)で、TMR2のPrescaler値を16とすると500Hz(周期は1/500 (sec))を発生させるPR2の値は、
PR2=(Period/(4*Tosc*TMR2Prescale Value))-1=(1/500/(4*(1/4000000))*16)-1
=4000000/(500*4*16) -1 =125-1=124
となります。
Duty比は、一番下の式できまりますので、PR2=124のときは、CCPR3Lの値を0から125まで設定すれば0から100%のDuty比のPWM信号を発生することができます。
プログラムです。DUTYの値をカウントアップするか、カウントダウンするかは、FLAGの値で決めます。10msごとにDUTYをカウントアップカウントダウンして、LEDの明るさを決めています。
-------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC16F1827 PWM TEST
; 2024.12.3
; JH7UBC Keiji Hata
;;;;;;;;;;;;;;;;;;;;;;;;;;
LIST P=PIC16F1827
INCLUDE P16F1827.INC
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
ERRORLEVEL -302
CBLOCK 020h
CNT1ms
CNT10ms
DUTY
FLAG
ENDC
SETUP
;クロック設定
BANKSEL OSCCON
MOVLW b'01101000' ;PLLなし、4MHz,Fosc
MOVWF OSCCON
;入出力設定
BANKSEL ANSELA
CLRF ANSELA ;AN0-AN4使用しない
CLRF ANSELB ;AN5-AN11使用しない
BANKSEL TRISA
CLRF TRISA ;PORTAは全て出力(RA5は入力)
CLRF TRISB ;PORTBは全て出力
;PWM設定
BANKSEL CCP3CON
MOVLW b'00001100' ;PWM mode
MOVWF CCP3CON
BANKSEL CCPTMRS
MOVLW b'00000000' ;bit5-bit4=00,CCP3にTimer2を割り当てる
MOVWF CCPTMRS
BANKSEL PR2
MOVLW 07Ch ;07Ch=124
MOVWF PR2 ;Timer2の周期を設定
BANKSEL T2CON
MOVLW b'00000110'
MOVWF T2CON ;prescale 1:16 Timer2 start
;変数初期値
BANKSEL DUTY
CLRF DUTY
MOVLW 01h
MOVWF FLAG
MAIN
BANKSEL DUTY
MOVFW FLAG
XORLW 01h
BTFSS STATUS,Z ;FLAG=1ならINCDUTYへ、FLAG=0ならDECDUTYへ
GOTO DECDUTY
INCDUTY
MOVFW DUTY
SUBLW 07Ch ;W=124-W
BTFSC STATUS,Z ;DUTY><124ならスキップ
GOTO FLAGCHG ;DUTY=124ならFLAGCHGへ
INCF DUTY ;DUTY=DUTY+1
GOTO SETDUTY
DECDUTY
DECFSZ DUTY ;DUTY=DUTY-1 DUTY=0になったらスキップ
GOTO SETDUTY
FLAGCHG
MOVFW FLAG
SUBLW 01h
MOVWF FLAG ;FLAG=1-FLAG
GOTO SETDUTY
SETDUTY
BANKSEL DUTY
MOVFW DUTY
BANKSEL CCPR3L
MOVWF CCPR3L
CALL LOOP10ms
GOTO MAIN
LOOP10ms
BANKSEL CNT10ms
MOVLW 0Ah ;0Ah=10
MOVWF CNT10ms
LOOP2
CALL LOOP1ms
DECFSZ CNT10ms
GOTO LOOP2
RETURN
LOOP1ms
MOVLW 0F9h ;0F9h=249
MOVWF CNT1ms
LOOP1
NOP
DECFSZ CNT1ms,F
GOTO LOOP1
RETURN
END
-------------------------------------------------
RA3から出力されたPWMの波形です。周期は約2ms(周波数は約500Hz)で、ヂューティ比が時間とともに変化します。
ブレッドボードです。赤いLEDが明るくなったり暗くなったりします。左下の緑色のLEDは電源確認用です。
※コメント投稿者のブログIDはブログ作成者のみに通知されます