;***************************************************************************** ; ; Filename: 1538ctl.asm ; Date: created 2006.5.4 ; ;***************************************************************************** list p=16f88 ; リストファイルの形式設定 #include ; プロセッサを指定するファイルを読み込む errorlevel -302 ; エラー表示レベルの設定 ;***** CONFIGレジスタ1の設定 ***** __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO ;***** CONFIGレジスタ2の設定 ***** __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;***** 各状態変数とそれぞれのランプ表示のデータの定義 ***** STAT_DISA EQU 0 ; discharge A LED_DISA EQU b'00000010' STAT_DISB EQU 1 ; discharge B LED_DISB EQU b'00000100' STAT_AC EQU 2 ; AC adapteter LED_AC EQU b'00000000' STAT_AIR EQU 3 ; airline LED_AIR EQU b'00000000' STAT_REA EQU 4 ; relearn A LED_REA EQU b'00000010' STAT_REB EQU 5 ; relearn B LED_REB EQU b'00000100' STAT_CHGA EQU 6 ; charge A LED_CHGA EQU b'00001000' STAT_CHGB EQU 7 ; charge B LED_CHGB EQU b'00010000' ;****** ポートBの出力ビットの定義 ****** BATSEL EQU 1 RELRN EQU 2 CHRG EQU 3 ;****** ポートBの入力ビットの定義 ****** OUT0 EQU 0 OUT1 EQU 4 OUT2 EQU 5 MAXCHARGE EQU .15 ;最大充電時間 ;***** 割り込み時に諸ステータスをセーブするために Micro Chipにより指定されている変数領域 ****** ; (コメントは原文のまま) w_temp EQU 0x71 ; variable used for context saving status_temp EQU 0x72 ; variable used for context saving pclath_temp EQU 0x73 ; variable used for context saving ;***** 諸変数の宣言 ****** _w EQU 0x74 ; これらはC言語におけるauto変数の _a EQU 0x75 ; ように一時的に用いる。 _b EQU 0x76 ; _c EQU 0x77 ; stat1538 EQU 0x20 ; MAX1538のステータス pb_buffer EQU 0x21 ; ポートBのバッファ pb_temp EQU 0x22 ; ポートBの変化検出のためのバッファ(未使用) stat_A EQU 0x23 ; 充電カウンタA stat_B EQU 0x24 ; 充電カウンタB secs EQU 0x25 ; 秒 mins EQU 0x26 ; 分 hours EQU 0x27 ; 時 just_hour EQU 0x28 ; 毎時フラグ just_minute EQU 0x29 ; 毎分フラグ(未使用) ;***** リセット時はここからスタートする ****** ORG 0x000 goto main ; 0番地からメインへジャンプ ;***** 割り込みルーチン 英文コメントはMicro Chip社の原文のまま ****** ORG 0x004 ; 割り込みベクタ movwf w_temp ; save off current W register contents movf STATUS,w ; move STATUS register into W register movwf status_temp ; save off contents of STATUS register movf PCLATH,W ; move PCLATH register into W register movwf pclath_temp ; save off contents of PCLATH register BANKSEL TMR1H BSF TMR1H, 7 ; 1秒毎の割り込みのためにMSBをセット BCF PIR1, TMR1IF ; 割り込みフラグをリセット INCF secs, F ; 秒を進める MOVF secs, w SUBLW .60 BTFSS STATUS, Z ; 60秒経過? goto isr_ex ; でなければ終了 CLRF secs ; 秒をクリア movlw 1 ;毎分フラグをセット movwf just_minute INCF mins, f ; 分を進める MOVF mins, w SUBLW .60 BTFSS STATUS, Z ; 60分経過? goto isr_ex ; でなければ終了 movlw 1 ; 毎時フラグをセット movwf just_hour CLRF mins ; 分をクリア INCF hours, f ; 時を進める MOVF hours, w SUBLW .24 BTFSS STATUS, Z ; 24時間経過? goto isr_ex ; でなければ終了 CLRF hours ; 時をクリア isr_ex movf pclath_temp,w ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ; ;*********************************************************************** ; main BANKSEL OSCCON ; OSCCONのあるバンク(bank 1)を開く movlw b'01101010' ; internal 4MHz,primary,non stable movwf OSCCON movlw b'00100000' ; ポートAの入出力の方向設定 movwf TRISA movlw b'11110001' ; ポートBの入出力の方向設定 movwf TRISB movlw b'01111111' ; ポートBの入力はプルアップ movwf OPTION_REG BANKSEL PORTB ; bank 0 clrf PORTB movlw h'20' ; レジスタのクリア movwf FSR movlw h'3f' ; ループ・カウンタをwにセット fregclr clrf INDF incf FSR,f addlw h'ff' ; w-- btfss STATUS,Z ; 20h to 5Fhまでをクリア goto fregclr call RTCinit ; タイマ1をRTCの機能として初期化する bsf INTCON,PEIE ; タイマ割り込みスタート bsf INTCON,GIE ; ;***** メイン・ループ **** ; loop sleep ; タイマ割り込みにより1秒毎にスリープから復帰し、 ; 処理を終えるとまたスリープするループ BANKSEL PORTA ; bank 0 bsf PORTA,7 ; テスト用マーカ出力 bcf PORTA,7 call get_stat ; ステータスを得る movlw STAT_DISA ;0 subwf stat1538,w btfsc STATUS,Z ; 放電A? goto discharge_A movlw STAT_DISB ;1 subwf stat1538,w btfsc STATUS,Z ; 放電B? goto discharge_B movlw STAT_AC ;2 subwf stat1538,w btfsc STATUS,Z ; ACアダブタ? goto AC_adapter movlw STAT_AIR ;3 subwf stat1538,w btfsc STATUS,Z ; エア・アダプタ? goto AIR_adapter movlw STAT_REA ;4 subwf stat1538,w btfsc STATUS,Z ; リラーンA? goto relearn_A movlw STAT_REB ;5 subwf stat1538,w btfsc STATUS,Z ; リラーンB? goto relearn_B movlw STAT_CHGA ;6 subwf stat1538,w btfsc STATUS,Z ; 充電A? goto charge_A ;;; movlw STAT_CHGB ;7(default:break) ;;; subwf stat1538,w ;;; btfsc STATUS,Z ; 充電B? goto charge_B discharge_A ; discharge A movlw LED_DISA ; 放電Aのランプ表示 goto putLED discharge_B ; discharge B movlw LED_DISB ; 放電Bのランプ表示 goto putLED AC_adapter ; AC adapter call check_A ; Aの電圧低下をチェックする btfss STATUS,Z goto ac10 clrf stat_A ; ゼロフラグが立ったら goto charge_begin ; Aを充電開始 ac10 call check_B ; Bの電圧低下をチェックする btfss STATUS,Z goto ac_ex clrf stat_B ; ゼロフラグが立ったら充電 charge_begin bsf PORTB,CHRG ; 充電モードに goto loop ac_ex movlw LED_AC ;ACアダプタ使用のランプ表示 goto putLED ; ;***** エア・アダプタの検出は行わないので、下の3つの場合は起こらない **** ; AIR_adapter ; airline movlw LED_AIR goto putLED relearn_A ; relearn A movlw LED_REA goto putLED relearn_B ; relearn B movlw LED_REB goto putLED ; ;****************************** ; charge_A ; バッテリAの充電制御 movf just_hour,f ; 毎時フラグをチェック btfsc STATUS,Z goto chga10 ; セットされていなかったらランプ表示へ clrf just_hour ; フラグをクリア incf stat_A,f ; 充電量++ movlw MAXCHARGE ; 最大値と比較 subwf stat_A,w ; w = stat_A - MAXCHARGE btfsc STATUS,C ; キャリが立っていたらランプ表示へ goto chga10 bcf PORTB,CHRG ; キャリが立っていなかったら充電終了 goto loop chga10 movlw LED_CHGA ; 充電Aを表示 goto putLED charge_B ; バッテリBの充電制御 movf just_hour,f ; 毎時フラグをチェック btfsc STATUS,Z goto chgb10 ; セットされていなかったらランプ表示へ clrf just_hour ; フラグをクリア incf stat_B,f ; 充電量++ movlw MAXCHARGE ; 最大値と比較 subwf stat_B,w ; w = stat_B - MAXCHARGE btfsc STATUS,C ; キャリが立っていたらランプ表示へ goto chgb10 bcf PORTB,CHRG ; キャリが立っていなかったら充電終了 goto loop chgb10 movlw LED_CHGB ; 充電Bを表示 putLED movwf PORTA goto loop ; メイン・ループの終わり ; ;**** バッテリの残量低下を推測する ***** ; check_A BANKSEL PORTB bcf PORTB,BATSEL ; Aを選択 goto bat_check check_B BANKSEL PORTB bsf PORTB,BATSEL ; Bを選択 bat_check bsf PORTB,RELRN ; 一時的にリラーン・モードにする movlw .20 ; ソフトウェア・ループによる20msecの待ち movwf _a bc10 movlw .250 ; 1msec call wait_loop decfsz _a,f goto bc10 call get_stat ; ステータスをチェック sublw STAT_AC ; ACアダプタ動作? bcf PORTB,RELRN ; リラーン・モードから復帰する return ; ;上に示した方法では、バッテリの残量が少ないことを判定するのに、電圧が終止電圧まで低下するまで待たねば ;ならないが、RB6,RB7をA-Dコンバータの入力として用いれば、それ以前のバッテリの状態を判断できる。 ; ;**** 1538のステータスを得る **** ; get_stat movf PORTB,w ; 1538のOUT0,OUT1およびOUT2をポートB movwf pb_buffer ; から読み込み、数値に変換する。 btfss pb_buffer,OUT0 ; OUT0の状態はビット0で表す goto clear0 bsf stat1538,0 goto check1 clear0 bcf stat1538,0 check1 btfss pb_buffer,OUT1 ; OUT1の状態はビット1で表す goto clear1 bsf stat1538,1 goto check2 clear1 bcf stat1538,1 check2 btfss pb_buffer,OUT2 ; OUT2の状態はビット2で表す goto clear2 bsf stat1538,2 goto gs_ex clear2 bcf stat1538,2 gs_ex movf stat1538,w return ; ;***** タイマ1をRTCとして動作させるための設定 ***** ; RTCinit BANKSEL TMR1H MOVLW 0x80 ; 1秒毎の割り込みのためにMSBをセットしておく MOVWF TMR1H CLRF TMR1L MOVLW b'0001111' ; 外付けの時計用クリスタルのための設定 MOVWF T1CON CLRF secs ; カウンタ類の初期化 CLRF mins MOVLW .12 MOVWF hours BANKSEL PIE1 BSF PIE1, TMR1IE ; 割り込みを許可 RETURN ; ;***** ソフトウェア・ループによるディレイ 実行時間(μsec)はwの値の4倍 ; wait_loop movwf _w w10 clrwdt ; 1 Tcy decfsz _w,f ; 1(2) Tcy goto w10 ; 2 Tcy return ; 2 Tcy END