;**************************************************************************** ; 7セグメント表示素子を使った光線銃早撃ちゲーム ; 3桁のセグメント発光ダイオードはPICでダイナミック点灯制御される ; 光線銃は引き金のボタンを押すと約数十msecのフラッシュ光線を発する ; ゲームがスタートするとある時間後に表示器が点灯を始める。 ; 光線銃の光が当たると表示器が反応時間○.○○secを表示して停止する。 ; 再度光線銃が当てるとゲームが再開する。 ;**************************************************************************** LIST P=PIC16F84 ;プロセッサ種別指定 INCLUDE "P16F84.INC" ;定数定義ファイル指定 ;******************************** ; 定数とメモリアドレスの定義 ;******************************** CNT1 EQU 0DH ;待ち時間用カウンタ CNT2 EQU 0EH ; 〃 CNT3 EQU 0FH ; 〃 COLUM EQU 10H ;表示桁位置 SHOOT EQU 11H ;光線感知フラグ RESTART EQU 12H ;再スタート待ちフラグ DIGIT1 EQU 13H ;1桁目データ DIGIT2 EQU 14H ;2桁目データ DIGIT3 EQU 15H ;3桁目データ WAIT EQU 16H ;誤感知回避待ちタイマ INTVL EQU 17H ;再開ディレイ用カウンタ ORG 0 ;0番地スタート ;******************************** ; メインプログラム ;******************************** MAIN ;**** PORT A & B、その他の初期化 **** BSF STATUS,RP0 ;bank 1に切替え MOVLW 010H ;RA4のみ入力他は出力 MOVWF TRISA ; CLRF TRISB ;PORT Bは全部出力 BCF STATUS,RP0 ;bank 0に戻す CLRF PORTB ;表示出力初期化 MOVLW 1 MOVWF PORTA ;1桁目のみ点灯(小数点) MOVLW 027H ;開始ディレイ初期化 MOVWF INTVL ;**** ゲーム開始 **** START BCF PORTA,3 ;ブザー off CLRF SHOOT ;感知フラグリセット CLRF RESTART ;再開待ちフラグリセット MOVLW 064H ;誤感知ディレイセット MOVWF WAIT ; CLRF DIGIT1 ;測定時間リセット(0.01sec) CLRF DIGIT2 ; 〃      (0.1sec) CLRF DIGIT3 ; 〃      (1sec) CALL DELAY ;開始ディレイ時間 BSF PORTA,3 ;ブザーon ;**** 時間カウント表示開始、光線監視開始 **** LOOP MOVLW 04H ;表示桁指定 MOVWF COLUM ;桁指定変数に保存 MOVF DIGIT1,W ;1桁目表示 CALL DISP MOVF DIGIT2,W ;2桁目表示 CALL DISP MOVF DIGIT3,W ;3桁目表示 CALL DISP ;**** 光線チェック ***** BTFSC SHOOT,0 ;当たったか? GOTO ATTACK ;当たった ;**** まだ当たらず、時間カウントアップ **** BTFSC RESTART,0 ;再開待ち中か? GOTO LOOP ;再開待ち中、表示静止 INCF DIGIT1,F ;1桁目+1(+0.01sec) MOVF DIGIT1,W ;9以上かチェック SUBLW 9 ;9-Wreg BTFSC STATUS,C ;負か? GOTO LOOP ;1桁目<10,そのまま戻る CLRF DIGIT1 ;1桁目0にして2桁目+1 INCF DIGIT2,F ;2桁目+1 MOVF DIGIT2,W ;9以上かチェック SUBLW 9 ;9-Wreg BTFSC STATUS,C ;負か? GOTO LOOP ;2桁目<10,そのまま戻る CLRF DIGIT2 ;2桁目0にして3桁目+1 INCF DIGIT3,F ;3桁目+1 MOVF DIGIT3,W ;9以上かチェック SUBLW 9 ;9-Wreg BTFSC STATUS,C ;負か? GOTO LOOP ;3桁目<10,そのまま戻る CLRF DIGIT3 ;3桁目0にする GOTO LOOP ;戻る ;**** 当たった、時間カウントアップ停止、再開待ち **** ATTACK BCF PORTA,3 ;ブザー off BTFSC RESTART,0 ;再開待ち中か? GOTO START ;再開へ ;**** 測定時間表示、静止状態 **** MOVF WAIT,W ;誤感知フラグを見る BTFSC STATUS,Z ;誤感知回避中か? GOTO AT1 ;回避終了 DECFSZ WAIT,F ;回避カウンタ-1 GOTO LOOP ;回避待ちループ AT1 BSF RESTART,0 ;再開待ちフラグセット CLRF SHOOT ;感知フラグクリア GOTO LOOP ;戻る ; ; 以下、サブルーチン群 ;********************************************** ; セグメント表示制御サブルーチン ; 表示データはWregにある ; ダイナミック点灯周期は 3msec/桁 ;********************************************** DISP CALL GET_7SEG ;10進数をセグメントに変換 MOVWF PORTB ;セグメントデータ出力 MOVF PORTA,W ;PORT A現在値入力 ANDLW 08H ;ブザービット取り出し IORWF COLUM,W ;ブザーと桁をOR MOVWF PORTA ;桁データ出力 CALL TIME3M ;3msec待つ CLRF PORTB ;次の桁のため一旦消去 ;**** 表示桁シフト **** BCF STATUS,C ;CARRYを消しておく RRF COLUM,F ;桁信号シフト ;**** 光感知チェック **** BTFSC PORTA,4 ;光入力チェック RETURN ;まだ、戻る BSF SHOOT,0 ;光感知、感知フラグon MOVF DIGIT1,W ;次の開始ディレイの計算 MOVWF INTVL ;INTVLに保存 RLF INTVL,F RLF INTVL,F ;INTVLを4倍 RETURN ;戻る ;************************************************* ; バイナリ4ビットをセグメントデータに変換 ; PORT RB0 は使わないのでその分シフト ;************************************************* GET_7SEG ANDLW 0FH ;下位4ビット取り出し ADDWF PCL,F ;PCレジスタに足してジャンプ RETLW B'01111110' ;Code 0 RETLW B'00001100' ;Code 1 RETLW B'10110110' ;Code 2 RETLW B'10011110' ;Code 3 RETLW B'11001100' ;Code 4 RETLW B'11011010' ;Code 5 RETLW B'11111010' ;Code 6 RETLW B'00001110' ;Code 7 RETLW B'11111110' ;Code 8 RETLW B'11001110' ;Code 9 RETLW B'00000000' ;Code A set blank RETLW B'00000000' ;Code b set blank RETLW B'00000000' ;Code C set blank RETLW B'00000000' ;Code d set balnk RETLW B'00000000' ;Code E set balnk RETLW B'00000000' ;Code F set blank ;************************************** ; ディレイタイマーサブルーチン ; TIM3M:3msec ; DELAY:開始ディレイ約1秒〜5秒 ;************************************** ;**** ダイナミック点灯用インターバル **** TIME3M MOVLW 6H ;約3msec相当 MOVWF CNT2 ; TIMLP2 CLRF CNT1 ;set 256 TIMLP1 NOP ;dumy nop NOP DECFSZ CNT1,F GOTO TIMLP1 ;5*256-1 DECFSZ CNT2,F GOTO TIMLP2 ;6*((5*256-1)+3)-1=7691 RETURN ;+3=7694*0.4usec=3.1msec ;**** ゲーム開始ディレイタイム(ランダム) **** ;**** 前回の時間の1桁目の値で時間を決める **** DELAY MOVF INTVL,W ;計算値取り出し ANDLW 020H ;最大値制限 ADDLW 0FH ;最小値制限 MOVWF CNT3 T5LP1 CLRF CNT2 T5LP2 CLRF CNT1 T5LP3 NOP ;dumy NOP NOP DECFSZ CNT1,F GOTO T5LP3 ;5*256-1=1279 DECFSZ CNT2,F GOTO T5LP2 ;(1279+4)*256-1=328447 DECFSZ CNT3,F GOTO T5LP1 ;(328447+4)*39-1+3=12.81M RETURN ;12.81*0.4=5.1sec ;***** source end ***** END