;-------------------------------------------------------------------------------- ; PIC16F88 充電電流 & 電池電圧メーター ; Programmed by GRANADA ; Original 12F675 version : since 2008/11/18-11/20 ; 16F88 version : since 2008/11/28- ; ;-------------------------------------------------------------------------------- LIST P=16F88 INCLUDE P16F88.INC ERRORLEVEL -302 __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;-------------------------------------------------------------------------------- ; ファイルアドレス定義 ;-------------------------------------------------------------------------------- VOLTAGE EQU H'20' ; 電流値ストア用 VOLTAGE_TMP EQU H'21' ; 測定電圧一時保存用 BATTERY_V EQU H'22' ; 電池電圧ストア用 BLINK_COUNTER EQU H'24' ; LED BLINK 処理用カウンタ LED_BIT EQU H'25' ; 電池電圧 LED 表示の際の表示位置保持用 W_WORK EQU H'30' ; 割り込み時の W レジスタ退避用(未使用) ST_WORK EQU H'31' ; 割り込み時のステータスレジスタ退避用(未使用) WORK1 EQU H'32' ; 割り込み時の時間待ち変数退避用 WORK2 EQU H'33' ; 割り込み時の時間待ち変数退避用 COUNTER1 EQU H'40' ; 時間待ち用ワーク COUNTER2 EQU H'41' ; 時間待ち用ワーク DISPLAY_COUNTER EQU H'43' ; LED 点灯回数用カウンタ INT_COUNTER EQU H'44' ; 割り込み処理用カウンタ ;-------------------------------------------------------------------------------- ; 定数定義 ;-------------------------------------------------------------------------------- CURRENT_IN EQU D'0' ; 電流値入力 RA0(AN0) BATTERY_IN EQU D'1' ; 電池電圧入力 RA1(AN1) LED1 EQU D'2' ; RA2 LED2 EQU D'3' ; RA3 LED3 EQU D'0' ; RB0 LED4 EQU D'1' ; RB1 LED5 EQU D'2' ; RB2 LED6 EQU D'3' ; RB3 LED7 EQU D'4' ; RB4 LED8 EQU D'5' ; RB5 LED9 EQU D'6' ; RA6 LED10 EQU D'7' ; RA7 ; ; 電流検出抵抗 40mオーム だと 1A で 40mV 発生。 ; 1.0A max ならゲイン 125倍 で 5V ; 0.5A max ならゲイン 250倍 で 5V ; ただしオペアンプの入力オフセットの補正は必要 ; ; ・・・・などといろいろ考えたが、要は測定最大電流を流した際に ; LED が全点灯するよう VR でゲインを調整し、A/D変換値はオペアンプの ; 最大出力電圧を考慮して等分すればいいと。 ; NJM2119D は max 4V スイングなので Vref+ 5V 時の A/D 変換最大値は 201 ; ; Ratio 1A max時 300mA max時 LED1_V EQU D'10' ; 1/20 50mA 15mA LED2_V EQU D'30' ; 3/20 150mA 45mA LED3_V EQU D'50' ; 5/20 250mA 75mA LED4_V EQU D'70' ; 7/20 350mA 105mA LED5_V EQU D'90' ; 9/20 450mA 135mA LED6_V EQU D'110' ; 11/20 550mA 165mA LED7_V EQU D'130' ; 13/20 650mA 195mA LED8_V EQU D'150' ; 15/20 750mA 225mA LED9_V EQU D'170' ; 17/20 850mA 255mA LED10_V EQU D'190' ; 19/20 950mA 285mA ; ; 12v 電池電圧表示用, 抵抗比は 1:3 (=1/4入力) ; BATTERY_LED2_V EQU D'143' ; 11.2/4 * 256/5 2.80v RED BATTERY_LED3_V EQU D'151' ; 11.8 2.95v YELLOW BATTERY_LED4_V EQU D'153' ; 12.0 3.00v YELLOW BATTERY_LED5_V EQU D'160' ; 12.5 3.12v GREEN BATTERY_LED6_V EQU D'166' ; 13.0 3.25v GREEN BATTERY_LED7_V EQU D'173' ; 13.5 3.37v GREEN BATTERY_LED8_V EQU D'185' ; 14.5 3.62v GREEN BATTERY_LED9_V EQU D'194' ; 15.2/4 * 256/5 3.80v GREEN ;-------------------------------------------------------------------------------- ; プログラム先頭 ;-------------------------------------------------------------------------------- ORG H'0' GOTO INITIALIZE ;-------------------------------------------------------------------------------- ; 割り込み処理 ;-------------------------------------------------------------------------------- ORG H'4' ; 割り込み処理先頭アドレス PUSH_REG: MOVWF W_WORK ; レジスタ待避 SWAPF STATUS,W ; Z フラグが影響しないよう、MOVF ではなく SWAPF を使用 MOVWF ST_WORK ; ; 割り込み処理(電池電圧表示) ; DECFSZ INT_COUNTER,F GOTO POP_REG ; 所定回数に達しなければ割り込み終了 ; ; 変数退避 ; MOVF COUNTER1,W MOVWF WORK1 MOVF COUNTER2,W MOVWF WORK2 ; ; 電池電圧表示実行 ; CALL DISPLAY_BATTERY_VOLTAGE ; ; 変数復帰 ; MOVF WORK1,W MOVWF COUNTER1 MOVF WORK2,W MOVWF COUNTER2 CLRF DISPLAY_COUNTER INCF DISPLAY_COUNTER,F ; 復帰後すぐ電流測定を開始するよう表示カウンタを最小にしておく CALL SET_INT_COUNTER ; 割り込みカウンタを初期化 POP_REG: SWAPF ST_WORK,W ;レジスタ復帰 MOVWF STATUS SWAPF W_WORK,F SWAPF W_WORK,W BCF PIR1,TMR1IF ; TMR1割り込みフラグをクリアしておく ; フラグをクリアしておかないと次回の割り込みがかからないので注意 RETFIE ; 割り込み処理終了 ;-------------------------------------------------------------------------------- ; 初期化 ;-------------------------------------------------------------------------------- INITIALIZE: BANKSEL OSCCON ; Bank1 MOVLW B'01111100' ; 内部クロック 8MHz に設定 MOVWF OSCCON BCF OPTION_REG,7 ; Bank1, PORTB weak pull up enable ( 0 = enable ) ; Bank1, ANSEL 設定は TRISA/B 設定より前でないダメというウワサあり BSF ANSEL,0 ; AN0, アナログポートのみ再指定、他はデジタル入出力に設定される NOP BSF ANSEL,1 ; AN1 CLRF TRISA ; Bank1, ひとまず全ポートを出力に指定 BSF TRISA,CURRENT_IN ; 電流計測ポートを入力に再指定 NOP ; 安定するまで待つ BSF TRISA,BATTERY_IN ; 電圧計測ポートを入力に再指定 CLRF TRISB ; Bank1, ひとまず全ポートを出力に設定 ; しかし TMR1 使用時 RB6, RB7 は TRISB 設定に関わらず ; 入力専用となり常に 0 になる(!)点に注意 ; この場合、PORTB 状態変化割り込みもかからない BANKSEL INTCON ; Bank0 CLRF INTCON MOVLW B'00000111' ; コンパレータ未使用(12F675 ではこれを設定しないと Port 0 の挙動が怪しいので念のため) MOVWF CMCON ; Bank0 MOVLW B'10000001' ; 32 Tosc, AN0 使用, AD コンバータ電源 ON MOVWF ADCON0 ; Bank0 BANKSEL ADCON1 ; Bank1 CLRF ADCON1 ; 左詰、32 Tosc(の最上位ビット), Vref+ = VDD, Vref- = Vss BANKSEL PIE1 ; Bank1 CLRF PIE1 ; ひとまず全ての割り込みを不許可 BSF PIE1,TMR1IE ; TMR1割り込み許可 BANKSEL TMR1H ; Bank0 MOVLW H'EA' ; 6万カウントで割り込み発生 MOVWF TMR1H MOVLW H'60' ; 8MHz時 1カウント = 0.5us なので MOVWF TMR1L ; 6万カウントなら 30ms毎に割り込み発生 BSF INTCON,PEIE ; Bank0, 周辺割り込み有効 NOP BSF INTCON,GIE ; グローバル割り込み許可 MOVLW B'00111000' ; プリスケース1:8なら240ms毎に割り込み発生 MOVWF T1CON ; Bank0, タイマーレジスタ設定 BSF T1CON,TMR1ON ; TMR1 スタート CALL SET_INT_COUNTER ; 割り込みカウンタを初期化 ; CALL BLINK_LED ; 全 LED を点滅させて正常起動を確認 ;-------------------------------------------------------------------------------- ; メインループ開始 ;-------------------------------------------------------------------------------- MAIN_LOOP: CALL READ_VOLTAGE ; オペアンプからの電圧を読んで MOVF VOLTAGE_TMP,W MOVWF VOLTAGE ; 電流表示用電圧としてストア CALL SET_DISPLAY_COUNTER ; LED 表示回数をリセット ;-------------------------------------------------------------------------------- ; LED 表示 ;-------------------------------------------------------------------------------- EXEC_DISPLAY: CALL DISPLAY_LED ; LED 表示 DECFSZ DISPLAY_COUNTER,F GOTO EXEC_DISPLAY ; 所定回数まで表示 GOTO MAIN_LOOP ;-------------------------------------------------------------------------------- ; メインループ終了、ここからサブルーチン群 ;-------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------- ; A/D 変換を実行し、値をメモリにストアする ;-------------------------------------------------------------------------------- READ_VOLTAGE: CALL WAIT_100us ; サンプリングまで 2TAD 以上待つ BSF ADCON0,GO ; GO (start) bit を立てて A/D 変換開始 EXEC_AD: ; 通常の A/D 変換 BTFSC ADCON0,GO ; A/D 変換終了したか? 0 なら次をスキップ GOTO EXEC_AD ; まだ変換中 MOVF ADRESH,W ; A/D 変換値を読み出して MOVWF VOLTAGE_TMP ; メモリにストアしておく RETURN ;-------------------------------------------------------------------------------- ; ダイナミック点灯サブルーチン ;-------------------------------------------------------------------------------- DISPLAY_LED: CALL ALL_LED_OFF ; 全 LED 消灯 MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED1_V ; LED1_V - VOLTAGE -> W BTFSC STATUS,C ; LED1_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる RETURN ; 最低電圧以下なのでメインループに戻る BSF PORTA,LED1 ; LED1 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED2 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED2_V ; LED2_V - VOLTAGE -> W BTFSC STATUS,C ; LED2_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTA,LED1 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTA,LED2 ; LED2 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED3 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED3_V ; LED3_V - VOLTAGE -> W BTFSC STATUS,C ; LED3_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTA,LED2 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTB,LED3 ; LED3 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED4 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED4_V ; LED4_V - VOLTAGE -> W BTFSC STATUS,C ; LED4_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTB,LED3 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTB,LED4 ; LED4 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED5 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED5_V ; LED5_V - VOLTAGE -> W BTFSC STATUS,C ; LED5_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTB,LED4 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTB,LED5 ; LED5 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED6 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED6_V ; LED6_V - VOLTAGE -> W BTFSC STATUS,C ; LED6_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTB,LED5 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTB,LED6 ; LED6 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED7 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED7_V ; LED7_V - VOLTAGE -> W BTFSC STATUS,C ; LED7_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTB,LED6 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTB,LED7 ; LED7 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED8 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED8_V ; LED8_V - VOLTAGE -> W BTFSC STATUS,C ; LED8_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTB,LED7 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTB,LED8 ; LED8 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED9 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED9_V ; LED9_V - VOLTAGE -> W BTFSC STATUS,C ; LED9_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTB,LED8 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTA,LED9 ; LED9 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド ;-------------------------------------------------------------------------------- ; LED10 以上の電圧? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW LED10_V ; LED10_V - VOLTAGE -> W BTFSC STATUS,C ; LED10_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO ALL_LED_OFF BCF PORTA,LED9 ; ひとつ前の LED を消す CALL WAIT_2us BSF PORTA,LED10 ; LED10 点灯 CALL HOLD_LED ; LED 点灯をしばらくホールド RETURN ;-------------------------------------------------------------------------------- ; LED 全消灯 ;-------------------------------------------------------------------------------- ALL_LED_OFF: CLRF PORTB ; LED3-8 消灯 BCF PORTA, LED1 BCF PORTA, LED2 BCF PORTA, LED9 BCF PORTA, LED10 RETURN ;-------------------------------------------------------------------------------- ; LED 表示を一定時間保持 ;-------------------------------------------------------------------------------- HOLD_LED: CALL WAIT_1ms CALL WAIT_1ms RETURN ;-------------------------------------------------------------------------------- ; LED 表示を一定時間保持(長め) ;-------------------------------------------------------------------------------- HOLD_LED_LONG: CALL WAIT_100ms RETURN ;-------------------------------------------------------------------------------- ; 全 LED 点滅表示 ;-------------------------------------------------------------------------------- BLINK_LED: CALL ALL_LED_OFF ; 全 LED 消灯 CALL HOLD_LED_LONG MOVLW D'2' ; LED BLINK 回数 MOVWF BLINK_COUNTER BLINK: MOVLW B'11001100' ; 全 LED を点滅させて正常起動をアピール MOVWF PORTA MOVLW B'11111111' MOVWF PORTB CALL WAIT_100ms CALL ALL_LED_OFF ; 全消灯 CALL WAIT_100ms DECFSZ BLINK_COUNTER,F GOTO BLINK ; 所定回数未満ならループ CALL HOLD_LED_LONG CALL ALL_LED_OFF ; 全 LED 消灯 RETURN ;-------------------------------------------------------------------------------- ; LED ダイナミック表示ループの回数を初期化 ;-------------------------------------------------------------------------------- SET_DISPLAY_COUNTER: MOVLW D'10' ; 短め(電流表示用) MOVWF DISPLAY_COUNTER ; ダイナミック表示を行う際のカウンタ RETURN SET_DISPLAY_COUNTER2: ; 長め(電池電圧表示用) MOVLW D'50' ; MOVWF DISPLAY_COUNTER ; ダイナミック表示を行う際のカウンタ RETURN ;-------------------------------------------------------------------------------- ; 割り込み処理用カウンタをクリア ;-------------------------------------------------------------------------------- SET_INT_COUNTER: MOVLW D'40' ; 240ms x 40 = 9.6 sec 毎に割り込み処理 MOVWF INT_COUNTER ; カウンタを初期化 RETURN ;-------------------------------------------------------------------------------- ; 電池電圧表示(TMR1割り込みで飛んでくる) ;-------------------------------------------------------------------------------- DISPLAY_BATTERY_VOLTAGE: BSF ADCON0,3 ; AN1 使用(電池電圧を読む) CALL READ_VOLTAGE ; 電圧を読んで BCF ADCON0,3 ; AN0 使用に戻す(電流を読む) MOVF VOLTAGE_TMP,W MOVWF BATTERY_V ; 電池電圧表示用としてストア CALL READ_VOLTAGE ; アナログポートのチャージを廃棄 CALL ALL_LED_OFF ; 念のため全消灯 CALL WAIT_100ms CALL WAIT_100ms CALL SET_DISPLAY_COUNTER2 ; LED 表示回数をリセット(長め) ;-------------------------------------------------------------------------------- ; 電池電圧の LED 表示ループ ;-------------------------------------------------------------------------------- BATTERY_DISPLAY2: CALL BATTERY_DISPLAY ; LED 表示 DECFSZ DISPLAY_COUNTER,F GOTO BATTERY_DISPLAY2 ; 所定回数まで表示 CALL WAIT_100ms CALL WAIT_100ms RETURN ;-------------------------------------------------------------------------------- ; 電池電圧 LED 表示サブルーチン ;-------------------------------------------------------------------------------- BATTERY_DISPLAY: ;-------------------------------------------------------------------------------- ; 左端点灯 ;-------------------------------------------------------------------------------- BSF TRISA,LED1 ; 左端点灯 CALL HOLD_LED BCF TRISA,LED1 ;-------------------------------------------------------------------------------- ; どの LED を点灯させるか ? ;-------------------------------------------------------------------------------- CLRF LED_BIT ; どのポートを点灯させるべきかのフラグ MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED2_V ; LED2_V - VOLTAGE -> W BTFSC STATUS,C ; LED2_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO RIGHT_LED_ON ; LED2 すら付かない MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED3_V ; LED3_V - VOLTAGE -> W BTFSC STATUS,C ; LED3_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO LED2_ON ; LED2 点灯 BSF LED_BIT,0 ; 0bit目(LED3) = 1 MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED4_V ; LED4_V - VOLTAGE -> W BTFSC STATUS,C ; LED4_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO SET_LED_PORT ; LED3 点灯 BCF LED_BIT,0 BSF LED_BIT,1 ; 1bit目(LED4) = 1 MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED5_V ; LED5_V - VOLTAGE -> W BTFSC STATUS,C ; LED5_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO SET_LED_PORT ; LED4 点灯 BCF LED_BIT,1 BSF LED_BIT,2 ; 2bit目(LED5) = 1 MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED6_V ; LED6_V - VOLTAGE -> W BTFSC STATUS,C ; LED6_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO SET_LED_PORT ; LED5 点灯 BCF LED_BIT,2 BSF LED_BIT,3 ; 3bit目(LED6) = 1 MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED7_V ; LED7_V - VOLTAGE -> W BTFSC STATUS,C ; LED7_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO SET_LED_PORT ; LED6 点灯 BCF LED_BIT,3 BSF LED_BIT,4 ; 4bit目(LED7) = 1 MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED8_V ; LED8_V - VOLTAGE -> W BTFSC STATUS,C ; LED8_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO SET_LED_PORT ; LED7 点灯 BCF LED_BIT,4 BSF LED_BIT,5 ; 5bit目(LED8) = 1 MOVF BATTERY_V,W ; 測定電圧値を読み出す SUBLW BATTERY_LED9_V ; LED9_V - VOLTAGE -> W BTFSC STATUS,C ; LED9_V 以上なら借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO SET_LED_PORT ; LED8 点灯 ;-------------------------------------------------------------------------------- ; 真ん中点灯 ;-------------------------------------------------------------------------------- LED9_ON: BSF PORTA,LED9 ; LED 9 点灯 CALL HOLD_LED BCF PORTA,LED9 ; 消灯 GOTO RIGHT_LED_ON LED2_ON: BSF PORTA,LED2 ; 点灯 CALL HOLD_LED BCF PORTA,LED2 ; 消灯 GOTO RIGHT_LED_ON SET_LED_PORT: MOVF LED_BIT,W MOVWF PORTB ; LED 点灯 CALL HOLD_LED CLRF PORTB ; 消灯 ;-------------------------------------------------------------------------------- ; 右端点灯 ;-------------------------------------------------------------------------------- RIGHT_LED_ON: BSF TRISA,LED10 ; 右端点灯 CALL HOLD_LED BCF TRISA,LED10 RETURN ;-------------------------------------------------------------------------------- ; 時間待ちサブルーチン ;-------------------------------------------------------------------------------- WAIT_2us: ; 8MHz時だいたい2us MOVLW D'1' MOVWF COUNTER2 GOTO WAIT_LOOP0 WAIT_100us: MOVLW D'50' MOVWF COUNTER2 WAIT_LOOP0: NOP DECFSZ COUNTER2,F GOTO WAIT_LOOP0 RETURN WAIT_1ms: MOVLW D'2' GOTO SET_COUNTER WAIT_10ms: MOVLW D'20' GOTO SET_COUNTER WAIT_100ms: MOVLW D'200' GOTO SET_COUNTER ;-------------------------------------------------------------------------------- ; 時間待ちサブルーチン・コア部分、4MHz 時 1ms ループ ; (クロック 4MHz 時 1 step = 1/4000000 x 4 (sec) = 1μs) ;-------------------------------------------------------------------------------- SET_COUNTER: MOVWF COUNTER1 WAIT_LOOP1: MOVLW H'F9' ; 4MHz 時 F9H で 1ms のループになる MOVWF COUNTER2 WAIT_LOOP2: NOP DECFSZ COUNTER2,F GOTO WAIT_LOOP2 DECFSZ COUNTER1,F GOTO WAIT_LOOP1 RETURN ;-------------------------------------------------------------------------------- ; プログラム終了 ;-------------------------------------------------------------------------------- END