/*1.2V-NiMH充電池放電・充電器*/ /*Designed by T.Inoue 2016-04-24/ /*単3x2本、放電・充電選択スイッチによりいずれかを実行*/ /*放電選択スイッチでLED点灯、放電開始、1.26V未満で放電LED-点滅、1.0V以下で放電終了LED消灯、または1.26V以上で消灯*/ /*充電選択スイッチでLED点灯、充電開始1.48V以下でLED点滅、1.48V以上でLED消灯充電停止、または開始13時間後に充電停止*/ //timer1を使い予定充電時間(13時間:プログラムで変更可)到達で充電を終了する #include #include __CONFIG(BOREN & UNPROTECT & PWRTEN & WDTDIS & HS ); #define _XTAL_FREQ 20000000 /*20MHz*/ #define JIKAN 30 /*30m秒*/ #define _Timer1_FREQ 32768 unsigned short volt0,volt1,volt2,volt3; char dchg0,dchg1,chg0,chg1; ioport(); tmr1_chk(); unsigned short s = 0; charge0(); charge1(); discharge0(); discharge1(); main() { PORTB=0; PORTC=0; ioport(); //T1CON T1CKPS1 = 0; T1CKPS0 = 0; T1OSCEN = 1; //Timer Osillatorを使う T1SYNC = 0; //外部入力クロックと同期する TMR1CS = 1; //RC0ピンからの外部クロックを使用 TMR1IE = 1; //タイマー割り込み許可 CMCON=0x07; /* b00000111 コンパレータはoff */ ADCS1=1; /*Frc*//*A/D変換クロックをFrc(A/D変換専用発振器内臓)にする */ ADCS0=1; ADCS2=0; ADFM=1; /* A/D変換結果データは右詰めにする*/ ADON=1; /* A/Dコンバータを電源ONにする*/ ADIF=0; /*割り込みフラッグビットを0にする*/ ADIE=1; /*A/D変換終了した時に起こす*/ PEIE=1; //タイマー1オーバーフロー割り込みを使う int i = 0; while(1){ dchg0 = 0,dchg1 = 0,chg0 = 0,chg1 = 0; if(RB7 == 0){ RB4 = 1; //充電未完 RB5 = 1; __delay_ms(JIKAN); /*ms待つ*/ RC2 = 0; //放電off消灯 RC3 = 0; //放電off消灯 RC4 = 0; //放電off RC5 = 0; //放電off __delay_ms(JIKAN); /*ms待つ*/ TMR1ON = 1; //timer1スタート while(1){ //充電 if(chg0 == 0){ charge0(); tmr1_chk(); for(i=3;i>0;i--){ __delay_ms(JIKAN); /*ms待つ*/ } } if(chg1 == 0){ charge1(); tmr1_chk(); for(i=3;i>0;i--){ __delay_ms(JIKAN); /*ms待つ*/ } } if(RB6 == 0){ //放電指令 TMR1ON = 0; //タイマー停止 break; } tmr1_chk(); if(s >= 46800){ //3600秒*13=46800秒, 13時間 TMR1ON = 0; //タイマー停止 RB0 = 1; //充電off RB1 = 1; //充電off RB4 = 0; //充電off消灯 RB5 = 0; //充電off消灯 __delay_ms(JIKAN); /*ms待つ*/ break; } } } if(RB6 == 0){ RC2 = 1; //放電未完 RC3 = 1; for(i=10;i>=0;i--){ __delay_ms(JIKAN); /*ms待つ*/ } RB0 = 1; //充電off RB1 = 1; //充電off RB4 = 0; //充電off消灯 RB5 = 0; //充電off消灯 __delay_ms(JIKAN); /*ms待つ*/ while(1){ //放電 if(dchg0 == 0){ discharge0(); for(i=10;i>=0;i--){ __delay_ms(JIKAN); /*ms待つ*/ } } if(dchg1 == 0){ discharge1(); for(i=10;i>=0;i--){ __delay_ms(JIKAN); /*ms待つ*/ } } if((dchg0 == 10)&&(dchg1 == 10)){ //放電完了 RC2 = 0; //放電off消灯 RC3 = 0; //放電off消灯 break; } if((dchg0 == 20)&&(dchg1 == 20)){ //放電なし RB4 ^= 1; //充電点滅 RB5 ^= 1; break; } if(RB7 == 0){ //充電指令 RC2 = 0; //放電off消灯 RC3 = 0; //放電off消灯 break; } } } } } charge0(){ /*電圧測定*/ CHS2=0; //AN0ピンでvolt0の電圧をAD変換する*/ CHS1=0; CHS0=0; __delay_us(5); /* 5us待つ*/ GODONE=1; /* A/D変換開始*/ while(GODONE); /*A/D変換が終わるまで待つ*/ ADIF=0; /*割り込みフラッグビットを0にする*/ volt0=(ADRESH*256)+ADRESL; /* A/D変換結果をvolt0に書く*/ if(volt0 < 303){ //*1.48V/5.0V*1024=303.1より*/ RB0 = 0; //充電on RB4 ^= 1; //充電中点滅 chg0 = 0; //充電中 } else if(volt0 >= 303){ //*1.48V以上 //充電完了 RB0 = 1; //充電off RB4 = 1; //充電完了点灯 chg0 = 10; //充電完了 } } charge1(){ CHS2=0; /*AN1ピンでvolt1の電圧をAD変換する*/ CHS1=0; CHS0=1; __delay_us(5); /* 5us待つ*/ GODONE=1; /* A/D変換開始*/ while(GODONE); /*A/D変換が終わるまで待つ*/ ADIF=0; /*割り込みフラッグビットを0にする*/ volt1=(ADRESH*256)+ADRESL; /* A/D変換結果をvolt1に書く*/ if(volt1 < 303){ //*1.48V/5.0V*1024=303.1より*/ RB1 = 0; //充電on RB5 ^= 1; //充電中点滅 chg1 = 0; //充電中 } else if(volt1 >= 303){ //*1.48V以上 //充電完了 RB1 = 1; //充電off RB5 = 1; //充電完了点灯 chg1 = 10; //充電完了 } } discharge0(){ /*電圧測定*/ CHS2=0; /*AN0ピンでvolt0の電圧をAD変換する*/ CHS1=0; CHS0=0; __delay_us(5); /* 5us待つ*/ GODONE=1; /* A/D変換開始*/ while(GODONE); /*A/D変換が終わるまで待つ*/ ADIF=0; /*割り込みフラッグビットを0にする*/ volt0=(ADRESH*256)+ADRESL; /* A/D変換結果をvolt0に書く*/ if(volt0 <= 205) { //*1.0V/5.0V*1024=204.8より*/ RC2 = 1; //放電終了点灯 RC4 = 0; //放電off dchg0 = 10; //放電終了 } else if(volt0 < 258){ //*1.26V/5.0V*1024=258より*/ RC2 ^= 1; //放電中点滅 RC4 = 1; //放電on dchg0 = 0; //放電中 } else if(volt0 >= 258){ //*1.26V*/ RC2 = 0; //放電無し消灯 RC4 = 0; //放電off dchg0 = 20; //放電無し } __delay_ms(JIKAN); /*ms待つ*/ } discharge1(){ CHS2=0; /*AN1ピンでvolt1の電圧をAD変換する*/ CHS1=0; CHS0=1; __delay_us(5); /* 5us待つ*/ GODONE=1; /* A/D変換開始*/ while(GODONE); /*A/D変換が終わるまで待つ*/ ADIF=0; /*割り込みフラッグビットを0にする*/ volt1=(ADRESH*256)+ADRESL; /* A/D変換結果をvolt1に書く*/ if(volt1 <= 205) { //*1.0V/5.0V*1024=204.8より*/ RC3 = 1; //放電終了点灯 RC5 = 0; //放電off dchg1 = 10; //放電終了 } else if(volt1 < 258){ //*1.26V/5.0V*1024=258より*/ RC3 ^= 1; //放電中点滅 RC5 = 1; //放電on dchg1 = 0; //放電中 } else if(volt1 >= 258){ //*1.26V*/ RC3 = 0; //放電無し消灯 RC5 = 0; //放電off dchg1 = 20; //放電無し } __delay_ms(JIKAN); /*ms待つ*/ } ioport() { TRISA=0x3F; /* b00111111 RA0,1,2,3,4,5ピンは入力ピン */ TRISB=0xC0; /* b11000000 RB0-5ピンは出力ピン RB6,7ピンは入力ピン*/ TRISC=0x03; /* b00000011 RC0,1ピンは入力、RC2-7ピンは出力ピン */ PCFG3=0; //AN0,AN1,AN2,AN3,AN4はアナログinput PCFG2=0; PCFG1=1; PCFG0=0; } tmr1_chk(){ if(TMR1IF){ //タイマー1がオーバーフローしたら1秒を+する TMR1H = 0x80; TMR1IF = 0; //割り込みリセット ++s; //秒を数える } }