// // Battery charger // with PIC12F675 // 2011.5.7 (c)h_fujiwara_1995 #include "12F675.H" #device ADC=10 #fuses INTRC_IO,NOWDT,PROTECT,NOMCLR,BROWNOUT,PUT #use delay(internal=4MHz) // RA0 AN0 Battery2(Positive side) // RA1 AN1 Battery1(Negative side) // RA2 AN2 Current // RA3 N.C (MCLR) // RA4 OUT CHARGE FET-GATE // RA5 OUT LED #use fast_io(A) int16 get_ad() { int1 done; int16 value; read_adc(ADC_START_ONLY); done = adc_done(); while(!done) done=adc_done(); value=read_adc(ADC_READ_ONLY); return(value); } int16 get_ad64(int ch) { int16 v; int i; set_adc_channel(ch); delay_us(50); v=0; for(i=0;i<64;i++) v+=get_ad(); v= v >> 6; return(v); } #define FETPORT PIN_A4 #define LEDPORT PIN_A5 // charge mode #define NOBATTERY 0 #define PRECHARGE 1 #define CHARGING 2 #define FINISHCHG 3 #define MAXTIMECHG (144*60*10) #define PRECHARGETIME (5*60*10) #define MINCURRENT (15) #define NOBATTERYVOLTAGE (700) main() { int16 curr,battery,maxbattery; int mode,i; int32 timercount; // initialize set_tris_a(0x0f); output_low(LEDPORT); output_low(FETPORT); setup_adc(ADC_CLOCK_DIV_8); setup_adc_ports(sAN0 | sAN1 | sAN2); mode=NOBATTERY; maxbattery=0; while(1){ switch(mode){ case NOBATTERY: timercount=0; maxbattery=0; output_high(FETPORT); // test charge delay_ms(100); curr=get_ad64(2); // check current battery= get_ad64(0) - get_ad64(1); if(curr>MINCURRENT) mode=PRECHARGE; else {output_low(FETPORT);delay_ms(900);} break; case PRECHARGE: output_high(FETPORT); timercount++; if(timercount>=PRECHARGETIME){mode=CHARGING; break;} // after precharging, run to charge curr=get_ad64(2); if(curr=NOBATTERYVOLTAGE){mode=NOBATTERY;break;} // removed battery if(timercount > MAXTIMECHG){mode=FINISHCHG; break;}// timer over if(battery>maxbattery) maxbattery=battery; if(battery<(maxbattery-1)) mode=FINISHCHG; // delta peak detection break; case FINISHCHG: timercount=0; maxbattery=0; output_low(FETPORT); delay_ms(2000); battery= get_ad64(0) - get_ad64(1); if(battery>=NOBATTERYVOLTAGE) mode=NOBATTERY; // removed battery break; default: mode=NOBATTERY; break; } delay_ms(100); // loop interval switch(mode){ case NOBATTERY: output_low(LEDPORT);break; case PRECHARGE: output_high(LEDPORT);break; case CHARGING: if(timercount&2) output_high(LEDPORT); else output_low(LEDPORT); break; case FINISHCHG: output_high(LEDPORT);break; default:break; } } }