目次>5章 第2ステップ(色々な実験)>フルカラーLEDを使う(イルミネーション)>ソース
− イルミネーション −
更新日2006.11.25
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ==============================
;
; clock:20MHz
;
; フルカラーLEDの実験(色々な色を表現)
;
; RB0-2:3色LED RB0 RED ,RB1 GREEN ,RB2 BLUE
;
; TMR0割込み
; TMR0 0(フリーラン)
; プリスケーラ 1
; TMR0割込み間隔 0.2uS×256×1=51.2uS
;
;
LIST P=PIC16F84A ; LIST宣言で使用するPICを16F84Aと定義する。
INCLUDE P16F84A.INC ; 設定ファイルp16f84a.incを読み込む。
__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
CBLOCK 0Ch
timer ; bit0:51.2uS
cycle ; PWM周期
wid_R ; PWM幅(赤)カウンタ
wid_B ; PWM幅(青)カウンタ
wid_G ; PWM幅(緑)カウンタ
wid_R_old ; PWM幅(赤)カウンタ(前回)
wid_G_old ; PWM幅(赤)カウンタ(前回)
wid_B_old ; PWM幅(赤)カウンタ(前回)
wid_R_i ; PWM幅(赤)カウンタ初期値
wid_B_i ; PWM幅(青)カウンタ初期値
wid_G_i ; PWM幅(緑)カウンタ初期値
wid_ch ; PWM幅変更間隔(nサイクル毎に幅を変える)
add_R ; PWM幅(赤)への加算値(±n)
add_B ; PWM幅(青)への加算値(±n)
add_G ; PWM幅(緑)への加算値(±n)
addflag ; 加算(1)か減算(0)か 2:R ,1:G ,0:B
ENDC
f51uS EQU 0 ; 51.2uSフラグ
cyclei EQU d'255' ; PWM周期
wid_chi EQU d'15' ; パルス幅変更間隔(サイクル数)
flag_R EQU 2 ; addflagのビット位置
flag_G EQU 1 ; addflagのビット位置
flag_B EQU 0 ; addflagのビット位置
ORG 0
GOTO init
; =================== TMR0割込み処理 =========================
ORG 4 ;割込みの入口
BCF INTCON,T0IF ;割込みフラグクリア
BSF timer,f51uS ;51.2uSフラグセット
RETFIE ;割込み許可リターン
; ===================== 初期処理 ==================================
init
BSF STATUS,RP0 ; ■バンク1
MOVLW 0F8h
MOVWF TRISB ; PORTB設定(RB0-2:出力,RB3-7:入力)
MOVLW 088h ; TMR0プリスケーラ:無し(0.2μS*1=0.2μS)
MOVWF OPTION_REG ;
BCF STATUS,RP0 ; ■バンク0
MOVLW 0A0h ; INTCONの設定
MOVWF INTCON ; GIE:1 ,T0IE:1 (TMR0割込み有効)
CLRF TMR0 ; TMR0をクリア
MOVLW 00h
MOVWF PORTB ; 赤・青・緑のLEDをON(白)
MOVLW cyclei
MOVWF cycle
MOVLW 01h
MOVWF wid_R_i ; パルス幅の初期値
MOVWF wid_B_i
MOVWF wid_G_i
MOVWF wid_R ; パルス幅の現在値
MOVWF wid_B
MOVWF wid_G
MOVLW 01h ; パルス幅加算値
MOVWF add_R
MOVLW 02h
MOVWF add_B
MOVLW 03h
MOVWF add_G
MOVLW wid_chi ; パルス幅変更間隔
MOVWF wid_ch
MOVLW 07h
MOVWF addflag ; 加減算フラグ(最初は全て加算)
; ===================== メイン処理 ================================
main
BTFSC timer,f51uS ;51.2uSフラグセット?
CALL rgb_pwm
GOTO main
; ===================== 3色LED設定処理(PWM) ===============
; 1サイクル終了までパルス幅を制御
rgb_pwm
BCF timer,f51uS ;51.2uSフラグクリア
DECFSZ cycle,F ;1サイクル終了?
GOTO rgb_pwm_R ;No
;Yes
CALL rgb_set
; 次のサイクル開始処理
MOVLW cyclei
MOVWF cycle ;1サイクルのカウンタ初期化
BCF PORTB,0 ;赤ON (PORTはOFF)
BCF PORTB,1 ;緑ON (PORTはOFF)
BCF PORTB,2 ;青ON (PORTはOFF)
GOTO rgb_pwm_E
; 各LEDのPWM幅が設定値になったらLEDをOFF(PORTはON)
rgb_pwm_R
DECFSZ wid_R,F
GOTO rgb_pwm_G
BSF PORTB,0 ;赤OFF
rgb_pwm_G
DECFSZ wid_G,F
GOTO rgb_pwm_B
BSF PORTB,1 ;緑OFF
rgb_pwm_B
DECFSZ wid_B,F
GOTO rgb_pwm_E
BSF PORTB,2 ;青OFF
rgb_pwm_E
RETURN
; ===================== パルス幅算出 ============================
; 1サイクル終了ごとにRGBのパルス幅を変更
rgb_set
DECFSZ wid_ch,F ; パルス幅変更?
GOTO rgb_set9 ; No
MOVLW wid_chi ; パルス幅変更間隔
MOVWF wid_ch ; 初期化
; 各色のPWM幅変更
CALL wid_set_R
CALL wid_set_G
CALL wid_set_B
rgb_set9
; PWM幅設定
MOVF wid_R_i,W
MOVWF wid_R
MOVF wid_G_i,W
MOVWF wid_G
MOVF wid_B_i,W
MOVWF wid_B
RETURN
; ===================== 赤のパルス幅算出 ============================
wid_set_R
MOVF wid_R_i,W
MOVWF wid_R_old ;前回のパルス幅を保存
BTFSS addflag,flag_R ;加減算は"+" ?
GOTO wid_set_R1 ; No
MOVF add_R,W
ADDWF wid_R_i,F
BTFSS STATUS,C ;最大値になった?
GOTO wid_set_R9 ;No
MOVF wid_R_old,W
MOVWF wid_R_i ;前回のパルス幅を復元
BCF addflag,flag_R ;加減算を"−"に変更
MOVF addflag,W
MOVWF add_R
INCF add_R,F
GOTO wid_set_R9
wid_set_R1
MOVF add_R,W
SUBWF wid_R_i,F
BTFSC STATUS,C ;最小値になった?
BTFSC STATUS,Z ;最小値になった?
GOTO wid_set_R2 ;Yes
GOTO wid_set_R9 ;No
wid_set_R2
MOVF wid_R_old,W
MOVWF wid_R_i ;前回のパルス幅を復元
BSF addflag,flag_R ;加減算を"+"に変更
MOVF addflag,W
MOVWF add_R
GOTO wid_set_R9
wid_set_R9
RETURN
; ===================== 緑のパルス幅算出 ============================
wid_set_G
;緑1回終了?
MOVF wid_G_i,W
MOVWF wid_G_old ;前回のパルス幅を保存
BTFSS addflag,flag_G ;加減算は"+" ?
GOTO wid_set_G1 ; No
MOVF add_G,W
ADDWF wid_G_i,F
BTFSS STATUS,C ;最大値になった?
GOTO wid_set_G9 ;No
MOVF wid_G_old,W
MOVWF wid_G_i ;前回のパルス幅を復元
BCF addflag,flag_G ;加減算を"−"に変更
MOVF addflag,W
MOVWF add_G
INCF add_G,F
GOTO wid_set_G9
wid_set_G1
MOVF add_G,W
SUBWF wid_G_i,F
BTFSC STATUS,C ;最小値になった?
BTFSC STATUS,Z ;最小値になった?
GOTO wid_set_G2 ;Yes
GOTO wid_set_G9 ;No
wid_set_G2
MOVF wid_G_old,W
MOVWF wid_G_i ;前回のパルス幅を復元
BSF addflag,flag_G ;加減算を"+"に変更
MOVF addflag,W
MOVWF add_G
GOTO wid_set_G9
wid_set_G9
RETURN
; ===================== 青のパルス幅算出 ============================
wid_set_B
;青1回終了?
MOVF wid_B_i,W
MOVWF wid_B_old ;前回のパルス幅を保存
BTFSS addflag,flag_B ;加減算は"+" ?
GOTO wid_set_B1 ; No
MOVF add_B,W
ADDWF wid_B_i,F
BTFSS STATUS,C ;最大値になった?
GOTO wid_set_B9 ;No
MOVF wid_B_old,W
MOVWF wid_B_i ;前回のパルス幅を復元
BCF addflag,flag_B ;加減算を"−"に変更
MOVF addflag,W
MOVWF add_B
INCF add_B,F
GOTO wid_set_B9
wid_set_B1
MOVF add_B,W
SUBWF wid_B_i,F
BTFSC STATUS,C ;最小値になった?
BTFSC STATUS,Z ;最小値になった?
GOTO wid_set_B2 ;Yes
GOTO wid_set_B9 ;No
wid_set_B2
MOVF wid_B_old,W
MOVWF wid_B_i ;前回のパルス幅を復元
BSF addflag,flag_B ;加減算を"+"に変更
MOVF addflag,W
MOVWF add_B
GOTO wid_set_B9
wid_set_B9
RETURN
END
; =========================== ここまで ===============================