Contains the functions for charging with constant current and voltage, and for deciding when to halt.
Definition in file chargefunc.c.
#include <ioavr.h>
#include "enums.h"
#include "structs.h"
#include "ADC.h"
#include "battery.h"
#include "chargefunc.h"
#include "main.h"
#include "menu.h"
#include "PWM.h"
#include "statefunc.h"
#include "time.h"
#include "LIIONspecs.h"
Go to the source code of this file.
Functions | |
unsigned char | ConstantCurrent (void) |
Charges battery with a constant current. | |
unsigned char | ConstantVoltage (void) |
Charges battery with a constant voltage. | |
unsigned char | HaltNow (void) |
Determines when to halt charging. | |
unsigned char | MaxVoltageAndCurrent (void) |
Charges battery with maximum allowable voltage or current. | |
Variables | |
ChargeParameters_t | ChargeParameters |
Struct that holds parameters for ConstantCurrent() and ConstantVoltage(). | |
HaltParameters_t | HaltParameters |
Struct that holds parameters for HaltNow(). |
unsigned char ConstantCurrent | ( | void | ) |
Charges battery with a constant current.
This function applies a constant current (set in ChargeParameters.Current) to the battery until HaltNow() returns TRUE, or a PWM error occurs and ABORT_IF_PWM_MIN or ABORT_IF_PWM_MAX is defined.
The charge current can vary with +/- BAT_CURRENT_HYST.
If the Master inhibits charging, timers are stopped and PWM output dropped. Once the battery is no longer flagged for charge inhibit, timers are started again and charging resumed.
ChargeParameters.NextState | Next state once this stage is done. If no errors occured, this will be whatever was set in Charge(). Otherwise, HaltNow() will have set a new next state. |
Definition at line 80 of file chargefunc.c.
References ADC_Wait(), ADCS, ADC_Status_struct::avgIBAT, BAT_CURRENT_HYST, BattActive, BattControl, ChargeParameters_struct::Current, ERR_PWM_CONTROL, FALSE, HaltNow(), ChargeParameters_struct::NextState, PWM_DecrementDutyCycle(), PWM_IncrementDutyCycle(), SetErrorFlag(), ST_ERROR, Time_Start(), Time_Stop(), and TRUE.
Referenced by Charge().
00081 { 00082 unsigned char error = FALSE, 00083 wasStopped = FALSE; 00084 00085 do { 00086 // Wait for ADC conversions to complete. 00087 ADC_Wait(); 00088 00089 // If Master has flagged for a charge inhibit, pause charging. 00090 // (This is to prevent damage during prolonged serial communication.) 00091 if (BattControl[BattActive].ChargeInhibit) { 00092 wasStopped = TRUE; 00093 Time_Stop(); 00094 OCR1B = 0; 00095 } else { 00096 // Continue charging! 00097 if (wasStopped) { 00098 wasStopped = FALSE; 00099 00100 // Timer variables are not reset by this. 00101 Time_Start(); 00102 } 00103 00104 // Adjust the charge current to within ChargeParameters.Current 00105 // +/- BAT_CURRENT_HYST. 00106 if ((ADCS.avgIBAT < 0) || 00107 (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) { 00108 00109 if(!PWM_IncrementDutyCycle()) { 00110 #ifdef ABORT_IF_PWM_MAX 00111 // If the duty cycle cannot be incremented, flag error and 00112 // go to error state. 00113 SetErrorFlag(ERR_PWM_CONTROL); 00114 ChargeParameters.NextState = ST_ERROR; 00115 error = TRUE; 00116 #endif 00117 } 00118 } else if ((ADCS.avgIBAT >= 0) && 00119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) { 00120 00121 if(!PWM_DecrementDutyCycle()) { 00122 #ifdef ABORT_IF_PWM_MIN 00123 // If the duty cycle cannot be decremented, flag error and 00124 // go to error state. 00125 SetErrorFlag(ERR_PWM_CONTROL); 00126 ChargeParameters.NextState = ST_ERROR; 00127 error = TRUE; 00128 #endif 00129 } 00130 } 00131 } 00132 } while (!HaltNow() && !error); 00133 00134 // Return the next state to Charge(). If an error has occured, this will 00135 // point to some other state than the next state of charging. 00136 return(ChargeParameters.NextState); 00137 }
unsigned char ConstantVoltage | ( | void | ) |
Charges battery with a constant voltage.
This function applies a constant voltage (set in ChargeParameters.Voltage) to the battery until HaltNow() returns TRUE, or a PWM error occurs and ABORT_IF_PWM_MIN or ABORT_IF_PWM_MAX is defined.
The charge voltage can vary with +/- BAT_VOLTAGE_HYST.
If the Master inhibits charging, timers are stopped and PWM output dropped. Once the battery is no longer flagged for charge inhibit, timers are started again and charging resumed.
ChargeParameters.NextState | Next state once this stage is done. If no errors occured, this will be whatever was set in Charge(). Otherwise, HaltNow() will have set a new next state. |
Definition at line 154 of file chargefunc.c.
References ADC_Wait(), ADCS, BAT_VOLTAGE_HYST, BattActive, BattControl, ERR_PWM_CONTROL, FALSE, HaltNow(), ChargeParameters_struct::NextState, PWM_DecrementDutyCycle(), PWM_IncrementDutyCycle(), SetErrorFlag(), ST_ERROR, Time_Start(), Time_Stop(), TRUE, ADC_Status_struct::VBAT, and ChargeParameters_struct::Voltage.
Referenced by Charge().
00155 { 00156 unsigned char error = FALSE, 00157 wasStopped = FALSE; 00158 00159 do{ 00160 00161 // Wait for ADC conversions to complete. 00162 ADC_Wait(); 00163 00164 // If Master has flagged for a charge inhibit, pause charging. 00165 // (This is to prevent damage during prolonged serial communication.) 00166 if (BattControl[BattActive].ChargeInhibit) { 00167 wasStopped = TRUE; 00168 Time_Stop(); 00169 OCR1B = 0; 00170 } 00171 00172 else { 00173 // Continue charging! 00174 if (wasStopped) { 00175 wasStopped = FALSE; 00176 00177 // Timer variables aren't reset by this. 00178 Time_Start(); 00179 } 00180 00181 // Adjust the charge voltage to within ChargeParameters.Voltage 00182 // +/- BAT_VOLTAGE_HYST. 00183 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) { 00184 00185 if(!PWM_IncrementDutyCycle()) { 00186 #ifdef ABORT_IF_PWM_MAX 00187 // Flag PWM control error and go to error-state if the duty 00188 // cycle cannot be incremented. 00189 SetErrorFlag(ERR_PWM_CONTROL); 00190 ChargeParameters.NextState = ST_ERROR; 00191 error = TRUE; 00192 #endif 00193 } 00194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) { 00195 00196 if(!PWM_DecrementDutyCycle()) { 00197 #ifdef ABORT_IF_PWM_MIN 00198 // Flag PWM control error and go to error-state if duty 00199 // cycle cannot be decremented. 00200 SetErrorFlag(ERR_PWM_CONTROL); 00201 ChargeParameters.NextState = ST_ERROR; 00202 error = TRUE; 00203 #endif 00204 } 00205 } 00206 } 00207 00208 } while (!HaltNow() && !error); 00209 00210 // Return the next state to Charge(). If an error has occured, this will 00211 // point to some other state than the next state of charging. 00212 return(ChargeParameters.NextState); 00213 }
unsigned char HaltNow | ( | void | ) |
Determines when to halt charging.
This function evaluates parameters depending on what has been flagged in HaltParameters.HaltFlags, and returns TRUE or FALSE if the charging should halt or not.
In addition, error flagging on timeout (battery exhaustion) can be set.
The function also checks if the battery temperature is within limits, if mains is OK, and if BatteryCheck() returns TRUE. If an error is detected, the associated errorflag is set and ChargeParameters.NextState is changed to an appropriate state.
TRUE | Halt now. | |
FALSE | Don't halt now. |
It is generally a bad idea not to halt on a timeout.
If HALT_ON_VOLTAGE_DROP is set, HaltParameters.VBATMax should be reset in Charge() before calling a charging-function.
Definition at line 445 of file chargefunc.c.
References ADC_Wait(), ADCS, Batteries_struct::ADCSteps, ADC_Status_struct::avgIBAT, BattActive, BattControl, BattData, BatteryCheck(), Battery_struct::ChargeInhibit, HaltParameters_struct::CurrentMin, Battery_struct::Enabled, ERR_BATTERY_EXHAUSTED, ERR_BATTERY_TEMPERATURE, Batteries_struct::Exhausted, FALSE, HALT_CURRENT_MIN, HALT_FLAG_EXHAUSTION, HALT_TEMPERATURE_RISE, HALT_TIME, HALT_VOLTAGE_DROP, HALT_VOLTAGE_MAX, HaltParameters_struct::HaltFlags, HaltParameters_struct::LastNTC, ADC_Status_struct::Mains, ChargeParameters_struct::NextState, NTCLookUp(), PWM_Stop(), ADC_Status_struct::rawNTC, SetErrorFlag(), ST_ERROR, ST_INIT, ST_SLEEP, Batteries_struct::Temperature, HaltParameters_struct::TemperatureMax, HaltParameters_struct::TemperatureMin, HaltParameters_struct::TemperatureRise, Time_Left(), Time_Set(), TIMER_CHG, TIMER_TEMP, TRUE, ADC_Status_struct::VBAT, HaltParameters_struct::VBATMax, HaltParameters_struct::VoltageDrop, and HaltParameters_struct::VoltageMax.
Referenced by ConstantCurrent(), ConstantVoltage(), and MaxVoltageAndCurrent().
00446 { 00447 unsigned char i, halt = FALSE; 00448 00449 // Wait for a full ADC-cycle to finish. 00450 ADC_Wait(); 00451 NTCLookUp(); 00452 00453 // Evaluate ADC readings according to HaltFlags. Flag errors if selected. 00454 // If an error is flagged, ChargeParameters.NextState is set to ST_ERROR. 00455 // (Gets overridden if either mains is failing, or the battery changes.) 00456 for (i = 0x01; i != 0; i <<= 1) { 00457 if (HaltParameters.HaltFlags & i) { 00458 switch (i) { 00459 // Is VBAT less than the recorded maximum? 00460 case HALT_VOLTAGE_DROP: 00461 00462 // Update VBATMax if VBAT is higher or charge is inhibited by master. 00463 // Evaluate for halt otherwise. 00464 if (ADCS.VBAT > HaltParameters.VBATMax || 00465 BattControl[BattActive].ChargeInhibit) { 00466 HaltParameters.VBATMax = ADCS.VBAT; 00467 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= 00468 HaltParameters.VoltageDrop) { 00469 halt = TRUE; 00470 } 00471 break; 00472 00473 00474 // Has VBAT reached the maximum limit? 00475 case HALT_VOLTAGE_MAX: 00476 00477 if (ADCS.VBAT >= HaltParameters.VoltageMax) { 00478 halt = TRUE; 00479 } 00480 break; 00481 00482 00483 // Has IBAT reached the minimum limit? 00484 case HALT_CURRENT_MIN: 00485 00486 // If the charging current has dropped below the minimum threshold and 00487 // charging is not inhibited by master, flag a halt. 00488 if (ADCS.avgIBAT <= HaltParameters.CurrentMin && 00489 !BattControl[BattActive].ChargeInhibit) { 00490 halt = TRUE; 00491 } 00492 break; 00493 00494 00495 // Is the temperature rising too fast? 00496 case HALT_TEMPERATURE_RISE: 00497 00498 // If rawNTC has increased, the temperature has dropped. 00499 // We can store this value for now, and start the timer. 00500 // Otherwise, check if NTC has changed too fast. 00501 if (ADCS.rawNTC > HaltParameters.LastNTC) { 00502 HaltParameters.LastNTC = ADCS.rawNTC; 00503 Time_Set(TIMER_TEMP,0,30,0); 00504 00505 // Is the increase in temperature greater than the set threshold? 00506 } else if ((HaltParameters.LastNTC - ADCS.rawNTC) >= 00507 (BattData.ADCSteps * HaltParameters.TemperatureRise)) { 00508 00509 // If this happened within a timeframe of 30 seconds, the 00510 // temperature is rising faster than we want. 00511 // If not, update LastNTC and reset timer. 00512 if (Time_Left(TIMER_TEMP)) { 00513 halt = TRUE; 00514 } else { 00515 HaltParameters.LastNTC = ADCS.rawNTC; 00516 Time_Set(TIMER_TEMP,0,30,0); 00517 } 00518 } 00519 break; 00520 00521 00522 // Is there any time left? 00523 case HALT_TIME: 00524 00525 if (!Time_Left(TIMER_CHG)) { 00526 halt = TRUE; 00527 00528 // If exhaustion flagging is selected, stop the PWM, disable the 00529 // battery and flag it as exhausted. Make ST_ERROR next state. 00530 if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) { 00531 PWM_Stop(); 00532 BattControl[BattActive].Enabled = FALSE; 00533 BattData.Exhausted = TRUE; 00534 SetErrorFlag(ERR_BATTERY_EXHAUSTED); 00535 ChargeParameters.NextState = ST_ERROR; 00536 } 00537 } 00538 break; 00539 00540 00541 default: // Shouldn't end up here, but is needed for MISRA compliance. 00542 break; 00543 } 00544 } 00545 } 00546 00547 // Standard checks: 00548 00549 // Battery too cold or hot? 00550 if ((BattData.Temperature < HaltParameters.TemperatureMin) || 00551 (BattData.Temperature > HaltParameters.TemperatureMax)) { 00552 00553 PWM_Stop(); 00554 SetErrorFlag(ERR_BATTERY_TEMPERATURE); 00555 ChargeParameters.NextState = ST_ERROR; 00556 halt = TRUE; 00557 } 00558 00559 // Battery not OK? 00560 if (!BatteryCheck()) { 00561 PWM_Stop(); 00562 ChargeParameters.NextState = ST_INIT; 00563 halt = TRUE; 00564 } 00565 00566 // Is mains voltage OK? 00567 if (!ADCS.Mains) { 00568 PWM_Stop(); 00569 ChargeParameters.NextState = ST_SLEEP; 00570 halt = TRUE; 00571 } 00572 00573 return(halt); 00574 }
unsigned char MaxVoltageAndCurrent | ( | void | ) |
Charges battery with maximum allowable voltage or current.
This function charges in compliance with the Japanese regulations for battery chargers, which specify maximum charge currents and voltages for four temperature ranges:
ID_|_Temp. range____|_Maximum I_|_Maximum U______ T0 | 0 - 10 deg. C | IC / IC/2 | 4.10 V / 4.25 V T1 | 10 - 45 deg. C | IC | 4.25 V T2 | 45 - 50 deg. C | IC | 4.15 V T3 | 50 - 60 deg. C | IC | 4.10 V
The maximum current or voltage for each temperature range is applied to the battery until HaltNow() returns TRUE, or a PWM error occurs and ABORT_IF_PWM_MIN or ABORT_IF_PWM_MAX is defined.
Note that IC will depend on the type of battery, and may be less than 1 C. This implementation uses whatever maximum current is set by the Resistor ID lookup, which would be either something from the RID lookup-table, or the default set in battery.h (if charging without RID is enabled).
Also, this function does not stop charging if the temperature is out of range, i.e., below 0 or above 60 degrees C. Instead, this is done by HaltNow() which relies on the limits (BAT_TEMPERATURE_MAX and BAT_TEMPERATURE_IN) defined in LIIONspecs.h or NIMHspecs::h.
If the Master inhibits charging, timers are stopped and PWM output dropped. Once the battery is no longer flagged for charge inhibit, timers are started again and charging resumed.
ChargeParameters.NextState | Next state once this stage is done. If no errors occured, this will be whatever was set in Charge(). Otherwise, HaltNow() will have set a new next state. |
To prevent "borderline" temperatures from causing the charging parameters to constantly change, a temperature hysteresis, defined in chargefunc.h , is used.
Definition at line 257 of file chargefunc.c.
References ADC_Wait(), ADCS, ADC_Status_struct::avgIBAT, BAT_CURRENT_HYST, BAT_VOLTAGE_HYST, BAT_VOLTAGE_MAX, BAT_VOLTAGE_MAX_T0, BAT_VOLTAGE_MAX_T2, BAT_VOLTAGE_MAX_T3, BattActive, BattControl, BattData, ChargeParameters_struct::Current, ERR_PWM_CONTROL, FALSE, HaltNow(), Batteries_struct::MaxCurrent, ChargeParameters_struct::NextState, NTCLookUp(), PWM_DecrementDutyCycle(), PWM_IncrementDutyCycle(), SetErrorFlag(), ST_ERROR, T0, T1, T2, T3, TEMP_HYST, Batteries_struct::Temperature, Time_Start(), Time_Stop(), TRUE, ADC_Status_struct::VBAT, and ChargeParameters_struct::Voltage.
Referenced by Charge().
00258 { 00259 unsigned char error = FALSE, 00260 wasStopped = FALSE, 00261 tempRangeChange; 00262 00263 signed char lastTempRange = -1; // Must be set to an "illegal" temperature 00264 // in the first iteration. 00265 00266 do { 00267 // Wait for ADC conversions to complete, then find the temperature. 00268 ADC_Wait(); 00269 NTCLookUp(); 00270 00271 // If Master has flagged for a charge inhibit, pause charging. 00272 // (This is to prevent damage during prolonged serial communication.) 00273 if (BattControl[BattActive].ChargeInhibit) { 00274 wasStopped = TRUE; 00275 Time_Stop(); 00276 OCR1B = 0; 00277 } 00278 else { 00279 // Continue charging! 00280 if (wasStopped) { 00281 wasStopped = FALSE; 00282 00283 // Timer variables are not reset by this. 00284 Time_Start(); 00285 } 00286 00287 // Temperature hysteresis, allow some drift around the transitional values. 00288 // (Compare the new temperature with the hysteresis boundaries of the 00289 // previously set temperature range, and flag for a change if the new 00290 // temperature deviates beyond the hysteresis. 00291 tempRangeChange = FALSE; // Start by assuming no change in temp. range. 00292 00293 // See if the temperature range has changed, flag if it has. Handle T0! 00294 switch (lastTempRange) { 00295 case T0 : 00296 if ((BattData.Temperature - T0) > TEMP_HYST) { 00297 tempRangeChange = TRUE; 00298 } 00299 else { 00300 // We need to do this check if we're staying in this range: 00301 // If the battery voltage is below threshold #1 for T0, attempt to 00302 // regulate the charge current to max 1.0C and voltage to max 4.10 V. 00303 // If the battery voltage is above threshold #1 for T0, attempt to 00304 // regulate the charge current to max 0.5C and voltage to max 4.25 V. 00305 00306 // This will cause a kind of "oscillation" starting when battery 00307 // voltage reaches 4.10 V, and ending once the battery voltage 00308 // surpasses 4.10 V for currents below 0.5 C, after which the 00309 // function will keep applying 4.25 V. 00310 // It will not cause any of the regulation limits to be crossed. 00311 if (ADCS.VBAT <= BAT_VOLTAGE_MAX_T0) { 00312 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T0; 00313 ChargeParameters.Current = BattData.MaxCurrent; 00314 } 00315 else { 00316 ChargeParameters.Voltage = BAT_VOLTAGE_MAX; 00317 ChargeParameters.Current = BattData.MaxCurrent/2; 00318 } 00319 } 00320 break; 00321 00322 00323 case T1 : 00324 if ((BattData.Temperature - T1) > TEMP_HYST 00325 || (T0 - BattData.Temperature) > TEMP_HYST) { 00326 tempRangeChange = TRUE; 00327 } 00328 break; 00329 00330 00331 case T2 : 00332 if ((BattData.Temperature - T2) > TEMP_HYST 00333 || (T1 - BattData.Temperature) >= TEMP_HYST) { 00334 tempRangeChange = TRUE; 00335 } 00336 break; 00337 00338 00339 case T3 : 00340 if ((T2 - BattData.Temperature) > TEMP_HYST) { 00341 tempRangeChange = TRUE; 00342 } 00343 break; 00344 00345 00346 // This should only happen in first iteration. 00347 default : tempRangeChange = TRUE; 00348 } 00349 00350 // If a change in temperature range was flagged, update charge parameters. 00351 if (tempRangeChange) { 00352 // Find new temperature range, set maximum charge current and voltage. 00353 00354 if (BattData.Temperature <= T0) { // [-inf,T0] degrees C 00355 if (ADCS.VBAT <= BAT_VOLTAGE_MAX_T0) { 00356 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T0; 00357 ChargeParameters.Current = BattData.MaxCurrent; 00358 } 00359 else { 00360 ChargeParameters.Voltage = BAT_VOLTAGE_MAX; 00361 ChargeParameters.Current = BattData.MaxCurrent/2; 00362 } 00363 lastTempRange = T0; 00364 } 00365 00366 else { 00367 // The other temperature ranges all allow charging at maximum 1.0 C, 00368 // but have different maximum voltages. 00369 ChargeParameters.Current = BattData.MaxCurrent; 00370 00371 if (BattData.Temperature <= T1) { // (T0,T1] 00372 ChargeParameters.Voltage = BAT_VOLTAGE_MAX; 00373 lastTempRange = T1; 00374 } 00375 else if (BattData.Temperature <= T2) { // (T1,T2] 00376 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T2; 00377 lastTempRange = T2; 00378 } 00379 else { // (T2,inf] 00380 ChargeParameters.Voltage = BAT_VOLTAGE_MAX_T3; 00381 lastTempRange = T3; 00382 } 00383 } 00384 } 00385 00386 // If both charge voltage and current are below limits, the PWM output may 00387 // be increased. 00388 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST) && 00389 ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST)) { 00390 00391 if(!PWM_IncrementDutyCycle()) { 00392 #ifdef ABORT_IF_PWM_MAX 00393 // If the duty cycle cannot be incremented, flag error and 00394 // go to error state. 00395 SetErrorFlag(ERR_PWM_CONTROL); 00396 ChargeParameters.NextState = ST_ERROR; 00397 error = TRUE; 00398 #endif 00399 } 00400 // If either voltage or current is above limit + hysteresis, reduce output. 00401 } 00402 if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST) || 00403 ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST)) { 00404 if(!PWM_DecrementDutyCycle()) { 00405 #ifdef ABORT_IF_PWM_MIN 00406 // If the duty cycle cannot be decremented, flag error and 00407 // go to error state. 00408 SetErrorFlag(ERR_PWM_CONTROL); 00409 ChargeParameters.NextState = ST_ERROR; 00410 error = TRUE; 00411 #endif 00412 } 00413 } 00414 } 00415 } while (!HaltNow() && !error); 00416 00417 // Return the next state to Charge(). If an error has occured, this will 00418 // point to some other state than the next state of charging. 00419 return(ChargeParameters.NextState); 00420 }
Struct that holds parameters for ConstantCurrent() and ConstantVoltage().
Definition at line 57 of file chargefunc.c.
Referenced by Charge().
Struct that holds parameters for HaltNow().
Definition at line 60 of file chargefunc.c.
Referenced by Charge().