;-------------------------------------------------------------------------------- ; 12V鉛電池・充放電コントローラー Ver 1.7 ; Programmed by GRANADA, Since 2007/09/11- ; ; 2007/10/17 パルス充電対応 ; 2009/01/14 コメント追加 ; 2009/02/19 負荷再接続処理追加(ただしコメントアウト) ; 2009/03/13 過放電時の処理改良(ただしコメントアウト) 、ソース見直し(EQU -> #DEFINE 変更等) ; 2009/04/13 電圧値を一部変更、満充電後クールダウン処理追加、パルス充電をマイルドに変更 ; ; 本プログラムはタブを4文字に設定すると綺麗に整形されます ; 製作記事:http://www.asahi-net.or.jp/~SE1M-NITU/html/pic_charge_controler.htm ;-------------------------------------------------------------------------------- LIST P=12F675 INCLUDE P12F675.INC ERRORLEVEL -205 ERRORLEVEL -302 CB = _CPD_OFF CB &= _CP_OFF CB &= _BODEN_OFF CB &= _MCLRE_OFF CB &= _PWRTE_ON CB &= _WDT_OFF CB &= _EXTRC_OSC_NOCLKOUT ; RCIO モードで Port 4 も使用可能に __CONFIG CB __IDLOCS H'0100' ;-------------------------------------------------------------------------------- ; 変数アドレス定義 ;-------------------------------------------------------------------------------- CBLOCK H'20' ; 変数エリア先頭アドレス VOLTAGE ; バッテリー電圧ストア用 EMPTY_FLAG ; 過放電フラグ ; 一旦過放電を検出したら過放電解消後にマニュアルでリセットしない限り ; 負荷を切り離して警告LED点灯(負荷による発振様のスイッチング防止) FULL_FLAG ; 満充電検出フラグ FIRST_FULL ; 満充電に達したことがあるかのフラグ COUNTER ; 時間待ち用ワーク PULSE_COUNT ; パルス充電用カウンタ BLINK_COUNT ; ノーマル LED 点滅用カウンタ ENDC ;-------------------------------------------------------------------------------- ; 定数定義 ;-------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------- ; 各種検出電圧、手持ちの鉛電池の特性、太陽電池の出力電流に合わせて最適化必要 ;-------------------------------------------------------------------------------- ; AN1 ポートに電池電圧の 1/5 の電圧が加わるよう VR を調製する。 ; A/D変換の基準電圧 = 電源電圧 = 5V の場合、 ; 8bit で A/D 変換を行うと 5V が 255 分割されることになるので、 #DEFINE FULL_V D'139' ; 満充電時 (13.6V) の 8bit A/D 変換値 = 13.6/5 * 255/5 #DEFINE RECHARGE_V D'135' ; 再充電許可時 (13.2V) の 8bit A/D 変換値 = 13.2/5 * 255/5 #DEFINE EMPTY_V D'122' ; 過放電時 (12.0V)の 8bit A/D 変換値 = 11.2/5 * 255/5 ; となる #DEFINE CHARGE_PORT D'0' ; 充電制御 FET はポート 0, 充電 = L, 満充電 = H #DEFINE ANALOG_IN D'1' ; 電圧検出アナログ入力はポート 1 #DEFINE LOAD_PORT D'2' ; 放電制御 FET はポート 2, 負荷 OK = H, 過放電 = L #DEFINE RESET_PORT D'3' ; リセットキーはポート 3 #DEFINE ALERT_LED D'4' ; 過放電警告 LED はポート 4 ;-------------------------------------------------------------------------------- ; プログラム先頭 ;-------------------------------------------------------------------------------- ORG H'0' GOTO INITIALIZE ;-------------------------------------------------------------------------------- ; 割り込み処理(現状未使用) ;-------------------------------------------------------------------------------- ORG H'4' ; 割り込み処理先頭アドレス RETFIE ; 何もしないで割り込み終了 ;-------------------------------------------------------------------------------- ; 初期化 ;-------------------------------------------------------------------------------- INITIALIZE: BANKSEL GPIO ; Bank 0 CLRF GPIO ; 全ポートを L に -> 充電許可、負荷接続不許可、警告表示消灯 MOVLW B'00000111' ; コンパレータ未使用、これを設定しないと Port 0 の挙動が怪しい MOVWF CMCON BANKSEL TRISIO ; Bank 1 CLRF TRISIO ; ひとまず全ポートを出力に指定 BSF TRISIO,ANALOG_IN ; 入力に再指定 NOP ; 連続ビット操作の際のおまじない BSF TRISIO,RESET_PORT ; 入力に再指定 MOVLW B'00110000' ; A/D 変換クロック -> FRC、全ポートをデジタル指定 MOVWF ANSEL BSF ANSEL,ANALOG_IN ; アナログポートのみ再指定、他はデジタルポートのまま CLRF PIE1 BSF PIE1,ADIE ; ADIE ビットを 1 にして AD 割り込み許可 BANKSEL INTCON ; Bank 0 BSF INTCON,PEIE ; PEIE ビットを 1 にして周辺割り込みを許可 ; ただし SLEEP からの起動のみなので GIE は立てない MOVLW B'00000101' ; 左詰、内部 REF、AD コンバータ電源 ON、AN1 で A/D 変換 MOVWF ADCON0 CLRF EMPTY_FLAG ; 過放電フラグをクリアしておく CLRF FULL_FLAG ; 満充電フラグをクリアしておく CLRF FIRST_FULL ; 満充電にまだ一度も達していない CALL BLINK_LED ; 正常起動確認のため LED を数回点滅 CALL LOAD_CONNECT ; 負荷接続開始 ;-------------------------------------------------------------------------------- ; メインループ開始 ;-------------------------------------------------------------------------------- MAIN_LOOP: CALL KEY_CHECK ; リセットキーチェック CALL Wait_20ms ; 次のサンプリングまで 2TAD 以上待つ CALL READ_VOLTAGE ; 電圧を読んでメモリにストア ;-------------------------------------------------------------------------------- ; 過放電フラグをチェックし、必要なら LED 警告 ; (通常 LED 使用時は以下3行のコードを復活させること) ;-------------------------------------------------------------------------------- ; ; MOVF EMPTY_FLAG,F ; 過放電フラグを読む。一度でも過放電に達していたら 1 になる ; BTFSS STATUS,Z ; Z フラグが 1(過放電ではない)なら次の命令をスキップ ; CALL FLASH_LED ; 過放電状態なら LED 警告 ;-------------------------------------------------------------------------------- ; 電圧比較、満充電か ? ;-------------------------------------------------------------------------------- MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW FULL_V ; FULL_V - VOLTAGE -> W BTFSC STATUS,C ; 満充電時は借り入れが発生するので C=0 となり、次の命令がスキップされる GOTO CHECK_RECHARGE ; 満充電ではない ;-------------------------------------------------------------------------------- ; 満充電 ;-------------------------------------------------------------------------------- CALL CHARGE_OFF ; 充電停止 MOVLW D'1' MOVWF FULL_FLAG ; 満充電フラグセット MOVLW D'1' MOVWF FIRST_FULL ; 満充電に一度でも達した CALL Wait_1sec ; 1秒充電停止、クールダウン CALL Wait_1sec ; 1秒充電停止、クールダウン GOTO MAIN_LOOP ; メイン処理再開 ;-------------------------------------------------------------------------------- ; 再充電許可電圧か ? ;-------------------------------------------------------------------------------- CHECK_RECHARGE: MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW RECHARGE_V ; RECHARGE_V - VOLTAGE -> W BTFSC STATUS,C ; 再充電許可電圧より電圧が高ければキャリーが発生して C=0 となり次の命令がスキップされる GOTO CHECK_EMPTY ; 過放電チェックへ ;-------------------------------------------------------------------------------- ; 再充電許可電圧以上の場合 ;-------------------------------------------------------------------------------- ; ;-------------------------------------------------------------------------------- ; 再充電許可電圧を超えたら負荷を自動再接続するには以下の3行を復活させる ;-------------------------------------------------------------------------------- ; CLRF EMPTY_FLAG ; 過放電フラグをクリア ; CALL LED_OFF ; 過放電 LED を消す ; CALL LOAD_CONNECT ; 負荷再接続 MOVF FULL_FLAG,F ; 満充電フラグをチェック。満充電に達していたら 1 になる BTFSS STATUS,Z ; Z フラグが 1(満充電に達していない)なら次の命令をスキップ GOTO MAIN_LOOP ; 満充電フラグが立っていたら電圧が下がるまで何もしない ;-------------------------------------------------------------------------------- ; 電源投入後、一度でも満充電に達したか ;-------------------------------------------------------------------------------- MOVF FIRST_FULL,F ; 一度も満充電に達していないかのフラグをチェック BTFSC STATUS,Z ; Z フラグが 0(既に一度でも満充電に達した)なら次の命令をスキップ GOTO MAIN_LOOP ; まだ一度も満充電に達していならパルス充電にはせず通常充電 ;-------------------------------------------------------------------------------- ; パルス充電 ;-------------------------------------------------------------------------------- CALL PULSE_CHARGE ; パルス充電する CALL CHARGE_ON ; 充電制御 FET ON にして CALL Wait_20ms ; 少し待って電圧を回復させる GOTO MAIN_LOOP ; メイン処理再開 ;-------------------------------------------------------------------------------- ; 電圧比較、過放電か ? ;-------------------------------------------------------------------------------- CHECK_EMPTY: CALL CHARGE_ON ; とにかく電圧が十分下がっているので充電制御 FET ON CLRF FULL_FLAG ; 満充電フラグをクリア MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW EMPTY_V ; EMPTY_V - VOLTAGE -> W BTFSS STATUS,C ; 過放電時はキャリーが発生しないから C=1 となり次の命令をスキップ GOTO MAIN_LOOP ; 電圧は正常範囲内 ;-------------------------------------------------------------------------------- ; 過放電 ;-------------------------------------------------------------------------------- MOVLW D'1' MOVWF EMPTY_FLAG ; 過放電フラグを立てる CALL LOAD_DISCONNECT ; 負荷制御 FET OFF して負荷を切り離す CALL FLASH_LED ; LED 警告開始 ; CLRF FIRST_FULL ; 再充電許可電圧〜満充電を通常充電モードに戻すならこの行を復活 GOTO MAIN_LOOP ; A/D 変換再開 ;-------------------------------------------------------------------------------- ; A/D 変換を実行し、値をメモリにストアする ;-------------------------------------------------------------------------------- READ_VOLTAGE: BCF PIR1,ADIF ; ADIF を 0 に(A/D 変換終了時このビットが 1 になる) BSF ADCON0,GO ; GO (start) bit を立てて A/D 変換開始 SLEEP ; A/D 変換しながら SLEEP モードへ NOP ; A/D 変換が終了したら自動的に再開 MOVF ADRESH,W ; A/D 変換値を読み出して MOVWF VOLTAGE ; ひとまず汎用メモリに保存 RETURN ;-------------------------------------------------------------------------------- ; 充電を許可する ;-------------------------------------------------------------------------------- CHARGE_ON: BCF GPIO,CHARGE_PORT ; 充電制御 FET ON RETURN ;-------------------------------------------------------------------------------- ; 充電を止める ;-------------------------------------------------------------------------------- CHARGE_OFF: BSF GPIO,CHARGE_PORT ; 充電制御 FET OFF RETURN ;-------------------------------------------------------------------------------- ; 一定時間パルス充電 ;-------------------------------------------------------------------------------- PULSE_CHARGE: ; MOVLW D'3' ; 充電パルス回数設定 ; MOVWF PULSE_COUNT PULSE_LOOP: CALL CHARGE_ON ; 充電制御 FET ON CALL Wait_100ms CALL CHARGE_OFF ; 充電制御 FET OFF CALL Wait_1sec ; 1秒充電停止してクールダウン ; DECFSZ PULSE_COUNT,F ; GOTO PULSE_LOOP ; in case DECFSZ false RETURN ;-------------------------------------------------------------------------------- ; 負荷接続を許可する ;-------------------------------------------------------------------------------- LOAD_CONNECT: BSF GPIO,LOAD_PORT ; 負荷制御 FET ON で通電 RETURN ;-------------------------------------------------------------------------------- ; 負荷を切り離す ;-------------------------------------------------------------------------------- LOAD_DISCONNECT: BCF GPIO,LOAD_PORT ; 負荷制御 FET OFF で負荷切り離し RETURN ;-------------------------------------------------------------------------------- ; 警告表示(LED点滅)自己点滅 LED の場合 ;-------------------------------------------------------------------------------- FLASH_LED: CALL LED_ON RETURN ;-------------------------------------------------------------------------------- ; 警告表示(LED点滅)ノーマル LED の場合 ;-------------------------------------------------------------------------------- ; ;FLASH_LED: ; ; CALL LED_ON ; CALL Wait_200ms ; CALL Wait_200ms ; CALL LED_OFF ; 警告 LED 消灯 ; CALL Wait_200ms ; CALL Wait_200ms ; ; RETURN ;-------------------------------------------------------------------------------- ; 警告(LED)表示点灯 ;-------------------------------------------------------------------------------- LED_ON: BSF GPIO,ALERT_LED ; 警告 LED 点灯 RETURN ;-------------------------------------------------------------------------------- ; 警告(LED)表示停止 ;-------------------------------------------------------------------------------- LED_OFF: BCF GPIO,ALERT_LED ; 警告 LED 消灯 RETURN ;-------------------------------------------------------------------------------- ; 正常起動確認(自動点滅 LED の場合) ;-------------------------------------------------------------------------------- BLINK_LED: CALL LED_ON CALL Wait_1sec CALL Wait_1sec CALL Wait_1sec CALL LED_OFF RETURN ;-------------------------------------------------------------------------------- ; 正常起動確認(ノーマル LED の場合) ;-------------------------------------------------------------------------------- ; ;BLINK_LED: ; 通常 LED を使用した場合の点滅処理 ; ; MOVLW D'3' ; 点滅回数 ; MOVWF BLINK_COUNT ; ;BLINK: ; ; CALL LED_ON ; 点灯 ; CALL Wait_200ms ; CALL Wait_200ms ; CALL LED_OFF ; 消灯 ; CALL Wait_200ms ; CALL Wait_200ms ; ; DECFSZ BLINK_COUNT,F ; GOTO BLINK ; 所定回数まで繰り返す ; ; RETURN ;-------------------------------------------------------------------------------- ; リセットキー操作チェック ;-------------------------------------------------------------------------------- KEY_CHECK: BTFSC GPIO,RESET_PORT ; ボタンが押されたか? RETURN ; 押されていなければ戻る、押されていればこのコードはスキップされる CALL Wait_20ms ; 押されたら20ミリ秒待つ(チャタリング防止) BTFSC GPIO,RESET_PORT ; まだボタンが押されているか? RETURN ; 押されていなければ戻る RESET: CALL CHARGE_ON ; ひとまず充電は許可する CALL READ_VOLTAGE ; A/D 変換実行 MOVF VOLTAGE,W ; 測定電圧値を読み出す SUBLW EMPTY_V ; EMPTY_V - VOLTAGE -> W BTFSC STATUS,C ; 正常電圧範囲内ならキャリーが発生し C=0 となり次の命令をスキップ GOTO MAIN_LOOP ; 電圧は未だ過放電状態なので何もしない CLRF EMPTY_FLAG ; 過放電状態ではないので、過放電フラグをクリアする CALL LED_OFF ; 警告 LED 消灯 CALL LOAD_CONNECT ; 負荷を接続してみる CALL Wait_20ms ; 少し待って電圧を安定化 RETURN ;-------------------------------------------------------------------------------- ; クロック 1KHz 時 1 step = 1/250 Sec = 4ms ;-------------------------------------------------------------------------------- Wait_20ms: MOVLW D'1' MOVWF COUNTER GOTO WAIT_LOOP Wait_100ms: MOVLW D'5' MOVWF COUNTER GOTO WAIT_LOOP Wait_200ms: MOVLW D'10' MOVWF COUNTER GOTO WAIT_LOOP Wait_1sec: MOVLW D'50' MOVWF COUNTER GOTO WAIT_LOOP WAIT_LOOP: ;5 steps = 20 clocks = 20ms if 1KHz clock GOTO $+1 ; 2 steps DECFSZ COUNTER,F GOTO WAIT_LOOP ; 所定の回数までループ RETURN ;-------------------------------------------------------------------------------- ; プログラム終了 ;-------------------------------------------------------------------------------- END