/////////////////////////////////////////////////////////////////////////////// // / // IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:38 / // Copyright 1996-2007 IAR Systems. All rights reserved. / // / // Source file = C:\home\kevin\pub\src\bc100_cal\IAR\NIMHcharge.c / // Command line = C:\home\kevin\pub\src\bc100_cal\IAR\NIMHcharge.c / // --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IA / // R\Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\De / // bug\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug / // \List\ --initializers_in_flash -z2 --no_cse / // --no_inline --no_code_motion --no_cross_call / // --no_clustering --no_tbaa --debug / // -DENABLE_BIT_DEFINITIONS -e --require_prototypes -I / // "C:\Program Files\IAR Systems\Embedded Workbench / // 4.0\avr\INC\" -I "C:\Program Files\IAR / // Systems\Embedded Workbench 4.0\avr\INC\CLIB\" / // --eeprom_size 512 / // List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\NIMHchar / // ge.s90 / // / // / /////////////////////////////////////////////////////////////////////////////// NAME NIMHcharge RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) EXTERN ?EPILOGUE_B2_L09 EXTERN ?PROLOGUE2_L09 EXTERN ?SS_DIVMOD_L02 EXTERN ?US_DIVMOD_L02 EXTERN __eeget8_16 PUBLIC Charge PUBWEAK __?EEARH PUBWEAK __?EEARL PUBWEAK __?EECR PUBWEAK __?EEDR EXTERN PWM_Start EXTERN Time_Set EXTERN ConstantCurrent EXTERN PWM_Stop EXTERN BattActive EXTERN BattControl EXTERN BattData EXTERN ChargeParameters EXTERN CurrentState EXTERN HaltParameters // C:\home\kevin\pub\src\bc100_cal\IAR\NIMHcharge.c // 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ // 2 /*! \file ********************************************************************* // 3 * // 4 * \brief // 5 * Charge state function for NiMH batteries // 6 * // 7 * Contains the charge state function, in which the NiMH charging // 8 * algorithm is, plus the associated functions. // 9 * // 10 * \par Application note: // 11 * AVR463: Charging NiMH Batteries with BC100 \n // 12 * // 13 * \par Documentation // 14 * For comprehensive code documentation, supported compilers, compiler // 15 * settings and supported devices see readme.html // 16 * // 17 * \author // 18 * Atmel Corporation: http://www.atmel.com \n // 19 * Support email: avr@atmel.com // 20 * // 21 * // 22 * $Name$ // 23 * $Revision: 2255 $ // 24 * $RCSfile$ // 25 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr463_Charging_NiMH_Batteries_with_BC100/trunk/code/IAR/NIMHcharge.c $ // 26 * $Date: 2007-08-09 14:47:58 +0200 (to, 09 aug 2007) $\n // 27 ******************************************************************************/ // 28 // 29 #include // 30 // 31 #include "enums.h" // 32 #include "structs.h" // 33 // 34 #include "battery.h" // 35 #include "charge.h" // 36 #include "chargefunc.h" // 37 #include "main.h" // 38 #include "menu.h" // 39 #include "NIMHspecs.h" // 40 #include "PWM.h" // 41 #include "time.h" // 42 // 43 #ifndef NIMH // 44 #error NIMH not defined in main.h! // 45 #endif // NIMH // 46 // 47 // 48 //****************************************************************************** // 49 // Functions // 50 //****************************************************************************** // 51 /*! \brief Controls the charging. // 52 * // 53 * This function contains the charging algorithm itself, divided into stages.\n // 54 * For each stage the PWM may be started/stopped, and the timer, // 55 * halt-requirements and charge parameters may be set.\n // 56 * The charging functions return whatever state is next, and as long as no // 57 * errors occur this is the next charging stage. // 58 * // 59 * \note If more stages are needed simply define more states in menu.h, include // 60 * them in \ref menu_state[] in menu.c, then add the cases to this function. // 61 * // 62 * \note This algorithm is for NiMH batteries. // 63 */ RSEG CODE:CODE:NOROOT(1) // 64 unsigned char Charge(unsigned char inp) Charge: // 65 { RCALL ?PROLOGUE2_L09 MOV R25, R16 // 66 unsigned char NextState; // 67 // 68 switch (CurrentState) { LDS R16, CurrentState SUBI R16, 30 BREQ ??Charge_0 SUBI R16, 20 BREQ ??Charge_1 SUBI R16, 10 BRNE $+2+2 RJMP ??Charge_2 SUBI R16, 10 BRNE $+2+2 RJMP ??Charge_3 RJMP ??Charge_4 // 69 // First stage is a prequalification. Attempt to charge battery to 1 V, // 70 // using a 0.1 C current, within 2 minutes. // 71 // If this fails, the battery is likely damaged. // 72 // If it succeeds, start a fast charge. // 73 case ST_PREQUAL: // 74 // 75 // Set up charge current and next state. // 76 ChargeParameters.Current = BattData.Capacity / 10; ??Charge_0: LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 LDD R16, Z+4 LDD R17, Z+5 LDI R20, 10 LDI R21, 0 RCALL ?US_DIVMOD_L02 LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 STD Z+2, R16 STD Z+3, R17 // 77 ChargeParameters.NextState = ST_FASTCHARGE; LDI R16, 50 STS (ChargeParameters + 4), R16 // 78 // 79 // Halt charge on voltage limit or timeout. // 80 // Timeout means battery exhaustion. // 81 HaltParameters.HaltFlags = (HALT_VOLTAGE_MAX | HALT_TIME | // 82 HALT_FLAG_EXHAUSTION); LDI R16, 50 STS HaltParameters, R16 // 83 // 84 // Set up voltage limit and temperature limits. // 85 HaltParameters.VoltageMax = BAT_VOLTAGE_PREQUAL; LDI R16, 184 LDI R17, 11 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+3, R16 STD Z+4, R17 // 86 HaltParameters.TemperatureMin = BAT_TEMPERATURE_MIN; LDI R16, 5 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+9, R16 STD Z+10, R17 // 87 HaltParameters.TemperatureMax = 35; LDI R16, 35 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+7, R16 STD Z+8, R17 // 88 // 89 // Reset temperature measurement for HaltNow(). // 90 HaltParameters.LastNTC = 0; LDI R16, 0 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+15, R16 STD Z+16, R17 // 91 // 92 // Start PWM and charge timer before calling the charge function. // 93 PWM_Start(); RCALL PWM_Start // 94 Time_Set(TIMER_CHG, BAT_TIME_PREQUAL, 0, 0); LDI R20, 0 LDI R17, 0 LDI R18, 2 LDI R19, 0 LDI R16, 1 RCALL Time_Set // 95 // 96 // Call charge function, get next state. // 97 NextState = ConstantCurrent(); RCALL ConstantCurrent MOV R24, R16 RJMP ??Charge_5 // 98 break; // 99 // 100 // 101 // Second stage is a fast charge. Charge at 1.0 C for at most 1.5 hours, // 102 // until either rate of temperature increase or voltage reaches limit, or // 103 // the voltage drops sufficiently. // 104 // Timeout doesn't mean battery exhaustion now. // 105 case ST_FASTCHARGE: // 106 // 107 // Set up charge current and next state. // 108 ChargeParameters.Current = BattData.Capacity; ??Charge_1: LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 LDD R16, Z+4 LDD R17, Z+5 LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 STD Z+2, R16 STD Z+3, R17 // 109 ChargeParameters.NextState = ST_LOWRATECHARGE; LDI R16, 60 STS (ChargeParameters + 4), R16 // 110 // 111 // Halt charge on voltage limit, timeout, voltage drop or rate of // 112 // temperature increase. // 113 HaltParameters.HaltFlags = (HALT_VOLTAGE_MAX | HALT_TIME | // 114 HALT_VOLTAGE_DROP | HALT_TEMPERATURE_RISE); LDI R16, 27 STS HaltParameters, R16 // 115 // 116 // Set up limits for voltage, voltage drop, temperature and rate of // 117 // temperature increase (1 degree C per minute). // 118 HaltParameters.VoltageMax = BAT_VOLTAGE_MAX; LDI R16, 192 LDI R17, 18 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+3, R16 STD Z+4, R17 // 119 HaltParameters.VoltageDrop = BAT_VOLTAGE_DROP; LDI R16, 45 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+1, R16 STD Z+2, R17 // 120 HaltParameters.TemperatureMax = BAT_TEMPERATURE_MAX; LDI R16, 50 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+7, R16 STD Z+8, R17 // 121 HaltParameters.TemperatureRise = 1; LDI R16, 1 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+11, R16 STD Z+12, R17 // 122 // 123 // Reset maximum voltage measurement for HaltNow(). // 124 HaltParameters.VBATMax = 0; LDI R16, 0 LDI R17, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+13, R16 STD Z+14, R17 // 125 // 126 // Start timer, PWM should still be running. // 127 Time_Set(TIMER_CHG, BattData.MaxTime, 0, 0); LDI R20, 0 LDI R17, 0 LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 LDD R18, Z+8 LDD R19, Z+9 LDI R16, 1 RCALL Time_Set // 128 // 129 // Call charge function, get next state. // 130 NextState = ConstantCurrent(); RCALL ConstantCurrent MOV R24, R16 RJMP ??Charge_5 // 131 break; // 132 // 133 // 134 // Last stage is a trickle charge. Charge at 0.1 C for at most 30 minutes, // 135 // until either rate of temperature increase or voltage reaches limit. // 136 case ST_LOWRATECHARGE: // 137 // 138 // Set up charge current and next state. // 139 ChargeParameters.Current = BattData.Capacity / 10; ??Charge_2: LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 LDD R16, Z+4 LDD R17, Z+5 LDI R20, 10 LDI R21, 0 RCALL ?US_DIVMOD_L02 LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 STD Z+2, R16 STD Z+3, R17 // 140 ChargeParameters.NextState = ST_ENDCHARGE; LDI R16, 70 STS (ChargeParameters + 4), R16 // 141 // 142 // Halt charge on voltage limit, timeout or temperature rise. // 143 // Use the same requirements as during the last stage (ST_FASTCHARGE). // 144 HaltParameters.HaltFlags = (HALT_VOLTAGE_MAX | HALT_TIME | // 145 HALT_TEMPERATURE_RISE); LDI R16, 26 STS HaltParameters, R16 // 146 // 147 // Start timer, 30 minutes. // 148 Time_Set(TIMER_CHG, 30, 0, 0); LDI R20, 0 LDI R17, 0 LDI R18, 30 LDI R19, 0 LDI R16, 1 RCALL Time_Set // 149 // 150 // Call charge function, get next state. // 151 NextState = ConstantCurrent(); RCALL ConstantCurrent MOV R24, R16 RJMP ??Charge_5 // 152 break; // 153 // 154 // 155 // Charging is done! // 156 case ST_ENDCHARGE: // 157 // 158 // Stop the PWM output and flag battery as charged. // 159 PWM_Stop(); ??Charge_3: RCALL PWM_Stop // 160 BattData.Charged = TRUE; LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 LD R16, Z ORI R16, 0x02 ST Z, R16 // 161 // 162 // If the other battery is enabled go to ST_BATCON, otherwise // 163 // go to ST_SLEEP. // 164 if (BattControl[(BattActive+1)%2].Enabled) { LDS R16, BattActive LDI R17, 0 SUBI R16, 255 SBCI R17, 255 LDI R20, 2 LDI R21, 0 RCALL ?SS_DIVMOD_L02 LDI R18, LOW(BattControl) LDI R19, (BattControl) >> 8 ADD R18, R20 ADC R19, R21 MOVW R21:R20, R19:R18 RCALL __eeget8_16 ANDI R16, 0x01 TST R16 BREQ ??Charge_6 // 165 NextState = ST_BATCON; LDI R24, 20 RJMP ??Charge_5 // 166 } else { // 167 NextState = ST_SLEEP; ??Charge_6: LDI R24, 40 RJMP ??Charge_5 // 168 } // 169 break; // 170 // 171 // 172 default: // Shouldn't end up here. Reinitialize for safety. // 173 NextState = ST_INIT; ??Charge_4: LDI R24, 10 // 174 break; // 175 } // 176 // 177 // Return the next state to main(). // 178 return(NextState); ??Charge_5: MOV R16, R24 LDI R30, 2 RJMP ?EPILOGUE_B2_L09 // 179 } ASEGN ABSOLUTE:DATA:NOROOT,01cH __?EECR: ASEGN ABSOLUTE:DATA:NOROOT,01dH __?EEDR: ASEGN ABSOLUTE:DATA:NOROOT,01eH __?EEARL: ASEGN ABSOLUTE:DATA:NOROOT,01fH __?EEARH: END // // 356 bytes in segment CODE // // 356 bytes of CODE memory // //Errors: none //Warnings: none