フルカラーLEDの発色実験

;*********************************************
; PIC16F628
; フルカラーLED制御プログラム v0.1
; yokoie 2003.11.26作製
; 2003.11.26更新
; クロックは4MHzで
;RB0,RB1,RB2 を使用
;*********************************************
LIST P=16F628, ST=OFF, R=DEC, F=INHX8M
INCLUDE P16F628.INC
__CONFIG _HS_OSC & _MCLRE_ON & _LVP_OFF & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _CP_OFF
; 変数レジスタの定義
CNT1 EQU 0x70 ;タイマ用変数
CNT2 EQU 0x71 ;タイマ用変数
CNT3 EQU 0x72 ;タイマ用変数
CNT4 EQU 0x73 ;タイマ用変数
PRDTIM EQU 0x74 ;PWMカウント用タイマ変数
DUTYR EQU 0x75 ;赤のパルス幅(0..PRD)
DUTYG EQU 0x76 ;緑のパルス幅
DUTYB EQU 0x77 ;青のパルス幅
DUTYPM EQU 0x78 ;0,1,2ビットでRGBの増加、減少を記録(1:+、0:-)
PRD EQU 0x79 ;PWMの周期(固定)
PMPRDR EQU 0x7a ;赤周期固定
PMPRDG EQU 0x7b ;緑周期固定
PMPRDB EQU 0x7c ;青周期固定
PMTIMR EQU 0x7d ;赤周期計数
PMTIMG EQU 0x7e ;緑周期計数
PMTIMB EQU 0x7f ;青周期計数
; メインルーチン
ORG 0 ;Reset Start
MAIN
;ポート設定
CALL BANK0 ;バンク0に切替え
CLRF PORTA ;PORTAをクリア
MOVLW B'00000010'
MOVWF CMCON ;PORTAをIOとして使用する
CALL BANK1 ;バンク1に切替え
MOVLW B'11100000'
MOVWF VRCON ;PORTAをIOとして使用する
MOVLW B'00000000'
MOVWF TRISA ;PORTAを全て出力に
MOVLW B'00000000'
MOVWF TRISB ;PORTBを全て出力に
CALL BANK0
;周期初期設定
MOVLW 0xf0
MOVLW PRD ;周期を128に
MOVLW 0x80
MOVWF DUTYR ;DUTYR:Redの時間を64に
MOVWF DUTYR ;DUTYGを64に
MOVWF DUTYB ;DUTYBを64に
MOVLW B'11111111' ;
MOVWF DUTYPM ;デューティーをすべてプラスに
MOVLW 0x14
MOVWF PMPRDR ;PMPRDR:赤周期を14に
MOVWF PMTIMR ;カウントリセット
MOVLW 0x1e
MOVWF PMPRDG ;PMPRDB:緑周期を1eに
MOVWF PMTIMG ;カウントリセット
MOVLW 0x28
MOVWF PMPRDB ;PMPRDBを28に
MOVWF PMTIMB ;カウントリセット
;メインループ
MAINLP
CALL TIM2 ;TIM2の時間待つ
DECFSZ PMTIMR ;PMTIMRを-1
GOTO DECPMG ;0でなければGへ飛ぶ
CALL PMR ;0ならR:赤の時間幅変更
DECPMG DECFSZ PMTIMG ;PMTIMGを-1
GOTO DECPMB ;0でなければBへ飛ぶ
CALL PMG ;0ならG:緑の時間幅変更
DECPMB DECFSZ PMTIMB ;PMTIMBを-1
GOTO MAINLP ;0でなければMAINLPに戻る
CALL PMB ;0ならB:青の時間幅変更
GOTO MAINLP ;繰り返す
;PWM初期化:3色を点灯する
PWMINIT MOVF PRD, W ;PRDをWに読み込む
MOVWF PRDTIM ;PRDCNTをPRDにリセット
MOVLW B'11111111'
MOVWF PORTA ;PORTAをすべてHに
MOVLW B'11111111'
MOVWF PORTB ;PORTBをすべてHに
RETURN
;PWMループ:1周期分繰返し、各色の時間幅で消灯する
PWMLP MOVF PRDTIM, W ;PRDTIMをWに読み込む
XORWF DUTYR, 0 ;PRDTIM == DUTYR?
BTFSC STATUS, Z ;ゼロフラグをチェック
BCF PORTB, 0 ;赤:PORTB-0をクリア
MOVF PRDTIM, W ;PRDTIMをWに読み込む
XORWF DUTYG, 0 ;PRDTIM == DUTYB?
BTFSC STATUS, Z ;ゼロフラグをチェック
BCF PORTB, 1 ;緑:PORTB-1をクリア
MOVF PRDTIM, W ;PRDTIMをWに読み込む
XORWF DUTYB, 0 ;PRDTIM == DUTYB?
BTFSC STATUS, Z ;ゼロフラグをチェック
; CLRF PORTB ;PORTBをクリア
BCF PORTB, 2 ;青:PORTB-2をクリア
DECFSZ PRDTIM, 1 ;PRDIMTを1マイナス
GOTO PWMLP ;0でなければPWMLPに戻る
RETURN
;赤色の時間設定
PMR BTFSC DUTYPM , 0
CALL DUTYPR ;幅を増す
BTFSS DUTYPM , 0
CALL DUTYMR ;幅を減らす
MOVF PMPRDR, W ;PMPRDRをWに
MOVWF PMTIMR ;カウントリセット
RETURN ;戻る
;+−G
PMG BTFSC DUTYPM , 1 ;
CALL DUTYPG
BTFSS DUTYPM , 1
CALL DUTYMG
MOVF PMPRDG, W ;PMPRDGをWに
MOVWF PMTIMG ;カウントリセット
RETURN
;+−B
PMB BTFSC DUTYPM , 2
CALL DUTYPB
BTFSS DUTYPM , 2
CALL DUTYMB
MOVF PMPRDB, W ;PMPRDBをWに
MOVWF PMTIMB ;カウントリセット
RETURN
;デューティープラスR
DUTYPR INCF DUTYR, 1
MOVF DUTYR, W ;DUTYRをWに読み込む
XORWF PRD, 0 ;DUTYR == PRD?
BTFSC STATUS, Z ;ゼロフラグをチェック
BCF DUTYPM, 0 ;+-フラグを0に(第0bit)
RETURN
;デューティーマイナスR
DUTYMR DECF DUTYR, 1
MOVLW 0x01 ;Wを1に
XORWF DUTYR, 0 ;DUTYR == 1?
BTFSC STATUS, Z ;ゼロフラグをチェック
BSF DUTYPM, 0 ;+-フラグを1に(第0bit)
RETURN
;デューティープラスG
DUTYPG INCF DUTYG, 1
MOVF DUTYG, W ;DUTYRをWに読み込む
XORWF PRD, 0 ;DUTYR == PRD?
BTFSC STATUS, Z ;ゼロフラグをチェック
BCF DUTYPM, 1 ;+-フラグを0に(第0bit)
RETURN
;デューティーマイナスG
DUTYMG DECF DUTYG, 1
MOVLW 0x01 ;Wを1に
XORWF DUTYG, 0 ;DUTYR == 1?
BTFSC STATUS, Z ;ゼロフラグをチェック
BSF DUTYPM, 1 ;+-フラグを1に(第0bit)
RETURN
;デューティープラスB
DUTYPB INCF DUTYB, 1
MOVF DUTYB, W ;DUTYBをWに読み込む
XORWF PRD, 0 ;DUTYA == PRD?
BTFSC STATUS, Z ;ゼロフラグをチェック
BCF DUTYPM, 2 ;+-フラグを0に(第2bit)
RETURN
;デューティーマイナスB
DUTYMB DECF DUTYB, 1
MOVLW 0x01 ;Wを1に
XORWF DUTYB, 0 ;DUTYB == 1?
BTFSC STATUS, Z ;ゼロフラグをチェック
BSF DUTYPM, 2 ;+-フラグを1に(第2bit)
RETURN
;タイマサブルーチン
TIM1 MOVLW 0xff ;255
MOVWF CNT1 ;
TIMLP1 CALL TIM2 ;
DECFSZ CNT1,F ;繰返し処理
GOTO TIMLP1 ;
RETURN ;
TIM2 MOVLW 0x01 ;
MOVWF CNT2 ;
TIMLP2 CALL PWMINIT ;PWM初期化
CALL PWMLP ;PWM実行
DECFSZ CNT2,F ;繰返し処理
GOTO TIMLP2 ;
RETURN ;
TIM4 MOVLW 0x02 ;使用せず
MOVWF CNT4 ;
TIMLP4 DECFSZ CNT4,F ;
GOTO TIMLP4 ;
RETURN
;メモリバンク0に切り替える
BANK0 BCF STATUS, RP0
BCF STATUS, RP1
RETURN
;メモリバンク1に切り替える
BANK1 BSF STATUS, RP0
BCF STATUS, RP1
RETURN
END