目次>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 ; =========================== ここまで ===============================