;--------------------------------------------------------------------- ; ニキシー管時計(IN-1 * 4桁) ; 2009.5.4 ; naka ; 機能など ; ・12時間表示/24時間表示切り替え(デフォルトは12時間表示) ; (電源投入時に時刻設定モードSWを押していると24時間表示に切り替え) ; ・10時の位はゼロサプレス(例:01:23 → 1:23) ; ・コロンは1秒毎に点滅 ; ・瞬断対策として1Fの電気二重層キャパシタでバックアップ(約10分) ; (電源断の間は表示OFF) ; ・デバッグ/デモ用625倍速モード(10分を1秒に圧縮) ; (電源投入時に時刻セットSWを押しているとデバッグモード) ; ;--------------------------------------------------------------------- ; I/Oポート ; (1). RB0〜4 [out] : アノード側(フォトカプラ) ; (2). RA0〜3 [out] : カソード側(KM155ID1) ; (3). RA4 [in] : 時刻セット/ADJUST SW ; (4). RA5 [in] : 時刻設定モードSW ; (5). RA6 [in] : 瞬断検知用(5Vを監視) ;--------------------------------------------------------------------- ;--------------------------------------------------------------------- ; デバイス定義 ;--------------------------------------------------------------------- LIST P=PIC16F648A INCLUDE "P16F648A.INC" __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _EXTCLK_OSC & _MCLRE_OFF & _LVP_OFF ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; 変数レジスタの定義(BANK0) ;--------------------------------------------------------------------- H10DGT EQU 020H ; 10時 H01DGT EQU 021H ; 01時 M10DGT EQU 022H ; 10分 M01DGT EQU 023H ; 01分 SECDIG EQU 024H ; 秒 SECFLG EQU 025H ; 0 : 秒フラグ ; 1 : コロン表示/非表示 ; 2 : デバッグ用60倍速 SECLOW EQU 026H ; 秒カウンタ(下位) SECHIGH EQU 027H ; 秒カウンタ(上位) ; FLAG EQU 028H ; 0 : モードスイッチ ; 1 : セットスイッチ ; 2 : 時刻設定モード(点滅判断) ; 3 : 12H表示/24H表示 ; 4 : 10時設定中 ; 5 : 1時設定中 ; 6 : 10分設定中 ; 7 : 1分設定中 OFFSET EQU 029H ROWCNT EQU 02AH ; ダイナミック表示列カウンタ(0〜3) SMPLCNT EQU 02BH ; チャタリング回避用(割り込み10回:3.2ms) DSPCNT EQU 02CH ; 表示カウンタ(割り込み8回に1度切り替え) BLKCNT EQU 02DH ; 時刻設定モード時の点滅用カウンタ ; BKUPW EQU 060H ; Wレジ待避用 BKUPS EQU 061H ; STATUSレジ待避用 BKUPFR EQU 062H ; FSRレジ待避用 BKUPPCL EQU 063H ; PCLHレジ待避用 ; ; 最後は 07FH ;--------------------------------------------------------------------- ; マクロ定義 ;--------------------------------------------------------------------- BANK0 MACRO BCF STATUS,RP0 ;BANK0に切り替える ENDM BANK1 MACRO BSF STATUS,RP0 ;BANK1に切り替える ENDM ;--------------------------------------------------------------------- ; 割り込みベクタ ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET GOTO START ; ORG 04H ; 割り込み時の飛び込み先 INTER ; GOTO INTRUPT ; ;--------------------------------------------------------------------- ; メイン ;--------------------------------------------------------------------- START CALL INIT ; 初期化 ; BTFSS PORTA,5 ; 時刻設定SWが押されている可能性があるので GOTO $-1 ; 離されるまで待つ BTFSS PORTA,4 ; 時刻セットSWが押されている可能性があるので GOTO $-1 ; 離されるまで待つ BCF FLAG,0 BCF FLAG,1 MAIN BTFSC FLAG,1 ; ADJUSTモード CALL ADJTIME ; BTFSC FLAG,0 ; 時刻設定モード CALL SETTIME ; BTFSS SECFLG,0 ; 秒フラグ確認 GOTO MAIN ; BCF SECFLG,0 ; 秒フラグクリア CALL COUNTUP GOTO MAIN ; ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- INIT BCF INTCON,GIE ;全割込み禁止 ; BANK1 MOVLW B'11110000' MOVWF TRISA ;ポートAは0-3出力、4-7入力 CLRF TRISB ;ポートBは全て出力端子 BANK0 ; BCF INTCON,GIE ; 割り込み禁止 BANK1 ;割り込みタイマーセット MOVLW H'81' ; プリスケーラを4にする MOVWF OPTION_REG ; 3.125KHzで割り込みが入るはず BANK0 ; clock 12.8MHz -> 3.2Mcycle ; 3.2Mcycle/(4*256)=3.125KHz(=320usec毎) ; CLRF ROWCNT ; クリア CLRF SECLOW ; 秒カウンタ(下位)クリア CLRF SECHIGH ; 秒カウンタ(上位)クリア CLRF SECFLG ; 秒フラグクリア CLRF FLAG CLRF BLKCNT CLRF SECDIG MOVLW D'3' MOVWF SMPLCNT ; SW状態のサンプリング間隔(3*320us=約1ms) MOVLW D'8' MOVWF DSPCNT ; CLRF M01DGT CLRF M10DGT BTFSS PORTA,5 ; 電源投入時に時刻設定モードスイッチONなら24時間表示 GOTO MODE24H MODE12H ; 12H表示の時は初期値が12:00 MOVLW D'2' MOVWF H01DGT MOVLW D'1' MOVWF H10DGT GOTO CHKDBG MODE24H ; 24H表示の時は初期値が00:00 CLRF H01DGT CLRF H10DGT BSF FLAG,3 ; 24H表示 ; CHKDBG BTFSS PORTA,4 ; 電源投入時に時刻セットスイッチONなら60倍速モード BSF SECFLG,2 ; BSF INTCON,T0IE ;RTCCマスクイネーブル BSF INTCON,GIE ;割り込み許可 RETURN ; ;--------------------------------------------------------------------- ; 割り込み処理で1秒のカウントと、時刻のダイナミック表示を行う。 ; 3,125回で1秒 ;--------------------------------------------------------------------- INTRUPT ;レジスタ待避 MOVWF BKUPW ; バックアップ(Wレジ) SWAPF STATUS,W ; バックアップ(STATUSレジ) MOVWF BKUPS MOVF FSR,W ; バックアップ(FSRレジ) MOVWF BKUPFR MOVF PCLATH,W ; バックアップ(PCLHレジ) MOVWF BKUPPCL ; BCF INTCON,T0IF ; 割り込みフラグリセット ; ; デバッグモードの1秒カウント(625倍、10分を1秒に圧縮) BTFSS SECFLG,2 GOTO CNT1S INCF SECLOW,F MOVLW D'5' ; 320us*5=1.6ms(625倍速) SUBWF SECLOW,W BTFSS STATUS,Z GOTO END1S GOTO CNT1SEC CNT1S ; ; 1秒カウント ; INCF SECLOW,F BTFSC STATUS,Z INCF SECHIGH,F ; MOVLW D'12' ; 12*256 + 53 = 3125 SUBWF SECHIGH,W ; BTFSS STATUS,Z ; GOTO END1S ; 1秒カウント終わり MOVLW D'53' ; SUBWF SECLOW,W BTFSS STATUS,Z GOTO END1S ; 1秒カウント終わり ; CNT1SEC CLRF SECLOW CLRF SECHIGH BSF SECFLG,0 ; 1秒経ったのでSECFLGセット END1S BTFSC PORTA,6 ; 停電監視 GOTO DISPROW ; 1桁表示 CALL DISPOFF ; 消灯 GOTO INTRTRN ; リターン ; DISPROW MOVF DSPCNT,W SUBLW D'3' BTFSC STATUS,C CLRF PORTB ; 一旦アノード側オフ(320us×2オフ、320us×6オン) ; DECFSZ DSPCNT,F ; 表示切り替えタイミング確認(割り込み8回に1回) GOTO DISPSKP ; 320us * 8 * 4列 = 10.24ms = 約98Hz ; CALL CHKBLNK ; 時刻設定モード時の点滅チェック BTFSS STATUS,Z GOTO SKIPDGT ; この桁は非表示 ; BTFSC FLAG,2 ; 通常表示時(時刻設定モード以外)は、 GOTO DISPDGT ; 10時の位のゼロサプレス MOVF ROWCNT,W SUBLW D'3' BTFSC STATUS,Z MOVF H10DGT,F BTFSC STATUS,Z GOTO SKIPDGT ; ゼロなので非表示 ; DISPDGT CALL SELDGT ; 表示する数字を選択 MOVWF PORTA ; カソード側設定 ; MOVF ROWCNT,W CALL DECBIT BTFSC SECFLG,1 ; コロン表示チェック IORLW B'00010000' ; 表示 MOVWF PORTB ; アノード側設定 ; SKIPDGT INCF ROWCNT,F ; 次回、次の桁を表示するためにインクリメント MOVLW D'4' SUBWF ROWCNT,W BTFSC STATUS,Z CLRF ROWCNT MOVLW D'8' ; 表示用カウンタセット MOVWF DSPCNT DISPSKP ; ; スイッチの状態確認 DECFSZ SMPLCNT,F ; チャタリング回避のためのサンプル時間確認 GOTO INTRTRN ; リターン ; MOVLW D'3' ; 次回のためにカウンタセット MOVWF SMPLCNT ; BCF FLAG,0 ; 時刻設定モードスイッチクリア BTFSS PORTA,5 BSF FLAG,0 ; 時刻設定モードスイッチON ; BCF FLAG,1 ; セット/ADJUSTスイッチクリア BTFSS PORTA,4 BSF FLAG,1 ; セットスイッチON ; INTRTRN ; ;レジスタ復元 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 ; ;--------------------------------------------------------------------- ; Wレジ値をビット位置にデコード ;--------------------------------------------------------------------- DECBIT CLRF PCLATH ; ADDWF PCL,F 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 ; ;--------------------------------------------------------------------- ; ROWCNT値から表示桁を選択 ;--------------------------------------------------------------------- SELDGT BCF STATUS,C RLF ROWCNT,W ; オフセット値(カウンタの2倍) CLRF PCLATH ADDWF PCL,F MOVF M01DGT,W ; 1分 RETURN MOVF M10DGT,W ; 10分 RETURN MOVF H01DGT,W ; 1時 RETURN MOVF H10DGT,W ; 10時 RETURN ; ;--------------------------------------------------------------------- ; 表示OFF ;--------------------------------------------------------------------- DISPOFF CLRF PORTA CLRF PORTB RETURN ;--------------------------------------------------------------------- ; 時刻設定モード時の桁点滅確認 ;--------------------------------------------------------------------- CHKBLNK BTFSS FLAG,2 ; 時刻設定モードなら点滅判断 GOTO CHKON ; INCF BLKCNT,F ; 点滅対象の桁か確認する MOVLW H'FF' BTFSS FLAG,4 GOTO $+2 MOVLW D'3' BTFSS FLAG,5 GOTO $+2 MOVLW D'2' BTFSS FLAG,6 GOTO $+2 MOVLW D'1' BTFSS FLAG,7 GOTO $+2 MOVLW D'0' ; SUBWF ROWCNT,W ; 一致したら対象となる BTFSS STATUS,Z GOTO CHKON ; 点滅対象外なのでオンでリターン ; ; 対象の桁なのでオン/オフか確認する MOVF BLKCNT,W SUBLW D'90' ; 90以下ならオン BTFSS STATUS,C GOTO CHKOFF CHKON BSF STATUS,Z ; オンでリターン RETURN ; CHKOFF MOVF BLKCNT,F SUBLW D'150' BTFSC STATUS,Z CLRF BLKCNT BCF STATUS,Z ; オフでリターン RETURN ; ;--------------------------------------------------------------------- ; 時刻アジャスト(秒を四捨五入:30秒以上なら分繰り上げ) ;--------------------------------------------------------------------- ADJTIME MOVLW D'30' SUBWF SECDIG,W BTFSC STATUS,C CALL CNTUPMIN ; 分をカウントアップ ; CLRF SECLOW ; 秒カウンタ(下位)クリア CLRF SECHIGH ; 秒カウンタ(上位)クリア CLRF SECDIG ; 秒をクリア BCF SECFLG,0 ; 秒フラグクリア ; BTFSC FLAG,1 ; スイッチが離される迄待つ GOTO $-1 ; RETURN ; ;--------------------------------------------------------------------- ; 時刻設定モード(時、分の各桁毎に数字をカウントアップ) ;--------------------------------------------------------------------- SETTIME BSF FLAG,2 ; 時刻設定モード BTFSC FLAG,0 ; モードSWが離されるまで待つ GOTO $-1 ; SET10H BSF FLAG,4 ; 10の位 設定モード(数字が点滅) BTFSC FLAG,1 ; セットスイッチが押された? GOTO INC10H ; BTFSS FLAG,0 ; モードスイッチが押された? GOTO SET10H BCF FLAG,4 BTFSC FLAG,0 ; モードSWが離されるまで待つ GOTO $-1 GOTO SET01H INC10H INCF H10DGT,F CLRF H01DGT ; 1時の桁をクリア MOVLW D'2' BTFSC FLAG,3 ; 12時間/24時間表示でのカウントアップ方法切り替え MOVLW D'3' SUBWF H10DGT,W BTFSC STATUS,Z CLRF H10DGT SET10HE BTFSC FLAG,1 ; 離されるまで待つ GOTO $-1 GOTO SET10H ; SET01H BSF FLAG,5 ; 1の位 設定モード(数字が点滅) BTFSC FLAG,1 ; セットスイッチが押された? GOTO INC01H ; BTFSS FLAG,0 ; モードスイッチが押された? GOTO SET01H BCF FLAG,5 BTFSC FLAG,0 ; モードSWが離されるまで待つ GOTO $-1 GOTO SET10M ; INC01H INCF H01DGT,F ; BTFSC FLAG,3 ; 12時間/24時間表示でのカウントアップ方法切り替え GOTO M24H M12H MOVF H10DGT,F BTFSC STATUS,Z GOTO SET01HC ; 10時の桁が0なら通常インクリメントチェック MOVLW D'3' ; 10時の桁が1のときは2迄 SUBWF H01DGT,W BTFSS STATUS,Z GOTO SET01HE CLRF H01DGT GOTO SET01HE M24H BTFSS H10DGT,1 GOTO SET01HC ; 10時の桁が0,1(!=2)なら通常インクリメントチェック MOVLW D'4' ; それ以外のときは3迄 SUBWF H01DGT,W BTFSS STATUS,Z GOTO SET01HE CLRF H01DGT GOTO SET01HE SET01HC MOVLW D'10' SUBWF H01DGT,W BTFSC STATUS,Z CLRF H01DGT SET01HE BTFSC FLAG,1 ; 離されるまで待つ GOTO $-1 GOTO SET01H ; SET10M BSF FLAG,6 ; 1の位 設定モード(数字が点滅) BTFSC FLAG,1 ; セットスイッチが押された? GOTO INC10M ; BTFSS FLAG,0 ; モードスイッチが押された? GOTO SET10M BCF FLAG,6 BTFSC FLAG,0 ; モードSWが離されるまで待つ GOTO $-1 GOTO SET01M ; INC10M INCF M10DGT,F MOVLW D'6' SUBWF M10DGT,W BTFSC STATUS,Z CLRF M10DGT ; BTFSC FLAG,1 ; 離されるまで待つ GOTO $-1 GOTO SET10M ; SET01M BSF FLAG,7 ; 1の位 設定モード(数字が点滅) BTFSC FLAG,1 ; セットスイッチが押された? GOTO INC01M ; BTFSS FLAG,0 ; モードスイッチが押された? GOTO SET01M BCF FLAG,7 BTFSC FLAG,0 ; モードスイッチが離されたらモード終わり GOTO $-1 GOTO SETEND INC01M INCF M01DGT,F MOVLW D'10' SUBWF M01DGT,W BTFSC STATUS,Z CLRF M01DGT ; BTFSC FLAG,1 ; 離されるまで待つ GOTO $-1 GOTO SET01M ; SETEND BCF FLAG,2 ; 時刻設定モード終了 CLRF SECLOW ; 秒カウンタ(下位)クリア CLRF SECHIGH ; 秒カウンタ(上位)クリア CLRF SECDIG ; 秒をクリア BCF SECFLG,0 ; 秒フラグクリア RETURN ; ;--------------------------------------------------------------------- ; 時刻カウントアップ ;--------------------------------------------------------------------- COUNTUP CALL TGLCOL ; :(コロン)表示をトグル ; INCF SECDIG,F ; 秒カウントアップ MOVLW D'60' SUBWF SECDIG,W BTFSS STATUS,Z RETURN CLRF SECDIG ; 秒クリア ; CNTUPMIN INCF M01DGT,F ; 分(1の位)カウントアップ MOVLW D'10' SUBWF M01DGT,W BTFSS STATUS,Z RETURN CLRF M01DGT ; INCF M10DGT,F ; 分(10の位)カウントアップ MOVLW D'6' SUBWF M10DGT,W BTFSS STATUS,Z RETURN CLRF M10DGT ; INCF H01DGT,F ; 時(1の位)カウントアップ MOVLW D'10' SUBWF H01DGT,W BTFSC STATUS,Z GOTO H10UP ; ; 12時間/24時間表示でのカウントアップ方法切り替え BTFSC FLAG,3 GOTO CNTUP24 CNTUP12 ; 12時間表示のカウントアップ MOVLW D'3' ; 13時のチェック SUBWF H01DGT,W BTFSS STATUS,Z RETURN MOVLW D'1' SUBWF H10DGT,W BTFSS STATUS,Z RETURN MOVLW D'1' MOVWF H01DGT CLRF H10DGT RETURN ; CNTUP24 ; 24時間表示のカウントアップ MOVLW D'4' ; 24時のチェック SUBWF H01DGT,W BTFSS STATUS,Z RETURN MOVLW D'2' SUBWF H10DGT,W BTFSS STATUS,Z RETURN CLRF H01DGT CLRF H10DGT RETURN H10UP CLRF H01DGT INCF H10DGT,F ; 時(10の位)カウントアップ RETURN ; ;--------------------------------------------------------------------- ; :(コロン)の表示/非表示(呼び出すたびにトグルする) ;--------------------------------------------------------------------- TGLCOL BTFSS SECFLG,1 GOTO $+3 BCF SECFLG,1 ; 表示中ならオフ RETURN BSF SECFLG,1 ; 非表示中ならオン RETURN ; ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------