;--------------------------------------------------------------------- ; 脳トレ(フラッシュ暗算) ; ; 2008.08.20 T.Nakamura ; ; (1). RC0〜7 [out] : 行(データポート) LEDアノード側 ; (2). RA0〜2,4,RB4〜7[out] : 列(スキャンポート) LEDカソード側 ; (3). RA3 [in] : タクトスイッチ ; (4). RA5 [out] : 圧電ブザー ;--------------------------------------------------------------------- ; ;--------------------------------------------------------------------- ; デバイス定義 ;--------------------------------------------------------------------- LIST P=PIC16F689 INCLUDE "P16F689.INC" __CONFIG _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; 変数レジスタの定義(BANK0) ;--------------------------------------------------------------------- ;--------------------------------------------------------------------- ; 変数レジスタの定義(マトリックスLEDプラットフォーム) ;--------------------------------------------------------------------- DSPBUF EQU 020H ; 表示バッファ 8バイト(20H〜27H, 28H) ; ; 28HはLEDなし(スクロール時の次の列データ) ROWCNT EQU 029H ; マトリックスLEDのROWカウンタ FLAG EQU 02AH ; 各種フラグ 0ビット:LED点灯:1,消灯:0 ; 1ビット:SW-変化:1,変化なし:0 ; 2ビット:SW-ON:1,OFF:0(押されている間ON) ; 3ビット:SW-ON:1(PGで解除するまでON) BKUPW EQU 02BH ; Wレジ待避用 BKUPS EQU 02CH ; STATUSレジ待避用 BKUPFR EQU 02DH ; FSRレジ待避用 BKUPPCL EQU 02EH ; PCLHレジ待避用 BKPORTA EQU 02FH ; PORTA状態(ビープ音用) ; POSX EQU 030H ; LED座標X POSY EQU 031H ; LED座標Y BUFCNT1 EQU 032H ; 表示バッファ作業用 BUFCNT2 EQU 033H ; 表示バッファ作業用 CNT EQU 034H ; カウンタ WCNT1 EQU 035H ; ウェイトカウンタ WCNT2 EQU 036H ; ウェイトカウンタ WCNT3 EQU 037H ; ウェイトカウンタ BCNT1 EQU 038H ; ビープ用 BWCNT1 EQU 039H ; ビープ用 BWCNT2 EQU 03AH ; ビープ用 BWCNT3 EQU 03BH ; ビープ用 CHATCNT EQU 03CH ; チャタリング除去用カウンタ ; MSGCNT EQU 03DH ; メッセージカウンタ MSGPTR EQU 03EH ; メッセージポインタ CHRCNT EQU 03FH ; メッセージカウンタ CHRPTR EQU 040H ; メッセージポインタ ;--------------------------------------------------------------------- ; 変数レジスタの定義(アプリ用) ;--------------------------------------------------------------------- DIGIT1 EQU 041H ; 1桁目(一の位) DIGIT2 EQU 042H ; 2桁目(十の位) DIGFLG EQU 043H ; 0ビット目 1:10の位、0:1の位の表示 WK1 EQU 044H WK2 EQU 045H WK3 EQU 046H CNT1 EQU 047H CNT2 EQU 048H ; RNDVAL EQU 049H RND1 EQU 04AH RND2 EQU 04BH ANS EQU 04CH MODE EQU 04DH ; モード(0:加算、1:減算:、2:混在) QNO EQU 04EH ; 問題番号 ;--------------------------------------------------------------------- ; マクロ定義 ;--------------------------------------------------------------------- BANK0 MACRO BCF STATUS,RP0 ;BANK0に切り替える BCF STATUS,RP1 ; ENDM BANK1 MACRO BSF STATUS,RP0 ;BANK1に切り替える BCF STATUS,RP1 ; ENDM BANK2 MACRO BCF STATUS,RP0 ;BANK2に切り替える BSF STATUS,RP1 ; ENDM ;--------------------------------------------------------------------- ; リセットベクタ ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET GOTO MAIN ; メイン処理へ ; ORG 04H ; 割り込み時の飛び込み先 GOTO INTRUPT ;--------------------------------------------------------------------- ; メイン処理 ;--------------------------------------------------------------------- MAIN CALL INIT ; ; START INCF MODE,F ; 問題モードインクリメント MOVLW D'4' ; mode=4ならクリア SUBWF MODE,W BTFSS STATUS,Z GOTO $+3 MOVLW D'1' MOVWF MODE ; CALL DSPMODE ; 問題モード表示 BTFSC FLAG,2 ; SWがOFFになるまで待つ GOTO $-1 BCF FLAG,3 ; SWクリア ; CALL WAIT BTFSC FLAG,3 ; SWが押されたら最初から GOTO START ; CLRF QNO ; 問題番号クリア LOOP CALL DSPNO ; 問題番号表示 CALL WAIT BTFSC FLAG,3 ; SWが押されたら最初から GOTO START ; CALL CLRDPBUF CALL WAIT BTFSC FLAG,3 ; SWが押されたら最初から GOTO START ; MOVLW D'1' SUBWF MODE,W BTFSS STATUS,Z GOTO $+5 ; 引き算へ CALL CALCADD ; mode=1 足し算 BTFSC FLAG,3 ; SWが押されたら最初から GOTO START GOTO LAST ; MOVLW D'2' SUBWF MODE,W BTFSS STATUS,Z GOTO $+5 ; 混在へ CALL CALCSUB ; mode=2 引き算 BTFSC FLAG,3 ; SWが押されたら最初から GOTO START GOTO LAST ; BTFSS QNO,0 ; mode=3 足し算/引き算混在 GOTO $+5 ; 引き算へ CALL CALCADD ; 足し算 BTFSC FLAG,3 ; SWが押されたら最初から GOTO START GOTO LAST ; CALL CALCSUB ; 引き算 BTFSC FLAG,3 ; SWが押されたら最初から GOTO START ; LAST INCF QNO,F ; 問題番号インクリメント MOVLW D'10' SUBWF QNO,W BTFSS STATUS,Z GOTO $+3 ; CLRF QNO ; 問題番号クリア CALL MSGFIN ; 終了メッセージ ; CALL WAIT BTFSC FLAG,3 ; SWが押されたら最初から GOTO START GOTO LOOP ; ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- INIT BCF INTCON,GIE ;全割込み禁止 BANK2 CLRF ANSEL CLRF ANSELH BANK1 MOVLW B'11001000' MOVWF TRISA ; ポートAはBIT0,1,2,4,5を出力、3を入力端子 CLRF TRISB ; ポートBは全て出力端子 CLRF TRISC ; ポートCは全て出力端子 ;割り込みタイマーセット MOVLW H'82' ;プリスケーラを1:8にする MOVWF OPTION_REG ;約488ヘルツで割り込みが入るはず BANK0 ;clock4MHz -> 1Mcycle ;1Mcycle/256/8 = 488Hz ; CLRF PORTA ; PORTクリア CLRF PORTB ; CLRF ROWCNT ; LED ROWカウンタクリア CALL CLRDPBUF ; LEDバッファクリア CALL RANDINT ; 乱数初期化 CLRF FLAG CLRF DIGFLG CLRF MODE ; modeクリア ; BSF INTCON,T0IE ; タイマ0割り込みイネーブル BSF INTCON,GIE ; 割り込み許可 ; RETURN ;--------------------------------------------------------------------- ; 割り込み処理でダイナミック表示を行う。 ;--------------------------------------------------------------------- INTRUPT ;レジスタ待避 MOVWF BKUPW ;バックアップ(Wレジ) SWAPF STATUS,W ;バックアップ(STATUSレジ) MOVWF BKUPS MOVF FSR,W ;バックアップ(FSRレジ) MOVWF BKUPFR MOVF PCLATH,W ;バックアップ(PCLATHレジ) MOVWF BKUPPCL ; BCF INTCON,T0IF ;割り込みフラグリセット ; ; タクトスイッチの状態確認 ; BTFSS FLAG,1 ; FLAG:1がONならSWが変化 GOTO CHKSW ; SWの状態確認へ DECFSZ CHATCNT,F ; チャタリングカウンタをデクリメント GOTO DSPLED ; まだ判断には早い ; SW状態確認 BCF FLAG,1 ; 変化フラグクリア BCF FLAG,2 ; FLAGクリア BTFSS PORTA,3 ; Highなら押されていないので次スキップ BSF FLAG,2 ; SWは押された(押されている間ON) BSF FLAG,3 ; SW-on(解除するまでON) GOTO DSPLED CHKSW BTFSS PORTA,3 GOTO CHKLOW ; Low:押されている ; High 押されていない BTFSS FLAG,2 ; 変化を確認 GOTO DSPLED ; 変化していない GOTO TOGGLE ; 変化した CHKLOW BTFSC FLAG,2 ; 変化を確認 GOTO DSPLED ; 変化していない TOGGLE BSF FLAG,1 ; 変化フラグをON MOVLW D'10' MOVWF CHATCNT ; チャタリング回避カウンタセット DSPLED ; ; 表示バッファの内容を1行分(1行)出力 ; ; 次の行データを出力する前に受け側portをHIGH(消灯になる) MOVLW B'11111111' ; MOVWF PORTB ; PORTB出力 BTFSS PORTA,5 ; PORTA(5) 確認 MOVLW B'11011111' ; PORTA(5) LOW MOVWF PORTA ; PORTA出力 ; MOVF ROWCNT,W ADDLW DSPBUF ; DSPバッファアドレス加算 MOVWF FSR MOVF INDF,W MOVWF PORTC ; PORTCに1行分のデータ出力 ; BTFSC ROWCNT,2 ; 4以上ならPORTBを設定 GOTO SETPRTB ; MOVF ROWCNT,W CALL DECPORTA BTFSS PORTA,5 ; PORTA(5) 確認 ANDLW B'11011111' ; PORTA(5) LOW MOVWF PORTA ; PORTA出力 MOVLW B'11111111' MOVWF PORTB ; PORTB出力 GOTO NXTROW ; 次の行にROWCNT設定 SETPRTB MOVLW D'4' SUBWF ROWCNT,W CALL DECPORTB MOVWF PORTB ; PORTB出力 MOVLW B'11111111' BTFSS PORTA,5 ; PORTA(5) 確認 ANDLW B'11011111' ; PORTA(5) LOW MOVWF PORTA ; PORTA出力 ; NXTROW INCF ROWCNT,W ANDLW H'07' ; ROWCNTは0〜7 MOVWF ROWCNT ; RSTREG ;レジスタ復元 MOVF BKUPPCL,W ;復元(PCLATHレジ) MOVWF PCLATH MOVF BKUPFR,W ;復元(FSRレジ) MOVWF FSR SWAPF BKUPS,W ;復元(STATUSレジ) MOVWF STATUS SWAPF BKUPW,F ;復元(Wレジ) SWAPF BKUPW,W ; RETFIE ;割り込みから復帰 ; DECPORTA CLRF PCLATH ; ADDWF PCL,F RETLW B'11111110' ; 0 RETLW B'11111101' ; 1 RETLW B'11111011' ; 2 RETLW B'11101111' ; 3 ; DECPORTB CLRF PCLATH ; ADDWF PCL,F RETLW B'11101111' ; 4 RETLW B'11011111' ; 5 RETLW B'10111111' ; 6 RETLW B'01111111' ; 7 ; ;--------------------------------------------------------------------- ; 足し算 ;--------------------------------------------------------------------- CALCADD CALL RANDOM CALL MOD100 ; 100で割った余り MOVWF RND1 BTFSC STATUS,Z ; 0なら再計算 GOTO CALCADD ; CALCADD1 CALL RANDOM CALL MOD100 ; 100で割った余り MOVWF RND2 BTFSC STATUS,Z ; 0なら再計算 GOTO CALCADD1 ; ADDWF RND1,W MOVWF ANS SUBLW D'99' BTFSS STATUS,C GOTO CALCADD ; MOVF RND1,W CALL DISPNUM CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; CALL DSPPLUS CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; MOVF RND2,W CALL DISPNUM CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; CALL DSPEQUAL CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; MOVF ANS,W CALL DISPNUM CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; CALL CLRDPBUF CALL WAIT RETURN ; ;--------------------------------------------------------------------- ; 引き算 ;--------------------------------------------------------------------- CALCSUB CALL RANDOM CALL MOD100 ; 100で割った余り MOVWF RND1 BTFSC STATUS,Z ; 0なら再計算 GOTO CALCSUB ; CALCSUB1 CALL RANDOM CALL MOD100 ; 100で割った余り MOVWF RND2 BTFSC STATUS,Z ; 0なら再計算 GOTO CALCSUB1 ; SUBWF RND1,W BTFSS STATUS,C GOTO CALCSUB MOVWF ANS ; MOVF RND1,W CALL DISPNUM CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; CALL DSPMINUS CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; MOVF RND2,W CALL DISPNUM CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; CALL DSPEQUAL CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; MOVF ANS,W CALL DISPNUM CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN ; CALL CLRDPBUF CALL WAIT RETURN ; ;--------------------------------------------------------------------- ; Wレジ値をビット位置にデコード ;--------------------------------------------------------------------- ORG H'0100' DECBIT MOVLW H'01' MOVWF PCLATH ADDWF PCL,F DECBIT1 RETLW B'00000001' ;0 RETLW B'00000010' ;1 RETLW B'00000100' ;2 RETLW B'00001000' ;3 RETLW B'00010000' ;4 RETLW B'00100000' ;5 RETLW B'01000000' ;6 RETLW B'10000000' ;7 ; ;--------------------------------------------------------------------- ; Wレジの値を表示(ゼロサプレス) ;--------------------------------------------------------------------- DISPNUM CALL B2BCD ; BCD変換 ; CALL CLRDPBUF ; 表示バッファクリア ; MOVF DIGIT1,W BCF DIGFLG,0 ; 1の位表示 CALL DSPDIGT ; MOVF DIGIT2,W BTFSC STATUS,Z RETURN BSF DIGFLG,0 ; 10の位表示 CALL DSPDIGT RETURN ;--------------------------------------------------------------------- ; BCD変換(単純に10を減算)Wレジのバイナリ値をDIGIT2,1にBCDで入れる ;--------------------------------------------------------------------- B2BCD CLRF DIGIT1 CLRF DIGIT2 MOVWF WK1 SUBLW D'99' ; 100以上なら"00"を返す BTFSS STATUS,C RETURN MOVLW D'10' B2BCD1 SUBWF WK1,F ; -10 BTFSS STATUS,C GOTO B2BCD2 INCF DIGIT2,F GOTO B2BCD1 B2BCD2 ADDWF WK1,W MOVWF DIGIT1 RETURN ; ;--------------------------------------------------------------------- ; 100で割った余りを求める ;--------------------------------------------------------------------- MOD100 MOVWF WK1 MOVLW D'100' MOD100_1 SUBWF WK1,F ; -100 BTFSC STATUS,C GOTO MOD100_1 ; ADDWF WK1,W RETURN ; ;--------------------------------------------------------------------- ; Wの値(00〜09:10種)の数字をDIGFLGに応じた位置に表示する ;--------------------------------------------------------------------- DSPDIGT MOVWF WK2 ; 待避 CLRF CHRPTR ; 列カウンタクリア MOVLW D'3' MOVWF CHRCNT MOVLW DSPBUF BTFSS DIGFLG,0 ADDLW D'4' ; 1の位なら4pix移動 MOVWF FSR DSPDIG1 CALL DIGCHR ; 数値の先頭1列分を取り出す MOVWF INDF INCF FSR,F DECFSZ CHRCNT,F GOTO DSPDIG1 RETURN ; DIGCHR ;数字の1列分のデータを取り出し MOVF CHRPTR,F ; MSGPTRが0か判断 BTFSS STATUS,Z ; 数字の最初の列のときにPTRを計算(3倍) GOTO DIGCHRD BCF STATUS,C ;キャリークリア RLF WK2,W ; 2倍 ADDWF WK2,W ; +元の数値で3倍 MOVWF CHRPTR DIGCHRD MOVLW H'01' MOVWF PCLATH MOVF CHRPTR,W INCF CHRPTR,F ; 1列進める ADDWF PCL,F ; digit 0 RETLW B'11111100' RETLW B'10000100' RETLW B'11111100' ; digit 1 RETLW B'10001000' RETLW B'11111100' RETLW B'10000000' ; digit 2 RETLW B'11001100' RETLW B'10100100' RETLW B'10011100' ; digit 3 RETLW B'10010100' RETLW B'10010100' RETLW B'01111000' ; digit 4 RETLW B'00011100' RETLW B'00010000' RETLW B'11111100' ; digit 5 RETLW B'10011100' RETLW B'10010100' RETLW B'01100100' ; digit 6 RETLW B'11111100' RETLW B'10010100' RETLW B'11110100' ; digit 7 RETLW B'00000100' RETLW B'11100100' RETLW B'00011100' ; digit 8 RETLW B'11111100' RETLW B'10010100' RETLW B'11111100' ; digit 9 RETLW B'10011100' RETLW B'10010100' RETLW B'01111100' ; ;--------------------------------------------------------------------- ; 問題番号QNOを表示する ;--------------------------------------------------------------------- DSPNO MOVF QNO,W MOVWF WK2 ; 待避 CLRF CHRPTR ; 列カウンタクリア MOVLW D'8' MOVWF CHRCNT MOVLW DSPBUF MOVWF FSR DSPNO1 CALL DIGNO ; 数値の先頭1列分を取り出す MOVWF INDF INCF FSR,F DECFSZ CHRCNT,F GOTO DSPNO1 RETURN ; DIGNO ;数字の1列分のデータを取り出し MOVF CHRPTR,F ; MSGPTRが0か判断 BTFSS STATUS,Z ; 数字の最初の列のときにPTRを計算(8倍) GOTO DIGNOD BCF STATUS,C ;キャリークリア RLF WK2,F ; 2倍 RLF WK2,F ; 4倍 RLF WK2,W ; 8倍 MOVWF CHRPTR DIGNOD MOVLW H'01' MOVWF PCLATH MOVF CHRPTR,W INCF CHRPTR,F ; 1列進める ADDWF PCL,F ; digit (1) RETLW B'01111100' RETLW B'10000010' RETLW B'01001000' RETLW B'01111100' RETLW B'01000000' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (2) RETLW B'01111100' RETLW B'10000010' RETLW B'01110100' RETLW B'01010100' RETLW B'01011100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (3) RETLW B'01111100' RETLW B'10000010' RETLW B'01010100' RETLW B'01010100' RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (4) RETLW B'01111100' RETLW B'10000010' RETLW B'00011100' RETLW B'00010000' RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (5) RETLW B'01111100' RETLW B'10000010' RETLW B'01011100' RETLW B'01010100' RETLW B'01110100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (6) RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'01010100' RETLW B'01110100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (7) RETLW B'01111100' RETLW B'10000010' RETLW B'00000100' RETLW B'01110100' RETLW B'00001100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (8) RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'01010100' RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (9) RETLW B'01111100' RETLW B'10000010' RETLW B'01011100' RETLW B'01010100' RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ; digit (F) RETLW B'01111100' RETLW B'10000010' RETLW B'01111100' RETLW B'00010100' RETLW B'00010100' RETLW B'10000010' RETLW B'01111100' RETLW B'00000000' ;--------------------------------------------------------------------- ; モードを表示する ;--------------------------------------------------------------------- DSPMODE MOVLW D'1' SUBWF MODE,W BTFSS STATUS,Z GOTO $+3 CALL DSPPLUS ; mode=1 足し算 RETURN MOVLW D'2' SUBWF MODE,W BTFSS STATUS,Z GOTO $+3 CALL DSPMINUS ; mode=2 引き算 RETURN CALL DSPPM ; mode=3 混在(プラスマイナス) RETURN ;--------------------------------------------------------------------- ; 演算子(+,-) と = を表示する ;--------------------------------------------------------------------- ORG H'0200' DSPPLUS MOVLW B'00000000' MOVWF DSPBUF MOVLW B'00010000' MOVWF DSPBUF+1 MOVLW B'00010000' MOVWF DSPBUF+2 MOVLW B'01111100' MOVWF DSPBUF+3 MOVLW B'00010000' MOVWF DSPBUF+4 MOVLW B'00010000' MOVWF DSPBUF+5 MOVLW B'00000000' MOVWF DSPBUF+6 MOVLW B'00000000' MOVWF DSPBUF+7 RETURN DSPMINUS MOVLW B'00000000' MOVWF DSPBUF MOVLW B'00000000' MOVWF DSPBUF+1 MOVLW B'00010000' MOVWF DSPBUF+2 MOVLW B'00010000' MOVWF DSPBUF+3 MOVLW B'00010000' MOVWF DSPBUF+4 MOVLW B'00010000' MOVWF DSPBUF+5 MOVLW B'00000000' MOVWF DSPBUF+6 MOVLW B'00000000' MOVWF DSPBUF+7 RETURN DSPEQUAL MOVLW B'00000000' MOVWF DSPBUF MOVLW B'00000000' MOVWF DSPBUF+1 MOVLW B'00101000' MOVWF DSPBUF+2 MOVLW B'00101000' MOVWF DSPBUF+3 MOVLW B'00101000' MOVWF DSPBUF+4 MOVLW B'00101000' MOVWF DSPBUF+5 MOVLW B'00000000' MOVWF DSPBUF+6 MOVLW B'00000000' MOVWF DSPBUF+7 RETURN DSPPM MOVLW B'00000100' MOVWF DSPBUF MOVLW B'00000100' MOVWF DSPBUF+1 MOVLW B'00011111' MOVWF DSPBUF+2 MOVLW B'00000100' MOVWF DSPBUF+3 MOVLW B'00100100' MOVWF DSPBUF+4 MOVLW B'00100000' MOVWF DSPBUF+5 MOVLW B'00100000' MOVWF DSPBUF+6 MOVLW B'00100000' MOVWF DSPBUF+7 RETURN ;--------------------------------------------------------------------- ; M系列乱数(1〜255) ;--------------------------------------------------------------------- RANDINT MOVLW B'00101010' MOVWF RNDVAL RETURN RANDOM MOVF RNDVAL,W MOVWF WK1 RRF WK1,F RRF WK1,F XORWF WK1,W RRF WK1,F RRF WK1,F XORWF WK1,W RRF WK1,F RRF WK1,F RRF WK1,F XORWF WK1,F BCF STATUS,C BTFSC WK1,0 BSF STATUS,C RLF RNDVAL,F MOVF RNDVAL,W XORWF TMR0,W RETURN ; ;--------------------------------------------------------------------- ; MESSAGE出力 ;--------------------------------------------------------------------- MESSAGE CLRF MSGPTR CALL MSGTXT ; メッセージ行数(バイト数)取り出し MOVWF MSGCNT INCF MSGCNT,F MSG1 ; ここがH'400'番地になること。 CALL MSGTXT ; メッセージ1行分(1バイト)取り出し MOVWF DSPBUF+8 ; バッファの最後の行に書き込む CALL DSPBUFST ; 表示バッファを1行分シフト CALL WAIT BTFSC FLAG,3 ; SWが押されたら即リターン RETURN DECFSZ MSGCNT,F GOTO MSG1 CALL DSFTCLR ; 画面をシフトクリア RETURN MSGTXT MOVLW H'01' MOVWF PCLATH MOVF MSGPTR,W INCF MSGPTR,F ; 1行進める ADDWF PCL,F ; RETLW D'8' ; メッセージ行数(バイト数) RETLW B'00000000' RETLW B'00000000' RETLW B'00000000' RETLW B'00000000' RETLW B'00000000' RETLW B'00000000' RETLW B'00000000' RETLW B'00000000' ; ;--------------------------------------------------------------------- ; お疲れ様メッセージ ;--------------------------------------------------------------------- MSGFIN CLRF MSGPTR CALL MSGFINT ; メッセージ行数(バイト数)取り出し MOVWF MSGCNT INCF MSGCNT,F MSGFIN1 ; ここがH'400'番地になること。 CALL MSGFINT ; メッセージ1行分(1バイト)取り出し MOVWF DSPBUF+8 ; バッファの最後の行に書き込む CALL DSPBUFST ; 表示バッファを1行分シフト CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN DECFSZ MSGCNT,F GOTO MSGFIN1 CALL DSFTCLR ; 画面をシフトクリア RETURN MSGFINT MOVLW H'02' MOVWF PCLATH MOVF MSGPTR,W INCF MSGPTR,F ; 1行進める ADDWF PCL,F ; RETLW D'31' ; メッセージ行数(バイト数) RETLW B'00111100' RETLW B'01000010' RETLW B'01010010' RETLW B'01110010' RETLW B'00000000' RETLW B'01111000' RETLW B'01001000' RETLW B'01111000' RETLW B'00000000' RETLW B'01111000' RETLW B'01001000' RETLW B'01111000' RETLW B'00000000' RETLW B'01111000' RETLW B'01001000' RETLW B'01111110' RETLW B'00000000' RETLW B'00000000' RETLW B'10000000' RETLW B'11111010' RETLW B'00000000' RETLW B'01111000' RETLW B'01001000' RETLW B'01111000' RETLW B'00000000' RETLW B'01111110' RETLW B'01001000' RETLW B'01111000' RETLW B'00000000' RETLW B'01011110' RETLW B'00000000' ; ;--------------------------------------------------------------------- ; 表示バッファシフト ;--------------------------------------------------------------------- DSPBUFST MOVLW DSPBUF MOVWF FSR ; FSRに表示バッファの先頭アドレスセット MOVLW D'8' MOVWF BUFCNT1 DSPBUFS1 INCF FSR,F MOVF INDF,W ; Wレジに読み込み DECF FSR,F ; FSRをデクリメント MOVWF INDF ; 一行シフトして上書き INCF FSR,F DECFSZ BUFCNT1,F GOTO DSPBUFS1 CLRF INDF ; 最後の行をクリアして戻る RETURN ; ;--------------------------------------------------------------------- ; 表示バッファシフトクリア ;--------------------------------------------------------------------- DSFTCLR MOVLW D'8' MOVWF BUFCNT2 DSFTCLR1 CALL DSPBUFST ; 表示バッファを1行分シフト CALL WAIT01S DECFSZ BUFCNT2,F GOTO DSFTCLR1 RETURN ; ;--------------------------------------------------------------------- ; 表示用バッファクリア ;--------------------------------------------------------------------- CLRDPBUF MOVLW D'8' MOVWF CNT ; 8バイト分のクリア MOVLW DSPBUF ; W ← DSPBUFの先頭アドレス MOVWF FSR ; FSR にアドレスをセット CLRDPBUF2 CLRF INDF ;(FSR)クリア INCF FSR,F ; DECFSZ CNT,F ; GOTO CLRDPBUF2 RETURN ; ;--------------------------------------------------------------------- ; BEEP音 ピッ(38KHzの音を0.1秒) ;--------------------------------------------------------------------- BEEP MOVLW H'80' MOVWF BCNT1 BEEP1 MOVF PORTA,W ;現状のポート状態取り込み ANDLW B'11011111' MOVWF PORTA CALL BWAIT MOVF PORTA,W IORLW B'00100000' MOVWF PORTA CALL BWAIT ; DECFSZ BCNT1,F GOTO BEEP1 RETURN ; BWAIT MOVLW D'38' MOVWF BWCNT1 BWAIT1 DECFSZ BWCNT1,F GOTO BWAIT1 RETURN ; B2WAIT MOVLW H'80' MOVWF BWCNT2 B2WAIT0 MOVLW H'FF' MOVWF BWCNT3 B2WAIT1 DECFSZ BWCNT3,F GOTO B2WAIT1 DECFSZ BWCNT2,F GOTO B2WAIT0 RETURN ; CLICK MOVF PORTA,W ANDLW B'11011111' MOVWF PORTA CALL BWAIT MOVF PORTA,W IORLW B'00100000' MOVWF PORTA RETURN ;--------------------------------------------------------------------- ; Waitルーチン(注)割り込みがあるので時間通りにならない ;--------------------------------------------------------------------- WAIT1MS ;約1msec MOVLW D'250' MOVWF WCNT1 W1MSLP NOP DECFSZ WCNT1,F GOTO W1MSLP RETURN ; WAIT01S ;0.1秒 MOVLW D'97' MOVWF WCNT2 W01SLP CALL WAIT1MS DECFSZ WCNT2,F GOTO W01SLP RETURN ; WAIT05S ;0.5秒 MOVLW D'5' MOVWF WCNT3 W05SLP CALL WAIT01S DECFSZ WCNT3,F GOTO W05SLP RETURN ; WAIT1S ;1秒 MOVLW D'10' MOVWF WCNT3 W1SLP CALL WAIT01S DECFSZ WCNT3,F GOTO W1SLP RETURN ; WAIT CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S RETURN WAIT2 CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S BTFSC FLAG,3 ; SWが押されたら即リターン RETURN CALL WAIT01S RETURN ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------