;--------------------------------------------------------------------- ; インターバルタイマー V2 ; 2014.11.8 naka ; 2013.6.2 naka ; I/Oポート ; (1). 出力ポート ; RC5: ソリッドステートリレーのLED、および通電モニタLEDに繋ぐ ; (2). 入力ポート ; RC2: 設定SW(SET) 設定スイッチ ; RC3: 設定SW(SHIFT) LCDカラムシフトスイッチ ; RC4: 設定SW(INC) LCDインクリメントスイッチ ; RA2: 強制ONスイッチ (V2で追加) ; (3). I2C(LCD接続) ; SCL(RC0), SDA(RC1) ; (4). OSCポート(X'TAL) ; OSC1(RA5),OSC2(RA4) 4MHz X'Tal ; (5). Program ; ICSPDAT(RA0), ICSPCLK(RA1) ; VPP(RA3) ; ; 機能 ; 設定した時間だけONし、設定した時間だけOFFになることを ; 繰り返す間欠タイマー ; ; ↓電源投入 ; ______ ______ ; | |___________| |___________| … ; ON OFF ON OFF ; ; 例1)1日に1時間だけ通電する設定 ; ON時間:1時間、OFF時間:23時間 ; ; 例2)半日ごとに10分だけ通電する設定 ; ON時間:10分、OFF時間:11時間50分 ; ; 例3)1時間に10秒だけ通電する設定 ; ON時間:10秒、OFF時間:59分50秒 ; ; 例4)イルミネーションのように1秒ごとにON/OFFする設定 ; ON時間:1秒、OFF時間:1秒 ; ; 強制ONの動作 ; ; ↓電源投入(インターバルタイマ動作) ; ______ ______ ; | |___________| |___________| … ; ON OFF ON OFF ; ; 強制ON ____________ ; ___________| |______________ … ; ; 出力(通電) ; ______ ______________ ; | |___| |___________| … ; ON OFF ON OFF ; ; ; 動作 ; (1) 電源を入れると、スプラッシュを表示後、(2)に遷移する ; (2) 通電ONモード ; 通電ONし、設定済みのON時間をカウントダウンしてゼロになったら(3)に遷移する ; (3) 通電OFFモード ; 通電OFFにし、設定済みのOFF時間をカウントダウンしてゼロになったら(2)に戻る ; (4) 動作中(通電ON/OFF時)、SETスイッチを長押しすると時間設定モード(5)に遷移する ; (5) 時間設定モード ; ・SHIFTスイッチで設定する桁を移動し、INCスイッチで数字をインクリメントする。 ; ・SETスイッチを押すと設定を完了し、(2)に遷移する ; ・SETスイッチを長押しするとコントラスト設定モード(6)に遷移する。 ; ・時間設定モード中は通電しない。 ; (6) コントラスト設定モード ; ・SHIFTスイッチでコントラストダウン、 ; INCスイッチでコントラストアップする。 ; ・SETスイッチを押すとコントラスト設定を完了し、(2)に遷移する。 ; ・コントラスト設定モード中は通電しない。 ; (7) 特殊処理 ; ・ON時間・OFF時間ともにゼロの場合には通電しない。 ; ・ON時間が1秒以上で、OFF時間がゼロの場合は、通電し続ける。 ; ・ON時間がゼロで、OFF時間が1秒以上の場合は、通電しない。 ; (8) 強制ON ; 上記のタイムチャートのように強制的に通電ONとなる。 ; ; 改版履歴 ; 2014.11 ・外付けスイッチで強制ONができるように変更 ; スイッチはRA2に接続(抵抗でプルアップしておき、SW-ONでGNDに落ちるactive low ; 強制ONの間もインターバルタイマとして時間カウント/通電動作は継続 ; ;--------------------------------------------------------------------- LIST P=PIC16F1823 INCLUDE "P16F1823.INC" __CONFIG _CONFIG1, _CPD_OFF & _CP_OFF & _BOREN_ON & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _FOSC_XT & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _LVP_OFF ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; 変数レジスタの定義 ;--------------------------------------------------------------------- SEC64CNT EQU 20H ; 64秒をカウント(1秒の補正のため) SECCNT EQU 21H ; 1秒を数えるカウンタ(244で1秒;但し64秒毎に253) HOUR EQU 22H ; 時 MIN EQU 23H ; 分 SEC EQU 24H ; 秒 CNT EQU 25H ; カウンタ CNT1 EQU 26H ; WAIT用カウンタ CNT2 EQU 27H ; WAIT用カウンタ TMP EQU 28H ; 一時作業用 SECFLG EQU 29H ; 0:秒フラグ, 1:タイムアウト SWFLG EQU 2AH ; スイッチ状態フラグ ; 0:モード設定, 1:SHIFT, 2:INC SWLCNT EQU 2BH ; SW長押しカウンタ CURADDR EQU 2CH ; LCDカーソル位置(0-15) COLCNT EQU 2DH ; LCDカーソルカウンタ(0-11;数字部のみカウント) CURTMP EQU 2EH ; LCDカーソル位置一時保管 ONHOUR EQU 30H ; ON時間(時) -+ ONMIN EQU 31H ; ON時間(分) | ONSEC EQU 32H ; ON時間(秒) | OFFHOUR EQU 33H ; OFF時間(時) | EEPROM読み書きのため、連続領域のこと OFFMIN EQU 34H ; OFF時間(分) | OFFSEC EQU 35H ; OFF時間(秒) | CNTRST EQU 36H ; コントラスト -+ FORCEON EQU 37H ; 強制ONスイッチフラグ 0:フラグ ONOFFST EQU 38H ; インターバルタイマとしてのON/OFF状態フラグ 0:フラグ ; このフラグと強制ONフラグの"OR"でSSRをONする LCDBUF1 EQU 40H ; LCDバッファ1行目(8バイト) LCDBUF2 EQU 48H ; LCDバッファ2行目(8バイト) ;-------------------------------------------------------------------------- ; binariy to BCD変換用 ;-------------------------------------------------------------------------- bin EQU 50H hundreds EQU 51H tens_and_ones EQU 52H ;-------------------------------------------------------------------------- ; EEPROM ;-------------------------------------------------------------------------- DATA_EE_ADDR EQU 70H ; どのバンクからも読み書きできる領域 DATA_EE_DATA EQU 71H ; ORG H'F000' ; EEPROM byte address=1E000 -> word addr=F000 DE D'00' ; オン 時 DE D'00' ; オン 分 DE D'05' ; オン 秒 DE D'00' ; オフ 時 DE D'00' ; オフ 分 DE D'05' ; オフ 秒 DE D'32' ; コントラスト(0-63の真ん中;電源電圧やLCDモジュールの個体差に依存) ;--------------------------------------------------------------------- ; リセット・割り込み ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET1 GOTO MAIN ; 初期設定へ ; ;--------------------------------------------------------------------- ; 割り込み処理(4.096ms毎)で時間をカウント ;--------------------------------------------------------------------- ORG 04H ; 割り込み時の飛び込み先 INTRUPT BTFSS INTCON,TMR0IF ; Timer0割り込みか? RETFIE ; 違えば即リターン ; BCF INTCON,TMR0IF ;割り込みフラグリセット ; INCF SECCNT,F ; 秒をカウント ; MOVF SEC64CNT,W SUBLW D'63' BTFSC STATUS,Z GOTO CNT253 CNT244 MOVF SECCNT,W SUBLW D'244' ; 4.096ms x 244 = 0.999424sec BTFSS STATUS,Z ; 補正するには64秒毎に244ではなく、 ; 253(244+9)カウントする(CNT253のラベル) GOTO CHKSWPORT GOTO CNT1SEC CNT253 MOVF SECCNT,W SUBLW D'253' ; 4.096ms x 244 = 0.999424sec BTFSS STATUS,Z ; 補正するには64秒毎に244ではなく、 ; 253(244+9)カウントする GOTO CHKSWPORT CLRF SEC64CNT ; 64秒カウンタクリア DECF SEC64CNT,F ; 2行下でincするのでdecしておく CNT1SEC CLRF SECCNT INCF SEC64CNT,F ; 補正のための回数カウント ; BSF SECFLG,0 ; 秒フラグセット ; CHKSWPORT ; SWの状態チェック CLRF SWFLG BTFSS PORTC,2 ; mode BSF SWFLG,0 BTFSS PORTC,3 ; shift BSF SWFLG,1 BTFSS PORTC,4 ; inc BSF SWFLG,2 CLRF FORCEON BTFSS PORTA,2 ; 強制ON BSF FORCEON,0 ; MOVF ONOFFST,W ; インターバルタイマのON/OFF状態 IORWF FORCEON,W ; 両フラグのORでSSR ON/OFF制御 BTFSS STATUS,Z GOTO SSRON_L CALL SSROFF ; OR結果が0なのでSSR OFF GOTO $+2 SSRON_L CALL SSRON ; OR結果が1なのでSSR ON ; INCF SWLCNT,F ; スイッチ長押しカウンタ ; RETFIE ;割り込みから復帰 ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- INIT BCF INTCON,GIE ;全割込み禁止 ; BANKSEL LATC CLRF LATA CLRF LATC BANKSEL ANSELA CLRF ANSELA ; デジタルI/O CLRF ANSELC ; デジタルI/O BANKSEL TRISC ; MOVLW H'83' ;プリスケーラを1:16にする MOVWF OPTION_REG ;約244ヘルツ(約4ms)で割り込みが入るはず ;clock4MHz -> 1Mcycle ;1Mcycle/256/16 = 244Hz ;244回の割り込みで約1秒弱 MOVLW B'00011111' MOVWF TRISC ; RC0:SCL, RC1:SDA, RC2:mode, RC3:sft, RC4:inc MOVLW B'00000100' MOVWF TRISA ; RA2:強制ONスイッチ ; BANKSEL PORTC MOVLW H'FF' MOVWF PORTC ; CLRF SEC64CNT CLRF SECCNT CLRF SEC CLRF MIN CLRF HOUR CLRF SECFLG CLRF SWFLG CLRF SWLCNT CLRF ONOFFST ; BSF INTCON,TMR0IE BSF INTCON,GIE ; 割り込み許可 ; RETURN ;--------------------------------------------------------------------- ; メイン処理 ;--------------------------------------------------------------------- MAIN CALL INIT ; 初期化 CALL LDSETTING ; EEPROMセッティング情報読み込み ; CALL I2CINIT ; I2C初期化 CALL LCDINIT ; LCD初期化 ; CALL BOOTSPLASH ; ブートスプラッシュ CALL CLRSECCNT ; 秒カウンタクリア BTFSS SECFLG,0 ; 1秒待ち GOTO $-1 MAIN_INI CALL SETONTIM CALL LCDONTIM CALL LCDONDSP ; CALL SETOFFTIM CALL LCDOFFTIM CALL LCDOFFDSP BCF SECFLG,1 CALL CLRSECCNT ; 秒カウンタクリア ; ;--------------------------------------------------- ; オン時間カウントダウン ;--------------------------------------------------- ONCOUNT_S CALL CHKSW1R ; MODEスイッチが押され、長押しされた BTFSC STATUS,Z ; Z=1 長押し GOTO SETTING ; 時間設定モードへ ; CALL SETONTIM ; ON時間設定(カウントダウン用) CALL CHKTIMZERO ; ON時間が0ならオフ時間カウントダウンへ BTFSC STATUS,Z GOTO OFFCOUNT_S CALL STATUSON ; ソリッドステートリレー、オン ONCOUNT_LP CALL CHKSW1P ; MODEスイッチが押された BTFSS STATUS,Z GOTO ONCOUNT_1 CALL CHKSW1R ; 離される BTFSC STATUS,Z ; Z=1 長押し GOTO SETTING ; 時間設定モードへ ; ONCOUNT_1 BTFSS SECFLG,0 GOTO ONCOUNT_LP ; BTFSC SECFLG,1 ; タイムアウト1秒後に CALL LCDOFFDSP ; 改めてOFF時間を表示 ; CALL DECTIM ; カウントダウン CALL LCDONTIM ; LCDに表示 CALL LCDONDSP BTFSS SECFLG,1 ; タイムアウト確認 GOTO ONCOUNT_LP ;--------------------------------------------------- ; オフ時間カウントダウン ;--------------------------------------------------- OFFCOUNT_S CALL SETONTIM CALL LCDONTIM ; CALL SETOFFTIM ; OFF時間設定(カウントダウン用) CALL CHKTIMZERO ; OFF時間が0ならオン時間カウントダウンへ BTFSC STATUS,Z GOTO ONCOUNT_S CALL STATUSOFF ; ソリッドステートリレー、オフ OFFCOUNT_LP CALL CHKSW1P ; MODEスイッチが押された BTFSS STATUS,Z GOTO OFFCOUNT_1 CALL CHKSW1R ; 離される BTFSC STATUS,Z ; Z=1 長押し GOTO SETTING ; 時間設定モードへ ; OFFCOUNT_1 BTFSS SECFLG,0 GOTO OFFCOUNT_LP ; BTFSC SECFLG,1 ; タイムアウト1秒後に CALL LCDONDSP ; 改めてON時間を表示 ; CALL DECTIM ; カウントダウン CALL LCDOFFTIM ; LCDに表示 CALL LCDOFFDSP BTFSS SECFLG,1 ; タイムアウト確認 GOTO OFFCOUNT_LP ; タイムアウト CALL SETOFFTIM CALL LCDOFFTIM GOTO ONCOUNT_S ;--------------------------------------------------- ; 時間設定モード ;--------------------------------------------------- SETTING CALL STATUSOFF ; ソリッドステートリレー、オフ CALL SETONTIM ; 現在の設定時間表示 CALL LCDONTIM CALL LCDONDSP ; CALL SETOFFTIM CALL LCDOFFTIM CALL LCDOFFDSP ; CLRF COLCNT ; カーソルカウンタ CALL CURMOV ; カーソル移動 CALL CURON ; カーソル表示モード ; BTFSC SWFLG,0 GOTO $-1 ; 長押しが離されるまで待つ ; SETTING_LP CALL CHKSW2P BTFSC STATUS,Z CALL CURSFT ; 設定カラムの移動 ; CALL CHKSW3P BTFSC STATUS,Z CALL SETINC ; カラム位置の数字インクリメント ; CALL CHKSW1P ; mode SWが押されるのを確認 BTFSS STATUS,Z GOTO SETTING_LP ; CALL CUROFF CALL STR2BIN ; 文字を時間に反映 ; CALL CHKSW1R ; mode SWが離されるのを待つ BTFSS STATUS,Z ; 長押しならコントラスト設定へ GOTO SAVESET ; そうでなければ、設定情報をEEPROMに保存 ;--------------------------------------------------- ; コントラスト設定モード ;--------------------------------------------------- CNSTMODE CALL CNSTDSP ; Contrast Setting 文字列表示 BTFSC SWFLG,0 GOTO $-1 ; 長押しが離されるまで待つ ; CNSTMODEL CALL CHKSW2P BTFSS STATUS,Z GOTO CNSTMODE1 CALL LCDCNTDWN CALL CHKSW2R CNSTMODE1 CALL CHKSW3P BTFSS STATUS,Z GOTO CNSTMODE2 CALL LCDCNTUP CALL CHKSW3R CNSTMODE2 CALL CHKSW1P ; mode SWが押されるのを待つ BTFSS STATUS,Z GOTO CNSTMODEL ; BTFSS SWFLG,0 ; mode SWが離されるのを待つ GOTO $-1 ; ;--------------------------------------------------- ; 設定情報の保存 ;--------------------------------------------------- SAVESET CALL SVSETTING ; 設定情報保存 GOTO MAIN_INI ; ;--------------------------------------------------------------------- ; 秒カウンタクリア ;--------------------------------------------------------------------- CLRSECCNT CLRF SEC64CNT CLRF SECCNT BCF SECFLG,0 RETURN ;--------------------------------------------------------------------- ; オン時間/オフ時間のチェック ;--------------------------------------------------------------------- CHKTIMZERO MOVF HOUR,F BTFSS STATUS,Z RETURN ; Z=0 MOVF MIN,F BTFSS STATUS,Z RETURN ; Z=0 MOVF SEC,F RETURN ; Z=0/1 ;--------------------------------------------------------------------- ; スイッチ状態チェック ;--------------------------------------------------------------------- CHKSW1P ; mode SWが押されたかチェック BCF STATUS,Z BTFSS SWFLG,0 RETURN BSF STATUS,Z CLRF SWLCNT ; 長押しカウンタ RETURN ; CHKSW2P ; shift SWが押されたかチェック BCF STATUS,Z BTFSS SWFLG,1 RETURN BSF STATUS,Z RETURN ; CHKSW3P ; inc SWが押されたかチェック BCF STATUS,Z BTFSS SWFLG,2 RETURN BSF STATUS,Z RETURN ; CHKSW1R ; mode SWが離されたことをチェック Z=1 長押し BCF STATUS,Z ; Zクリア BTFSS SWFLG,0 ; mode SWチェック RETURN ; 離された ; CALL CHKSWL ; 長押しチェック BTFSS STATUS,Z GOTO CHKSW1R RETURN ; 長押し ; CHKSW2R ; shift SWが離されたことをチェック BTFSC SWFLG,1 GOTO CHKSW2R RETURN ; CHKSW3R ; inc SWが離されたことをチェック BTFSC SWFLG,2 GOTO CHKSW3R RETURN ; CHKSWL MOVF SWLCNT,W SUBLW D'130' ; 4ms * 130 = 520ms で長押し判定 RETURN ; Z=1 長押し ; ;--------------------------------------------------------------------- ; LCDカーソル表示 ; ; COLCNT=0〜11 ; ; 01:23:45 ; ; 67:89:AB ;--------------------------------------------------------------------- CURMOV CALL CNVCOLDT MOVWF CURADDR BTFSC CURADDR,3 ; 8以上ならLCD 2行目 ADDLW H'40' - H'08' ADDLW H'80' ; LCD位置コマンド CALL LCDCMD RETURN CNVCOLDT CLRF PCLATH MOVF COLCNT,W ADDWF PCL,F RETLW D'0' RETLW D'1' RETLW D'3' RETLW D'4' RETLW D'6' RETLW D'7' RETLW D'8' RETLW D'9' RETLW D'11' RETLW D'12' RETLW D'14' RETLW D'15' ;--------------------------------------------------------------------- ; 設定情報(オン/オフ時分秒、コントラスト)の読み出し ;--------------------------------------------------------------------- LDSETTING MOVLW H'00' ; 先頭アドレス MOVWF DATA_EE_ADDR MOVLW HIGH ONHOUR ; 読み込みデータ先頭 MOVWF FSR1H MOVLW LOW ONHOUR MOVWF FSR1L ; MOVLW D'7' ; オン時分秒、オフ時分秒、コントラスト MOVWF CNT LDSETL CALL RDEEPROM ; EEPROM読み出し MOVWF INDF1 INCF DATA_EE_ADDR,F ADDFSR FSR1,1 DECFSZ CNT,F GOTO LDSETL RETURN ; ;--------------------------------------------------------------------- ; 設定情報(オン/オフ時分秒、コントラスト)のEEPROM格納 ;--------------------------------------------------------------------- SVSETTING MOVLW H'00' ; EEPROM先頭アドレス MOVWF DATA_EE_ADDR MOVLW HIGH ONHOUR ; 書き込みデータ先頭 MOVWF FSR1H MOVLW LOW ONHOUR MOVWF FSR1L ; MOVLW D'7' ; オン時分秒、オフ時分秒、コントラスト MOVWF CNT SVSETL MOVF INDF1,W MOVWF DATA_EE_DATA CALL WRTEEPROM ; EEPROM書き込み INCF DATA_EE_ADDR,F ADDFSR FSR1,1 DECFSZ CNT,F GOTO SVSETL RETURN ; ;--------------------------------------------------------------------- ; カーソル位置の数字のインクリメント ;--------------------------------------------------------------------- SETINC MOVF CURADDR,W ADDLW LOW LCDBUF1 MOVWF FSR1L MOVLW HIGH LCDBUF1 MOVWF FSR1H ; INCF INDF1,F ; MOVF CURADDR,W SUBLW D'3' BTFSC STATUS,Z GOTO SETINC1 ; MOVF CURADDR,W SUBLW D'6' BTFSC STATUS,Z GOTO SETINC1 ; MOVF CURADDR,W SUBLW D'11' BTFSC STATUS,Z GOTO SETINC1 ; MOVF CURADDR,W SUBLW D'14' BTFSS STATUS,Z GOTO SETINC2 ; SETINC1 MOVF INDF1,W SUBLW H'36' ; 10分、10秒の位は最大5まで(CURADDR=3,6,11,14) BTFSC STATUS,Z GOTO SETINC3 GOTO SETINC4 SETINC2 MOVF INDF1,W SUBLW H'3A' ; 最大9まで BTFSS STATUS,Z GOTO SETINC4 SETINC3 MOVLW H'30' MOVWF INDF1 SETINC4 MOVF CURADDR,W BTFSC CURADDR,3 ; 8以上ならLCD 2行目 ADDLW H'40' - H'08' ADDLW H'80' ; LCD位置コマンド MOVWF CURTMP CALL LCDCMD ; MOVF INDF1,W CALL LCDDATA ; MOVF CURTMP,W ; カーソルを戻す CALL LCDCMD ; CALL CHKSW3R ; INC SWが離されるまで待つ RETURN ;--------------------------------------------------------------------- ; カーソル移動 ;--------------------------------------------------------------------- CURSFT INCF COLCNT,F MOVF COLCNT,W SUBLW D'12' BTFSC STATUS,Z CLRF COLCNT CALL CURMOV ; CALL CHKSW2R ; シフトSWが離されるまで待つ RETURN ;--------------------------------------------------------------------- ; コントラスト文字列表示 ;--------------------------------------------------------------------- CNSTDSP MOVLW D'16' MOVWF CNT CLRF TMP ; MOVLW HIGH LCDBUF1 MOVWF FSR1H MOVLW LOW LCDBUF1 MOVWF FSR1L CNSTDSPL CALL CNSTDSPDT MOVWF INDF1 ADDFSR FSR1,1 INCF TMP,F DECFSZ CNT,F GOTO CNSTDSPL ; CALL LCDONDSP ; LCDへ表示 CALL LCDOFFDSP ; LCDへ表示(2行目) RETURN CNSTDSPDT MOVLW H'01' MOVWF PCLATH MOVF TMP,W ADDWF PCL,F RETLW 'C' RETLW 'o' RETLW 'n' RETLW 't' RETLW 'r' RETLW 'a' RETLW 's' RETLW 't' RETLW ' ' RETLW 'S' RETLW 'e' RETLW 't' RETLW 't' RETLW 'i' RETLW 'n' RETLW 'g' ;--------------------------------------------------------------------- ; Interval Timer文字列表示 ;--------------------------------------------------------------------- BOOTSPLASH MOVLW D'16' MOVWF CNT CLRF TMP ; MOVLW HIGH LCDBUF1 MOVWF FSR1H MOVLW LOW LCDBUF1 MOVWF FSR1L BOOTSPLASHL CALL BOOTSPLASHDT MOVWF INDF1 ADDFSR FSR1,1 INCF TMP,F DECFSZ CNT,F GOTO BOOTSPLASHL ; CALL LCDONDSP ; LCDへ表示 CALL LCDOFFDSP ; LCDへ表示(2行目) RETURN BOOTSPLASHDT MOVLW H'01' MOVWF PCLATH MOVF TMP,W ADDWF PCL,F RETLW 'I' RETLW 'n' RETLW 't' RETLW 'e' RETLW 'r' RETLW 'v' RETLW 'a' RETLW 'l' RETLW ' ' RETLW ' ' RETLW ' ' RETLW 'T' RETLW 'i' RETLW 'm' RETLW 'e' RETLW 'r' ;--------------------------------------------------------------------- ; コントラスト設定 ;--------------------------------------------------------------------- LCDCNTUP MOVF CNTRST,W SUBLW D'63' BTFSS STATUS,Z INCF CNTRST,F MOVF CNTRST,W MOVWF CNTRST CALL LCDCNTRST RETURN LCDCNTDWN MOVF CNTRST,F BTFSS STATUS,Z DECF CNTRST,F MOVF CNTRST,W MOVWF CNTRST CALL LCDCNTRST RETURN LCDCNTRST MOVLW H'39' CALL LCDCMD MOVF CNTRST,W ANDLW H'0F' ; 下位4ビット IORLW H'70' CALL LCDCMD SWAPF CNTRST,W ANDLW H'03' ; 上位2ビット IORLW H'54' CALL LCDCMD MOVLW H'38' CALL LCDCMD RETURN ;--------------------------------------------------------------------- ; 文字列→数値変換(LCDBUFの文字を数値に変換)2桁×3(時分秒)×2行 ;--------------------------------------------------------------------- STR2BIN MOVLW LOW LCDBUF1 MOVWF FSR1L MOVLW HIGH LCDBUF1 MOVWF FSR1H ; LCD 1行目 CALL CHR2BIN MOVWF ONHOUR ADDFSR FSR1,1 ; ':'スキップ CALL CHR2BIN MOVWF ONMIN ADDFSR FSR1,1 ; ':'スキップ CALL CHR2BIN MOVWF ONSEC ; ; LCD 2行目 CALL CHR2BIN MOVWF OFFHOUR ADDFSR FSR1,1 ; ':'スキップ CALL CHR2BIN MOVWF OFFMIN ADDFSR FSR1,1 ; ':'スキップ CALL CHR2BIN MOVWF OFFSEC ; CHR2BIN MOVIW INDF1++ ANDLW H'0F' ; 文字コードを数値に変換 MOVWF TMP LSLF TMP,F ; 2倍 MOVF TMP,W ; Wレジに保管 LSLF TMP,F ; 4倍 LSLF TMP,F ; 8倍 ADDWF TMP,F ; 10倍 MOVIW INDF1++ ANDLW H'0F' ; 文字コードを数値に変換 ADDWF TMP,W ; 1の位を足す RETURN ;--------------------------------------------------------------------- ; カーソル表示/非表示 ;--------------------------------------------------------------------- CURON MOVLW H'0C' + H'03' ; Display ON/OFF control CALL LCDCMD RETURN ; CUROFF MOVLW H'0C' + H'00' ; Display ON/OFF control CALL LCDCMD RETURN ;--------------------------------------------------------------------- ; インターバル ON/OFF 状態フラグ ;--------------------------------------------------------------------- STATUSON BSF ONOFFST,0 RETURN STATUSOFF BCF ONOFFST,0 RETURN ;--------------------------------------------------------------------- ; SSR ON/OFF ;--------------------------------------------------------------------- SSRON MOVLW B'00000000' MOVWF PORTC RETURN SSROFF MOVLW B'00100000' MOVWF PORTC RETURN ;--------------------------------------------------------------------- ; 設定時間をカウントダウン用時分秒へコピー ;--------------------------------------------------------------------- SETONTIM MOVF ONHOUR,W MOVWF HOUR MOVF ONMIN,W MOVWF MIN MOVF ONSEC,W MOVWF SEC RETURN ; SETOFFTIM MOVF OFFHOUR,W MOVWF HOUR MOVF OFFMIN,W MOVWF MIN MOVF OFFSEC,W MOVWF SEC RETURN ; ;--------------------------------------------------------------------- ; 秒分時のカウントダウン ;--------------------------------------------------------------------- DECTIM BCF SECFLG,0 ; 1秒フラグクリア ; DECF SEC,F MOVF SEC,W BTFSS STATUS,Z ; 00秒 GOTO DECTIM2 MOVF MIN,W BTFSS STATUS,Z ; 00分 GOTO DECTIM2 MOVF HOUR,W BTFSS STATUS,Z ; 00時 GOTO DECTIM2 ; BSF SECFLG,1 ; Timeout RETURN ; DECTIM2 MOVF SEC,W SUBLW D'255' BTFSS STATUS,Z GOTO DECTIM3 MOVLW D'59' MOVWF SEC DECF MIN,F DECTIM3 MOVF MIN,W SUBLW D'255' BTFSS STATUS,Z GOTO DECTIM4 MOVLW D'59' MOVWF MIN DECF HOUR,F DECTIM4 BCF SECFLG,1 RETURN ;--------------------------------------------------------------------- ; LCDにON時間を表示 ;--------------------------------------------------------------------- LCDONTIM MOVLW D'0' MOVWF CURADDR MOVF HOUR,W CALL BIN2LCD ; MOVLW ':' MOVWF LCDBUF1+D'2' ; MOVLW D'3' MOVWF CURADDR MOVF MIN,W CALL BIN2LCD ; MOVLW ':' MOVWF LCDBUF1+D'5' ; MOVLW D'6' MOVWF CURADDR MOVF SEC,W CALL BIN2LCD RETURN ; LCDONDSP MOVLW H'80' + H'00' ; 1行目先頭へ CALL LCDCMD ; MOVLW D'8' MOVWF CNT MOVLW LOW LCDBUF1 MOVWF FSR1L MOVLW HIGH LCDBUF1 MOVWF FSR1H ; LCDONTIM2 MOVF INDF1,W CALL LCDDATA ADDFSR FSR1,1 DECFSZ CNT,F GOTO LCDONTIM2 ; RETURN ;--------------------------------------------------------------------- ; LCDにOFF時間を表示 ;--------------------------------------------------------------------- LCDOFFTIM MOVLW D'8' MOVWF CURADDR MOVF HOUR,W CALL BIN2LCD ; LCDBUF2に格納 ; MOVLW ':' MOVWF LCDBUF1+D'10' ; MOVLW D'11' MOVWF CURADDR MOVF MIN,W CALL BIN2LCD ; LCDBUF2に格納 ; MOVLW ':' MOVWF LCDBUF1+D'13' ; MOVLW D'14' MOVWF CURADDR MOVF SEC,W CALL BIN2LCD ; LCDBUF2に格納 RETURN ; LCDOFFDSP MOVLW H'80' + H'40' ; LCD2行目先頭へ CALL LCDCMD ; MOVLW D'8' ; LCDBUF2の8バイトをLCDへ転送 MOVWF CNT MOVLW LOW LCDBUF2 MOVWF FSR1L MOVLW HIGH LCDBUF2 MOVWF FSR1H ; LCDOFFTIM2 MOVF INDF1,W CALL LCDDATA ADDFSR FSR1,1 DECFSZ CNT,F GOTO LCDOFFTIM2 ; RETURN ;--------------------------------------------------------------------- ; バイナリ値を2桁の文字に変換しLCDBUFに格納 ; w : バイナリ値 ; CURADDR : LCDの桁番号 ; ; CURADDR=01234567 ; | | ; LCD1行目 00:00:00 ; LCD2行目 00:00:00 ; | | ; 89ABCDEF ;--------------------------------------------------------------------- BIN2LCD MOVWF bin CALL binary_to_bcd ; MOVLW LOW LCDBUF1 ADDWF CURADDR,W MOVWF FSR1L MOVLW HIGH LCDBUF1 MOVWF FSR1H ; SWAPF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF INDF1 ; 1桁目 ; MOVF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 ADDFSR FSR1,1 MOVWF INDF1 ; 2桁目 RETURN ; ;--------------------------------------------------------------------- ; EEPROM読み出し ;--------------------------------------------------------------------- RDEEPROM BANKSEL EEADRL; MOVF LOW DATA_EE_ADDR,W ; MOVWF EEADRL ; Data Memory ; Address to read BCF EECON1,CFGS ; Deselect Config space BCF EECON1,EEPGD ; Point to DATA memory BSF EECON1,RD ; EE Read MOVF EEDATL,W ; W = EEDATL BANKSEL 0 RETURN ;--------------------------------------------------------------------- ; EEPROM書き込み ;--------------------------------------------------------------------- WRTEEPROM BANKSEL EEADRL ; MOVF DATA_EE_ADDR,W ; MOVWF EEADRL ; Data Memory Address to write MOVF DATA_EE_DATA,W ; MOVWF EEDATL ; Data Memory Value to write BCF EECON1,CFGS ; Deselect Configuration space BCF EECON1,EEPGD ; Point to DATA memory BSF EECON1,WREN ; Enable writes BCF INTCON,GIE ; Disable INTs. MOVLW 55h ; MOVWF EECON2 ; Write 55h MOVLW 0AAh ; MOVWF EECON2 ; Write AAh BSF EECON1,WR ; Set WR bit to begin write BSF INTCON,GIE ; Enable Interrupts BCF EECON1,WREN ; Disable writes BTFSC EECON1,WR ; Wait for write to complete GOTO $-2 ;Done BANKSEL 0 RETURN ;--------------------------------------------------------------------- ; I2C初期化(マスター) ;--------------------------------------------------------------------- I2CINIT BANKSEL SSP1CON1 BSF SSP1CON1,SSPM3 ;I2C Master mode, clock = FOSC / (4 * (SSP1ADD+1)) BCF SSP1CON1,SSPM2 BCF SSP1CON1,SSPM1 BCF SSP1CON1,SSPM0 ; BSF SSP1STAT,SMP ; Slew rate control なし(100KHz) BCF SSP1STAT,CKE ; Disable SMBus specific inputs ; MOVLW H'09' ; Boud rate 100K MOVWF SSP1ADD ; BSF SSP1CON1,SSPEN ; Enables the serial port BCF SSP1CON1,WCOL ; Write Collision Detect bit = No BCF SSP1CON1,SSPOV ; Receive Overflow Indicator bit = No ; BANKSEL 0 RETURN ;--------------------------------------------------------------------- ; I2Cスタート ;--------------------------------------------------------------------- I2CSTART BANKSEL SSP1CON2 BSF SSP1CON2,SEN ; Start Condition Enabled bit ; BANKSEL PIR1 BTFSS PIR1,SSP1IF ; 動作完了まで待つ GOTO $-1 ; BCF PIR1,SSP1IF ; フラグクリア ; RETURN ; ;--------------------------------------------------------------------- ; I2Cストップ ;--------------------------------------------------------------------- I2CSTOP BANKSEL SSP1CON2 BSF SSP1CON2,PEN ; Stop Condition Enable bit ; BANKSEL PIR1 BTFSS PIR1,SSP1IF ; 動作完了まで待つ GOTO $-1 ; BCF PIR1,SSP1IF ; フラグクリア ; RETURN ;--------------------------------------------------------------------- ; I2C送信 (Wレジの内容を送信する) ;--------------------------------------------------------------------- I2CSEND BANKSEL SSP1STAT BTFSC SSP1STAT,BF ; Data transmit complete GOTO $-1 ; MOVWF SSP1BUF ; バッファに格納すると送信開始 ; BANKSEL PIR1 BTFSS PIR1,SSP1IF ; 動作完了まで待つ GOTO $-1 ; BCF PIR1,SSP1IF ; フラグクリア ; RETURN ; ;--------------------------------------------------------------------- ; LCD データ(Wレジ内容をLCDに書き込む) ;--------------------------------------------------------------------- LCDDATA MOVWF TMP ; 書き込みデータ一時退避 ; CALL I2CSTART MOVLW H'7C' ; LCDスレーブアドレス CALL I2CSEND ; MOVLW H'40' ; Data (RS=1) CALL I2CSEND ; MOVF TMP,W CALL I2CSEND ; CALL I2CSTOP ; RETURN ; ;--------------------------------------------------------------------- ; LCDコマンド (W:CMD) ;--------------------------------------------------------------------- LCDCMD MOVWF TMP ; 一時退避 ; CALL I2CSTART MOVLW H'7C' CALL I2CSEND MOVLW H'00' ; Command (RS=0) CALL I2CSEND MOVF TMP,W CALL I2CSEND CALL I2CSTOP ; MOVLW H'01' ; Clear Display SUBWF TMP,W BTFSC STATUS,Z GOTO LCDW1MS MOVLW H'02' ; Return Home SUBWF TMP,W BTFSC STATUS,Z GOTO LCDW1MS ; CALL W27US ; Normal command RETURN LCDW1MS CALL W1MS RETURN ;--------------------------------------------------------------------- ; LCD初期化(データシート通り) ;--------------------------------------------------------------------- LCDINIT CALL W20MS ; 電源が安定するまでの待ち時間 CALL W20MS ; MOVLW H'38' ; Function set CALL LCDCMD ; MOVLW H'39' ; Functino set CALL LCDCMD ; MOVLW H'14' ; Intrenal OSC frequency CALL LCDCMD ; MOVF CNTRST,W ; コントラスト ANDLW H'0F' ; 下位4ビット IORLW H'70' CALL LCDCMD SWAPF CNTRST,W ANDLW H'03' ; 上位2ビット IORLW H'54' CALL LCDCMD ; ; Contrast= B'10 1000' = D'40' ;; MOVLW H'70'+H'08' ; Contrast set ;; CALL LCDCMD ; ;; MOVLW H'54'+H'02' ; Power/ICON/Contrast control ;; CALL LCDCMD ; MOVLW H'6C' ; Follower control CALL LCDCMD CALL W100MS ; 200ms CALL W100MS ; MOVLW H'38' ; Function set CALL LCDCMD ; MOVLW H'0C' + H'01' ; Display ON/OFF control CALL LCDCMD ; MOVLW H'01' ; Clear Display CALL LCDCMD ; RETURN ;--------------------------------------------------------------------- ; Waitルーチン(注)割り込みが入るので下記時間にはならない ;--------------------------------------------------------------------- W27US MOVLW D'7' ; CALL含めて27マイクロ秒 LCD待ち時間 MOVWF CNT1 NOP W27USLP DECFSZ CNT1,F GOTO W27USLP RETURN ; W1MS ;1ミリ秒(998usec) CALLと合わせて1.000ms MOVLW D'248' ;1cycle MOVWF CNT1 ;1cycle W1MSLP NOP ;1cycle*248 DECFSZ CNT1,F ;1cycle*247+2cycle GOTO W1MSLP ;2cycle*247 GOTO $+1 ;2cycle NOP ;1cycle RETURN ;2cycle ; W20MS ;約20ミリ秒 MOVLW D'20' ; MOVWF CNT2 ; W20LP CALL W1MS ; DECFSZ CNT2,F ; GOTO W20LP ; RETURN ; ; W100MS MOVLW D'100' MOVWF CNT2 W100MSLP CALL W1MS DECFSZ CNT2,F GOTO W100MSLP RETURN ;--------------------------------------------------------------------- ;http://www.piclist.com/techref/microchip/math/radix/b2bhp-8b3d.htm ;******************************** ;binary_to_bcd - 8-bits ; ;Input ; bin - 8-bit binary number ; A1*16+A0 ;Outputs ; hundreds - the hundreds digit of the BCD conversion ; tens_and_ones - the tens and ones digits of the BCD conversion binary_to_bcd: CLRF hundreds SWAPF bin, W ; swap the nibbles ADDWF bin, W ; so we can add the upper to the lower ANDLW B'00001111' ; lose the upper nibble (W is in BCD from now on) SKPNDC ; if we carried a one (upper + lower > 16) ADDLW 0x16 ; add 16 (the place value) (1s + 16 * 10s) SKPNDC ; did that cause a carry from the 1's place? ADDLW 0x06 ; if so, add the missing 6 (carry is only worth 10) ADDLW 0x06 ; fix max digit value by adding 6 SKPDC ; if was greater than 9, DC will be set ADDLW -0x06 ; if if it wasn't, get rid of that extra 6 BTFSC bin,4 ; 16's place ADDLW 0x16 - 1 + 0x6 ; add 16 - 1 and check for digit carry SKPDC ADDLW -0x06 ; if nothing carried, get rid of that 6 BTFSC bin, 5 ; 32nd's place ADDLW 0x30 ; add 32 - 2 BTFSC bin, 6 ; 64th's place ADDLW 0x60 ; add 64 - 4 BTFSC bin, 7 ; 128th's place ADDLW 0x20 ; add 128 - 8 % 100 ADDLW 0x60 ; has the 10's place overflowed? RLF hundreds, F ; pop carry in hundreds' LSB BTFSS hundreds, 0 ; if it hasn't ADDLW -0x60 ; get rid of that extra 60 MOVWF tens_and_ones ; save result BTFSC bin,7 ; remeber adding 28 - 8 for 128? INCF hundreds, F ; add the missing 100 if bit 7 is set RETURN ; all done! ; ;Note: SKPDC is equivalent to BTFSS STATUS, DC and SKPNDC is equivalent to BTFSC STATUS, DC ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------