############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 13/Mar/2008 04:52:02 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100\IAR\NIMHcharge.c # # Command line = C:\home\kevin\pub\src\bc100\IAR\NIMHcharge.c # # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc10 # # 0\IAR\Release\Obj\ -D NDEBUG -lCN # # C:\home\kevin\pub\src\bc100\IAR\Release\List\ # # -lB C:\home\kevin\pub\src\bc100\IAR\Release\Lis # # t\ --initializers_in_flash -s9 --no_cross_call # # --no_tbaa -DENABLE_BIT_DEFINITIONS -e -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 # # --misrac=5-9,11-12,14,16-17,19-21,24-26,29-32, # # 34-35,38-39,42-43,46,50,52-54,56-59,61-62, # # 64-65,68-80,83-84,87-91,94-95,98-100,103-110, # # 112-126 # # Enabled MISRA C rules = 5-9,11-12,14,16-17,19-21,24-26,29-32,34-35, # # 38-39,42-43,46,50,52-54,56-59,61-62,64-65, # # 68-80,83-84,87-91,94-95,98-100,103-110,112-126 # # Checked = 5,7-9,11-12,14,17,19-21,24,29-32,34-35,38-39, # # 42,46,50,52-54,56-59,61-62,64,68-69,71-80, # # 83-84,87-89,91,94-95,98,100,104-105,108-109, # # 112-115,118-126 # # Not checked = 6,16,25-26,43,65,70,90,99,103,106-107,110, # # 116-117 # # List file = C:\home\kevin\pub\src\bc100\IAR\Release\List\NI # # MHcharge.lst # # Object file = C:\home\kevin\pub\src\bc100\IAR\Release\Obj\NIM # # Hcharge.r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100\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 { 66 unsigned char NextState; 67 68 switch (CurrentState) { \ 00000000 9100.... LDS R16, CurrentState \ 00000004 510E SUBI R16, 30 \ 00000006 F049 BREQ ??Charge_0 \ 00000008 5104 SUBI R16, 20 \ 0000000A F149 BREQ ??Charge_1 \ 0000000C 500A SUBI R16, 10 \ 0000000E F409 BRNE $+2+2 \ 00000010 C04A RJMP ??Charge_2 \ 00000012 500A SUBI R16, 10 \ 00000014 F409 BRNE $+2+2 \ 00000016 C05E RJMP ??Charge_3 \ 00000018 C077 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: \ 0000001A .... LDI R30, LOW(BattData) \ 0000001C .... LDI R31, (BattData) >> 8 \ 0000001E 8104 LDD R16, Z+4 \ 00000020 8115 LDD R17, Z+5 \ 00000022 E04A LDI R20, 10 \ 00000024 E050 LDI R21, 0 \ 00000026 .... RCALL ?US_DIVMOD_L02 \ 00000028 .... LDI R30, LOW(ChargeParameters) \ 0000002A .... LDI R31, (ChargeParameters) >> 8 \ 0000002C 8302 STD Z+2, R16 \ 0000002E 8313 STD Z+3, R17 77 ChargeParameters.NextState = ST_FASTCHARGE; \ 00000030 E302 LDI R16, 50 \ 00000032 8304 STD Z+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); \ 00000034 .... LDI R30, LOW(HaltParameters) \ 00000036 .... LDI R31, (HaltParameters) >> 8 \ 00000038 8300 ST Z, R16 83 84 // Set up voltage limit and temperature limits. 85 HaltParameters.VoltageMax = BAT_VOLTAGE_PREQUAL; \ 0000003A EB08 LDI R16, 184 \ 0000003C E01B LDI R17, 11 \ 0000003E 8303 STD Z+3, R16 \ 00000040 8314 STD Z+4, R17 86 HaltParameters.TemperatureMin = BAT_TEMPERATURE_MIN; \ 00000042 E005 LDI R16, 5 \ 00000044 E010 LDI R17, 0 \ 00000046 8701 STD Z+9, R16 \ 00000048 8712 STD Z+10, R17 87 HaltParameters.TemperatureMax = 35; \ 0000004A E203 LDI R16, 35 \ 0000004C 8307 STD Z+7, R16 \ 0000004E 8710 STD Z+8, R17 88 89 // Reset temperature measurement for HaltNow(). 90 HaltParameters.LastNTC = 0; \ 00000050 8717 STD Z+15, R17 \ 00000052 8B10 STD Z+16, R17 91 92 // Start PWM and charge timer before calling the charge function. 93 PWM_Start(); \ 00000054 .... RCALL PWM_Start 94 Time_Set(TIMER_CHG, BAT_TIME_PREQUAL, 0, 0); \ 00000056 E040 LDI R20, 0 \ 00000058 E010 LDI R17, 0 \ 0000005A E022 LDI R18, 2 \ 0000005C C037 RJMP ??Charge_5 95 96 // Call charge function, get next state. 97 NextState = ConstantCurrent(); 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: \ 0000005E .... LDI R18, LOW(BattData) \ 00000060 .... LDI R19, (BattData) >> 8 \ 00000062 01F9 MOVW R31:R30, R19:R18 \ 00000064 8104 LDD R16, Z+4 \ 00000066 8115 LDD R17, Z+5 \ 00000068 .... LDI R30, LOW(ChargeParameters) \ 0000006A .... LDI R31, (ChargeParameters) >> 8 \ 0000006C 8302 STD Z+2, R16 \ 0000006E 8313 STD Z+3, R17 109 ChargeParameters.NextState = ST_LOWRATECHARGE; \ 00000070 E30C LDI R16, 60 \ 00000072 8304 STD Z+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); \ 00000074 .... LDI R30, LOW(HaltParameters) \ 00000076 .... LDI R31, (HaltParameters) >> 8 \ 00000078 E10B LDI R16, 27 \ 0000007A 8300 ST Z, 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; \ 0000007C EC00 LDI R16, 192 \ 0000007E E112 LDI R17, 18 \ 00000080 8303 STD Z+3, R16 \ 00000082 8314 STD Z+4, R17 119 HaltParameters.VoltageDrop = BAT_VOLTAGE_DROP; \ 00000084 E20D LDI R16, 45 \ 00000086 E010 LDI R17, 0 \ 00000088 8301 STD Z+1, R16 \ 0000008A 8312 STD Z+2, R17 120 HaltParameters.TemperatureMax = BAT_TEMPERATURE_MAX; \ 0000008C E302 LDI R16, 50 \ 0000008E 8307 STD Z+7, R16 \ 00000090 8710 STD Z+8, R17 121 HaltParameters.TemperatureRise = 1; \ 00000092 E001 LDI R16, 1 \ 00000094 8703 STD Z+11, R16 \ 00000096 8714 STD Z+12, R17 122 123 // Reset maximum voltage measurement for HaltNow(). 124 HaltParameters.VBATMax = 0; \ 00000098 8715 STD Z+13, R17 \ 0000009A 8716 STD Z+14, R17 125 126 // Start timer, PWM should still be running. 127 Time_Set(TIMER_CHG, BattData.MaxTime, 0, 0); \ 0000009C E040 LDI R20, 0 \ 0000009E 01F9 MOVW R31:R30, R19:R18 \ 000000A0 8520 LDD R18, Z+8 \ 000000A2 8531 LDD R19, Z+9 \ 000000A4 C015 RJMP ??Charge_6 128 129 // Call charge function, get next state. 130 NextState = ConstantCurrent(); 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: \ 000000A6 .... LDI R30, LOW(BattData) \ 000000A8 .... LDI R31, (BattData) >> 8 \ 000000AA 8104 LDD R16, Z+4 \ 000000AC 8115 LDD R17, Z+5 \ 000000AE E04A LDI R20, 10 \ 000000B0 E050 LDI R21, 0 \ 000000B2 .... RCALL ?US_DIVMOD_L02 \ 000000B4 .... LDI R30, LOW(ChargeParameters) \ 000000B6 .... LDI R31, (ChargeParameters) >> 8 \ 000000B8 8302 STD Z+2, R16 \ 000000BA 8313 STD Z+3, R17 140 ChargeParameters.NextState = ST_ENDCHARGE; \ 000000BC E406 LDI R16, 70 \ 000000BE 8304 STD Z+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); \ 000000C0 E10A LDI R16, 26 \ 000000C2 9300.... STS HaltParameters, R16 146 147 // Start timer, 30 minutes. 148 Time_Set(TIMER_CHG, 30, 0, 0); \ 000000C6 E040 LDI R20, 0 \ 000000C8 E010 LDI R17, 0 \ 000000CA E12E LDI R18, 30 \ ??Charge_5: \ 000000CC E030 LDI R19, 0 \ 000000CE E001 LDI R16, 1 \ ??Charge_6: \ 000000D0 .... RCALL Time_Set 149 150 // Call charge function, get next state. 151 NextState = ConstantCurrent(); \ 000000D2 .... RJMP ConstantCurrent 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: \ 000000D4 .... RCALL PWM_Stop 160 BattData.Charged = TRUE; \ 000000D6 .... LDI R30, LOW(BattData) \ 000000D8 .... LDI R31, (BattData) >> 8 \ 000000DA 8100 LD R16, Z \ 000000DC 6002 ORI R16, 0x02 \ 000000DE 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) { \ 000000E0 9100.... LDS R16, BattActive \ 000000E4 E010 LDI R17, 0 \ 000000E6 5F0F SUBI R16, 255 \ 000000E8 4F1F SBCI R17, 255 \ 000000EA E042 LDI R20, 2 \ 000000EC E050 LDI R21, 0 \ 000000EE .... RCALL ?SS_DIVMOD_L02 \ 000000F0 .... LDI R18, LOW(BattControl) \ 000000F2 .... LDI R19, (BattControl) >> 8 \ 000000F4 0F24 ADD R18, R20 \ 000000F6 1F35 ADC R19, R21 \ 000000F8 01A9 MOVW R21:R20, R19:R18 \ 000000FA .... RCALL __eeget8_16 \ 000000FC 7001 ANDI R16, 0x01 \ 000000FE F011 BREQ ??Charge_7 165 NextState = ST_BATCON; \ 00000100 E104 LDI R16, 20 \ 00000102 9508 RET 166 } else { 167 NextState = ST_SLEEP; \ ??Charge_7: \ 00000104 E208 LDI R16, 40 \ 00000106 9508 RET 168 } 169 break; 170 171 172 default: // Shouldn't end up here. Reinitialize for safety. 173 NextState = ST_INIT; \ ??Charge_4: \ 00000108 E00A LDI R16, 10 174 break; 175 } 176 177 // Return the next state to main(). 178 return(NextState); \ 0000010A 9508 RET 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 268 268 bytes in segment CODE 268 bytes of CODE memory Errors: none Warnings: none