############################################################################### # # # 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\IAR # # \Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debu # # g\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Li # # st\ --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\NIMHcharg # # e.lst # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\NIMHcharge # # .r90 # # # # # ############################################################################### 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 */ \ In segment CODE, align 2, keep-with-next 64 unsigned char Charge(unsigned char inp) \ Charge: 65 { \ 00000000 .... RCALL ?PROLOGUE2_L09 \ 00000002 2F90 MOV R25, R16 66 unsigned char NextState; 67 68 switch (CurrentState) { \ 00000004 9100.... LDS R16, CurrentState \ 00000008 510E SUBI R16, 30 \ 0000000A F049 BREQ ??Charge_0 \ 0000000C 5104 SUBI R16, 20 \ 0000000E F1D1 BREQ ??Charge_1 \ 00000010 500A SUBI R16, 10 \ 00000012 F409 BRNE $+2+2 \ 00000014 C06E RJMP ??Charge_2 \ 00000016 500A SUBI R16, 10 \ 00000018 F409 BRNE $+2+2 \ 0000001A C085 RJMP ??Charge_3 \ 0000001C C09F 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: \ 0000001E .... LDI R30, LOW(BattData) \ 00000020 .... LDI R31, (BattData) >> 8 \ 00000022 8104 LDD R16, Z+4 \ 00000024 8115 LDD R17, Z+5 \ 00000026 E04A LDI R20, 10 \ 00000028 E050 LDI R21, 0 \ 0000002A .... RCALL ?US_DIVMOD_L02 \ 0000002C .... LDI R30, LOW(ChargeParameters) \ 0000002E .... LDI R31, (ChargeParameters) >> 8 \ 00000030 8302 STD Z+2, R16 \ 00000032 8313 STD Z+3, R17 77 ChargeParameters.NextState = ST_FASTCHARGE; \ 00000034 E302 LDI R16, 50 \ 00000036 9300.... 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); \ 0000003A E302 LDI R16, 50 \ 0000003C 9300.... STS HaltParameters, R16 83 84 // Set up voltage limit and temperature limits. 85 HaltParameters.VoltageMax = BAT_VOLTAGE_PREQUAL; \ 00000040 EB08 LDI R16, 184 \ 00000042 E01B LDI R17, 11 \ 00000044 .... LDI R30, LOW(HaltParameters) \ 00000046 .... LDI R31, (HaltParameters) >> 8 \ 00000048 8303 STD Z+3, R16 \ 0000004A 8314 STD Z+4, R17 86 HaltParameters.TemperatureMin = BAT_TEMPERATURE_MIN; \ 0000004C E005 LDI R16, 5 \ 0000004E E010 LDI R17, 0 \ 00000050 .... LDI R30, LOW(HaltParameters) \ 00000052 .... LDI R31, (HaltParameters) >> 8 \ 00000054 8701 STD Z+9, R16 \ 00000056 8712 STD Z+10, R17 87 HaltParameters.TemperatureMax = 35; \ 00000058 E203 LDI R16, 35 \ 0000005A E010 LDI R17, 0 \ 0000005C .... LDI R30, LOW(HaltParameters) \ 0000005E .... LDI R31, (HaltParameters) >> 8 \ 00000060 8307 STD Z+7, R16 \ 00000062 8710 STD Z+8, R17 88 89 // Reset temperature measurement for HaltNow(). 90 HaltParameters.LastNTC = 0; \ 00000064 E000 LDI R16, 0 \ 00000066 E010 LDI R17, 0 \ 00000068 .... LDI R30, LOW(HaltParameters) \ 0000006A .... LDI R31, (HaltParameters) >> 8 \ 0000006C 8707 STD Z+15, R16 \ 0000006E 8B10 STD Z+16, R17 91 92 // Start PWM and charge timer before calling the charge function. 93 PWM_Start(); \ 00000070 .... RCALL PWM_Start 94 Time_Set(TIMER_CHG, BAT_TIME_PREQUAL, 0, 0); \ 00000072 E040 LDI R20, 0 \ 00000074 E010 LDI R17, 0 \ 00000076 E022 LDI R18, 2 \ 00000078 E030 LDI R19, 0 \ 0000007A E001 LDI R16, 1 \ 0000007C .... RCALL Time_Set 95 96 // Call charge function, get next state. 97 NextState = ConstantCurrent(); \ 0000007E .... RCALL ConstantCurrent \ 00000080 2F80 MOV R24, R16 \ 00000082 C06D 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: \ 00000084 .... LDI R30, LOW(BattData) \ 00000086 .... LDI R31, (BattData) >> 8 \ 00000088 8104 LDD R16, Z+4 \ 0000008A 8115 LDD R17, Z+5 \ 0000008C .... LDI R30, LOW(ChargeParameters) \ 0000008E .... LDI R31, (ChargeParameters) >> 8 \ 00000090 8302 STD Z+2, R16 \ 00000092 8313 STD Z+3, R17 109 ChargeParameters.NextState = ST_LOWRATECHARGE; \ 00000094 E30C LDI R16, 60 \ 00000096 9300.... 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); \ 0000009A E10B LDI R16, 27 \ 0000009C 9300.... 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; \ 000000A0 EC00 LDI R16, 192 \ 000000A2 E112 LDI R17, 18 \ 000000A4 .... LDI R30, LOW(HaltParameters) \ 000000A6 .... LDI R31, (HaltParameters) >> 8 \ 000000A8 8303 STD Z+3, R16 \ 000000AA 8314 STD Z+4, R17 119 HaltParameters.VoltageDrop = BAT_VOLTAGE_DROP; \ 000000AC E20D LDI R16, 45 \ 000000AE E010 LDI R17, 0 \ 000000B0 .... LDI R30, LOW(HaltParameters) \ 000000B2 .... LDI R31, (HaltParameters) >> 8 \ 000000B4 8301 STD Z+1, R16 \ 000000B6 8312 STD Z+2, R17 120 HaltParameters.TemperatureMax = BAT_TEMPERATURE_MAX; \ 000000B8 E302 LDI R16, 50 \ 000000BA E010 LDI R17, 0 \ 000000BC .... LDI R30, LOW(HaltParameters) \ 000000BE .... LDI R31, (HaltParameters) >> 8 \ 000000C0 8307 STD Z+7, R16 \ 000000C2 8710 STD Z+8, R17 121 HaltParameters.TemperatureRise = 1; \ 000000C4 E001 LDI R16, 1 \ 000000C6 E010 LDI R17, 0 \ 000000C8 .... LDI R30, LOW(HaltParameters) \ 000000CA .... LDI R31, (HaltParameters) >> 8 \ 000000CC 8703 STD Z+11, R16 \ 000000CE 8714 STD Z+12, R17 122 123 // Reset maximum voltage measurement for HaltNow(). 124 HaltParameters.VBATMax = 0; \ 000000D0 E000 LDI R16, 0 \ 000000D2 E010 LDI R17, 0 \ 000000D4 .... LDI R30, LOW(HaltParameters) \ 000000D6 .... LDI R31, (HaltParameters) >> 8 \ 000000D8 8705 STD Z+13, R16 \ 000000DA 8716 STD Z+14, R17 125 126 // Start timer, PWM should still be running. 127 Time_Set(TIMER_CHG, BattData.MaxTime, 0, 0); \ 000000DC E040 LDI R20, 0 \ 000000DE E010 LDI R17, 0 \ 000000E0 .... LDI R30, LOW(BattData) \ 000000E2 .... LDI R31, (BattData) >> 8 \ 000000E4 8520 LDD R18, Z+8 \ 000000E6 8531 LDD R19, Z+9 \ 000000E8 E001 LDI R16, 1 \ 000000EA .... RCALL Time_Set 128 129 // Call charge function, get next state. 130 NextState = ConstantCurrent(); \ 000000EC .... RCALL ConstantCurrent \ 000000EE 2F80 MOV R24, R16 \ 000000F0 C036 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: \ 000000F2 .... LDI R30, LOW(BattData) \ 000000F4 .... LDI R31, (BattData) >> 8 \ 000000F6 8104 LDD R16, Z+4 \ 000000F8 8115 LDD R17, Z+5 \ 000000FA E04A LDI R20, 10 \ 000000FC E050 LDI R21, 0 \ 000000FE .... RCALL ?US_DIVMOD_L02 \ 00000100 .... LDI R30, LOW(ChargeParameters) \ 00000102 .... LDI R31, (ChargeParameters) >> 8 \ 00000104 8302 STD Z+2, R16 \ 00000106 8313 STD Z+3, R17 140 ChargeParameters.NextState = ST_ENDCHARGE; \ 00000108 E406 LDI R16, 70 \ 0000010A 9300.... 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); \ 0000010E E10A LDI R16, 26 \ 00000110 9300.... STS HaltParameters, R16 146 147 // Start timer, 30 minutes. 148 Time_Set(TIMER_CHG, 30, 0, 0); \ 00000114 E040 LDI R20, 0 \ 00000116 E010 LDI R17, 0 \ 00000118 E12E LDI R18, 30 \ 0000011A E030 LDI R19, 0 \ 0000011C E001 LDI R16, 1 \ 0000011E .... RCALL Time_Set 149 150 // Call charge function, get next state. 151 NextState = ConstantCurrent(); \ 00000120 .... RCALL ConstantCurrent \ 00000122 2F80 MOV R24, R16 \ 00000124 C01C 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: \ 00000126 .... RCALL PWM_Stop 160 BattData.Charged = TRUE; \ 00000128 .... LDI R30, LOW(BattData) \ 0000012A .... LDI R31, (BattData) >> 8 \ 0000012C 8100 LD R16, Z \ 0000012E 6002 ORI R16, 0x02 \ 00000130 8300 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) { \ 00000132 9100.... LDS R16, BattActive \ 00000136 E010 LDI R17, 0 \ 00000138 5F0F SUBI R16, 255 \ 0000013A 4F1F SBCI R17, 255 \ 0000013C E042 LDI R20, 2 \ 0000013E E050 LDI R21, 0 \ 00000140 .... RCALL ?SS_DIVMOD_L02 \ 00000142 .... LDI R18, LOW(BattControl) \ 00000144 .... LDI R19, (BattControl) >> 8 \ 00000146 0F24 ADD R18, R20 \ 00000148 1F35 ADC R19, R21 \ 0000014A 01A9 MOVW R21:R20, R19:R18 \ 0000014C .... RCALL __eeget8_16 \ 0000014E 7001 ANDI R16, 0x01 \ 00000150 2300 TST R16 \ 00000152 F011 BREQ ??Charge_6 165 NextState = ST_BATCON; \ 00000154 E184 LDI R24, 20 \ 00000156 C003 RJMP ??Charge_5 166 } else { 167 NextState = ST_SLEEP; \ ??Charge_6: \ 00000158 E288 LDI R24, 40 \ 0000015A C001 RJMP ??Charge_5 168 } 169 break; 170 171 172 default: // Shouldn't end up here. Reinitialize for safety. 173 NextState = ST_INIT; \ ??Charge_4: \ 0000015C E08A LDI R24, 10 174 break; 175 } 176 177 // Return the next state to main(). 178 return(NextState); \ ??Charge_5: \ 0000015E 2F08 MOV R16, R24 \ 00000160 E0E2 LDI R30, 2 \ 00000162 .... RJMP ?EPILOGUE_B2_L09 179 } Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ Charge 2 4 -> PWM_Start 2 2 -> Time_Set 2 2 -> ConstantCurrent 2 2 -> Time_Set 2 2 -> ConstantCurrent 2 2 -> Time_Set 2 2 -> ConstantCurrent 2 2 -> PWM_Stop 2 2 Segment part sizes: Function/Label Bytes -------------- ----- Charge 356 356 bytes in segment CODE 356 bytes of CODE memory Errors: none Warnings: none