title LED_M1 Lamp list p=16f648A,R=DEC,f=inhx32 #include ; ; CONFIG設定 __CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _LVP_OFF & _CP_OFF & _BOREN_ON ; ; 2006年9月19日 REV.2 仮テスト ; 2006年10月22日 REV.4 SW1を内蔵し、チラツキおよび点滅を追加 ; 2006年11月19日 REV.5 周期を224−>122Hz変更 DIP4-7動作ゆらぎへ変更 ; 2006年11月23日 REV.6 DIP=4動作テーブルを32個、x8ステップへ変更 ;動作 5端子レギュレータの出力1ラインをON/OFFさせて接続されたLED点灯を制御する ; RB3 RB2 RB1 RB0 ; 0 0 0 0  常時点灯 SW1にて遅延消灯、即点灯 ; 0 0 0 1  75%点灯 SW1にて遅延消灯、即点灯 ; 0 0 1 0  50%点灯 SW1にて遅延消灯、即点灯 ; 0 0 1 1  25%点灯 SW1にて遅延消灯、即点灯 ; 0 1 0 0 ゆらぎ ランダム点灯1 ; 0 1 0 1 ゆらぎ ランダム点灯2 ; 0 1 1 0 ゆらぎ シーケンシャル点灯1 ; 0 1 1 1 ゆらぎ シーケンシャル点灯2 ; 1 x x x 予備 ; org 20h count256us res 1 ;256μS毎の割り込みをカウント count65ms res 1 ;256μsを256カウントで1up wtemp res 1 ;Wレジ保存エリア statemp res 1 ;ステータスレジ保存エリア ; t_ledon res 1 ;LEDが点灯している時間(n/16) now_count res 1 ;現在の256usカウントの下4ビット t_mask res 1 ;周期を指定するマスク値 countshuki res 1 ;スイッチ周期毎にカウント countx res 1 ;スイッチングカウントの倍数保存 m1_flag res 1 ; sw1_on equ 0 ;SW1がオンされたセット p_start equ 1 ;周期パルスがスタートした t_max res 1 ; endcount_t res 1 ;終了 パルス幅タイマカウント endcount_w res 1 ;終了 周期タイマカウント dcnt1 res 1 ;終了カウント dcnt2 res 1 line1 equ 7 ;RB7 sw1 equ 1 ;RA1 org 00h ;プログラム開始番地 goto Start ; ;******** ; タイマー割込みルーチン 256μs毎の割り込みをカウントする ;******** org 4 movwf wtemp ;save wreg swapf STATUS,w movwf statemp ;save STATUS ; ここまでが割り込みPUSH bcf INTCON,T0IF ;reset Timer0 interrupt ; movlw -led_interval ;タイマ初期値 ; movwf TMR0 ;set Timer0 counter incfsz count256us,f ;割込みごとにカウントアップ goto t_exit ; incf count65ms,f ;もし、オーフローしたら65msカウンタをアップ ; ここからが割り込みPOP t_exit swapf statemp,w movwf STATUS ;re-load STATUS swapf wtemp,f swapf wtemp,w ;re-load Wreg retfie ;割込みルーチンから戻る ;************** movlw "6" ;REV. status 2006/11/20 ;******** ; DIPスイッチ(RB3-0)の値でジャンプする(7FF番地まで可) lowswjump clrf PCLATH andlw 0Fh addwf PCL,F ; goto dip0 ;decode 0 goto dip1 ;decode 1 goto dip2 ;decode 2 goto dip3 ;decode 3 goto dip4 ;decode 4 goto dip5 ;decode 5 goto dip6 ;decode 6 goto dip7 ;decode 7 goto dip8 ;decode 8 goto dip9 ;decode 9 goto dip10 ;decode 10 goto dip11 ;decode 11 goto dip12 ;decode 12 goto dip13 ;decode 13 goto dip14 ;decode 14 goto dip15 ;decode 15 ;***** ; 明るさを定義するテーブル ;***** duty1 ;16通りのランダムな明るさ clrf PCLATH andlw 0Fh addwf PCL,F ; dt 32,24,24,32,29,25,25,30,25,27,27,32,27,25,29,32 ;** duty2 ;16通りのシーケンシャル明るさ clrf PCLATH andlw 0Fh addwf PCL,F dt 32,29,25,22,20,19,17,16,16,17,19,20,22,25,29,32 ; duty3 ;32通りのランダムの明るさ clrf PCLATH andlw 1Fh addwf PCL,F dt 32,30,29,28,27,26,25,24,26,25,27,25,26,25,24,24 dt 25,24,25,26,27,25,26,27,26,27,28,29,28,29,30,31 ;ここの終わりは100番地未満とする。 ;************ Start ; ポートの初期化 ; PORT -A initial I/O setting I I I I I I I 0 bsf STATUS,RP0 ;bank 1 movlw B'11111110' ; movwf TRISA-80h ; PORT -B Initial I/O Setting O O O O I I I I movlw B'00001111'; movwf TRISB-80h ; CPUスピードを決める bsf PCON-80h,OSCF ;内蔵CLOCKを4MHzに設定する ; タイマー割り込み設定とPort-Bをプルアップする ; -RBUP=0 ON TOCS=0内蔵 T0SEイベント許可 PSA=1 PRESC不使用 PS2-0=0 movlw B'00001000' movwf OPTION_REG-80h bcf STATUS,RP0 ;bank 0 ; PORT-AをデジタルI/Oにする movlw 7h movwf CMCON ; ; clear Port-A/B data bit clrf PORTA clrf PORTB clrf TMR0 clrf count256us ;割り込みルーチン内のカウンタ clrf count65ms ; clrf countshuki ; ; タイマー割り込みをセットする GIE 0 T0IE 0 0 T0IF 0 0 movlw b'10100000' movwf INTCON ; ;*** btfss PORTB,3 ;RB3 =1 =OFF ;*** goto spec2 ;ONなので新しい仕様動作へ ;**** ; DIPスイッチを読んで動作を決めジャンプする ; 明るさを制御(調光)する値を設定する。(PWM動作もどき) m1_start movlw b'10000000' ; movwf PORTB ;ライン1のLEDを点灯させる clrf count256us ;割り込みルーチン内のカウンタ clrf m1_flag ; m1_readsw movf PORTB,w ;DIPスイッチRB3-0を読む xorlw 0ffh ;ON=0を1に反転する goto lowswjump ;内容によりDIP0からDIP7に戻ってくる ; ;**** ; LED点灯の点灯明るさを変化させる ;**** dip0 ;常時点灯 movlw 0 movwf t_ledon goto dip0003 dip1 ;75% movlw 24 ; movwf t_ledon goto dip0003 dip2 ;50% movlw 16 ; movwf t_ledon goto dip0003 dip3 ;25% movlw 8 movwf t_ledon dip0003 ;DOP00-DIP03は周期を32カウント、約8ms=122Hz動作 movlw 32-1 ;MAX 32カウント movwf t_max goto ledstart ;*********** ; DUTYを変えてチラツキを出す ;*********** dip4 ;周期カウンタ8倍でDUTY値ランダム32個 movf countshuki,w movwf countx rrf countx,f ;Shift 1 rrf countx,f ;Shift 1 rrf countx,f ;Shift 1 movlw 32-1 ;MAX 32カウント122Hz movwf t_max movf countx,w ; call duty3 ;テーブルは32個 movwf t_ledon goto ledstart ; dip5 ;周期カウンタ4倍でDUTY値ランダム16個 movf countshuki,w movwf countx rrf countx,f ;Shift 1 rrf countx,f ;Shift 1 movlw 32-1 ;MAX 32カウント122Hz movwf t_max movf countx,w ; call duty1 ; movwf t_ledon goto ledstart ; dip6 ;周期カウンタ4倍でDUTY値シーケンシャル movf countshuki,w movwf countx rrf countx,f ;Shift 1 rrf countx,f ;Shift 1 goto dip0607 ; dip7 ;周期カウンタ8倍でDUTY値シーケンシャル movf countshuki,w movwf countx rrf countx,f ;Shift 1 rrf countx,f ;Shift 1 rrf countx,f ;Shift 1 dip0607 movlw 32-1 ;MAX 32カウント 122Hz movwf t_max movf countx,w ; call duty2 ; movwf t_ledon goto ledstart ; ;****MAIN ; ledstart ; 現在のカウント(下4ビット)がゼロならLEDを点灯 movf count256us,w ;タイマカウントを読む andwf t_max,w ;下の5ビットを取り出す movwf now_count ;周期カウントとして保存する btfss STATUS,Z ;カウント開始のゼロか? goto checkoff ;NO, ; YES, btfsc m1_flag,p_start ;すでに処理ずみか? goto checksw1 ;YES スキップ bsf m1_flag,p_start ;処理済フラグをセット movlw b'10000000' ;Line1点灯 movwf PORTB ; incf countshuki,f ; goto checksw1 ;消灯カウントのチェックをスキップ ; 現在のカウント(下5ビット)と指定カウントが一致したらLEDを消灯 checkoff bcf m1_flag,p_start ;処理済フラグをクリア movf now_count,w ;タイマカウントは消灯カウントか? xorwf t_ledon,w ; btfss STATUS,Z ; goto checksw1 ;NO そのまま継続 movlw b'00000000' ;YES Line1消灯 movwf PORTB ; ; SW1を押されたら、しばらくして照明を切るモードにする checksw1 ; btfsc PORTB,2 ;dip4-7のSW1使用モードか?(ON=0) ; goto m1_readsw ;NO 通常点灯モード ; btfsc PORTA,sw1 ;SW1押されたか? goto check_wait ;NO goto $+1 ;押されたのでチャタリング防止のため少し待つ goto $+1 btfsc PORTA,sw1 ;再度、SW1押されていたか?(確認) goto check_wait ;NO clrf count65ms ;押されるごとに待ち時間カウントをクリアし延長する bsf m1_flag,sw1_on ;sw1が押されたことを覚える ; 照明OFFの時間まで継続し、その後消灯する check_wait btfss m1_flag,sw1_on ;すでにSW1が押されたかチェックする goto m1_readsw ;まだ、押されていないので戻る ; movf count65ms,w ; xorlw 07fh ;65msx128=8秒待ったか? btfss STATUS,Z ; goto m1_readsw ;NO 継続する movlw b'00000000' ;待ったのでLine1を消灯する movwf PORTB ; ; 消灯後は今度SW1を押したら点灯させるモードに切り替える。 ; SW1スイッチ押されると点灯する check_sw1_on btfsc PORTA,sw1 ;SW1押されたか?(ON=0) goto check_sw1_on ;NO goto $+1 goto $+1 btfsc PORTA,sw1 ;再度、SW1押されていたか? goto check_sw1_on ;NO ; SW1が離されるまで待つ check_sw1_off btfss PORTA,sw1 ;SW1を離したか? goto check_sw1_off ;NO goto $+1 goto $+1 goto $+1 goto $+1 btfss PORTA,sw1 ;もう一度SW1を離したか確認? goto check_sw1_off ;NO goto $+1 goto $+1 goto m1_start spec2 ; ; ユーザ定義用(予備) ; dip8 dip9 dip10 dip11 dip12 dip13 dip14 dip15 movlw B'10000000' ; movwf PORTB ;RB7のLED点灯 ; goto m1_readsw ; ;*** ; 65ms毎ディレイルーチン (Wレジの時刻まで待つ) ;*** delay movwf dcnt1 ;終了時間を保存する dloop1 xorwf count65ms,w ;65msタイマは終了時間に一致したか? btfsc STATUS,Z ;NO return ;YES movf dcnt1,w ;終了時間を再ロード goto dloop1 end