BC.c Don Carveth July 2002 Multi chemistry, multi cell battery charger based on Atmels app note AVR450. Added a Smart Battery interface and made numerous modifications to the Atmel program. The program was originally written for an AT90S4433. After adding the Smart Battery routines I switched to an ATMEGA8 (same pin-out but 8K memory instead of 4K) as I was well beyond 4K flash usage. You need to use the new GCC 3.2 compiler to be able to use the direct I/O assigments and for the ATMEGA8. Note that the overall program is made up of code, and styles, from three separate sources: Atmels code, the smart battery code (modified by me from a generic I2C interface for the 68HC11/Imagecraft C) and my own code. The resulting program is a littel disjointed. Main() is located in BC.c. User configuration is primarily in LiIon.h. Most of the action takes place in LiIon.c. SBComm.c contains the Smart Battery routines. *********** REVISION HISTORY ************************** Rev 1 General fixups 7/24/02 bc.h: Moved VBat2 to PC1 - on ATMEGA8 PC5 is only 8 bit. Not good enough for voltage reading. Changed to: #define VBAT2 1 and rewired accordingly. Printout was too fast in CONST_V mode. Moved printout routines to inside each of the CONST_C and CONST_V sections a modified the printout periods for each. ISET in Custom mode fixed. Added more preset battery configurations. Fixed hang-up in Smart Battery mode. Smart Battery printout was not updating -fixed. Changed MIN_I_FAST calculation - was 50 mA min, now 80 mA per 1600 mAH of capacity. Tuned up LED flash rates. Fixed Error LED Changed CURRENT_STEP to 226. My ammeter was was reading in error. Measured voltage across .05 ohm resistor, this also agreed with smart battery reading. Timeout timer not working - moved to TCNT0. Works. Reformatted printout, added time in h:m:s format Changed MAX_TIME_FAST to 180 minutes from 90 Rev 0 Creation 6/22/02 Converted from IAR to GCC Fully operational. Not all error modes tested. As published with article on AVRFreaks *********** Steps to convert from IAR to GCC ********** 1. All header files: Replace #include library file references - Done 2. I use the modified header files allowing direct I/O register access so that PORTA = 0xFF references work, therefore the I/O access modification is not required. 3. BC.c: Removed C_task type declaration in main() statement- done 4. BC.c: changed interrupt routine definition to SIGNAL(SIG_OVERFLOW1) -done. 5. BC.c: Removed unused commented out interrupt references 6. BC.c: Changed global interrupt enable (in Setup) from _SEI() to sei() - done. 7. BC_def.h: Removed "flash" reference in ntc_c lookup table. This means the table will be stored in RAM. OK if there's room (there is). -done. 8. Added makefile with proper file references to project. -done. 9. Changed array indes types to "unsigned char" from "char" - done 10. Change return type of main to int. - done 11. All: Changed Device: to AT90S4433 from AT90S2333 in comments - done 12. bc.h: global variables were stored in unused registers. Changed to store in RAM; 13. bc.h: Removed interrupt function prototype - done 14. Added #define DEBUG to BC_debug.c file 15. BC_debug.c: Changed UCR to UCSRB and USR to UCSRA Total conversion time about 90 minutes. Program compiled and executed at this point. ********* Changes made to program after conversion: ************* 1. Commented out trickle charge algorithm - don't see a need but the code is there if you wish to revive it. 2. Removed debug routines - added my own 3. Changed MIN_I_FAST calc - removed CELLS from equation - I don't see how the number of series cells would affect the minimum current cut-off. 4. Changed LED operation - slow flash on current control, fast flash on voltage control, steady on when done. 5. Added printout routine showing current, voltage and temperature readings. Added I, V, v(voltage with PWM off) and T as variables for this. 6. Modified program such that battery parameters could be set by hardware. Use 8 preconfigured battery configurations or custom set. Had to change macros to variables. Added GetBattery function in LiIon.c to define. 7. The VOLTAGE comparisons in the Fast Charge routine were incorrect. They were comparing raw ADC inputs to voltages, not voltages converted to 0 -1024 range. 8. Added my own StdDefs.c and StdDefs.h files and used UART setup and run_led routines from there. 7. Added Smart Battery routines including test for SB, fetching charge parameters and displaying parameters. 8. Removed most references to alternate battery types. The Atmel code includes routines for NiCad, NiHa and SLA batteries as well that I have nor used. 9. Deleted the BC_def.h file and moved the few remaining definitions to the LiIon.h file. Notes re new GCC Version(3.2): 1. Recommend changing ADCW back to ADC (io4433.h, others?) for compatibility. 2. outb command seems to be interpreted as an in command. Compiles but does not work. Changing to direct assignment - works. 3. Compiler sometimes reports a warning "No new line at end of file" even though it clearly exists. Does not report as a problem in earlier versions. 4. In compiling this code: suart_putchar: sbi DDRB,TxD Reports: Error. Number must be less than 32. All references to PORTB, PINB, DDRB reported the same error. Notes re Smart Battery Interface 1. Software was modified from 68HC11 Imagecraft code to ATMEGA8. 2. I had to add extra delay statements in I2CInit to make it work. Never did figure out why. Could not just add delay time to the delay statement. 3. During one troubleshooting frenzy I changed all the port bit twiddling routines to AVR GCC type "sbi", "cbi", "bit_is_set", etc. I left the previous versions intact but commented out. *********** OPERATION ********************************* Set up parameters specific to you charger in LiIon.h. Set up parameters specific to your battery in GetBattery function in LiIon.c. 1. Plug in battery to charger. If smart battery connect smart interface. 2. Plug in power supply to charger. Ensure Power supply is capable of current that battery can take and charger can handle. Check CHARGER_MAX_CURRENT setting in LiIon.h. 3. If battery is depleted charging will start in constant current mode. LED0 will flash quickly. 4. Once battery has reached max charge voltage operation switches to constant voltage. LED flashed more slowly. 5. Once charge current in constant voltage mode reaches MIN_I_FAST a 30 minute delay is started. 6. At the end of 30 minutes the charger shuts down. LED0 is now on steady. Setting Battery Charging Parameters CAUTION!!! Be very careful not to set the charger to voltages or currents higher than the battery is designed for. The battery could be damaged or even explode. Smart Battery - if a smart battery is connected and detected all charging parameters come from the battery. Preset configurations - three dip switches allow the user to select preset parameters for up to eight different batteries. Custom setting - use the on-board pot and dip switches to set up specific parameters. Note that there can be a significant drop between the charger and the battery at high current rates. The charger could therefore read 12.6 and switch to constant voltage mode when the battery is only at 12.35 volts. This is OK. As the current declines the two voltages approach each other and the final charge voltage will not exceed the max voltage setting. The only downside is that charging is slowed down a little. *********** RESOURCES ********************************* Processor: ATMEGA8 Crystal: 7.3 MHz Flash size: As converted: 0xdfa or 3578 Final: 0x1532 or 5426 RAM Used: As converted: 0x27 or 39 Final: 0xC0 or 192 EEPROM Used: 0 Pins used: PB0 LED0 Fast Charge - Green PB1 PWM 2 PB2 PB3 LED 2 Error - yellow PB4 Num Cells SW 0 PB5 Num Cells SW 1 PC0 Cell Volts SW PC1 PC2 ISet PC3 TBat2 PC4 IBat2 PC5 VBat2 PD0 PD1 UART Txd PD2 SDA - Smart Battery PD3 SCL - Smart Battery PD4 Switch 0 Custom Battery Settings PD5 Switch 1 Predefined Battery Parameters SW 0 PD6 Switch 2 Predefined Battery Parameters SW 1 PD7 Switch 3 Predefined Battery Parameters SW 2 Interrupts: Timer 1 Overflow - Delay, charge timeout timer Timers: TCNT1 Used for PWM output to MOSFET to control charge rate. OCR1 = 0x00 : used to set PWM duration by incrementing TCCR1B = 0x01; //counter1 clock prescale = 1 Also used as timer for delay/timeout times TCNT0 Used for time out timer. TCCR0 = 0x05; // Timer0 enabled, divide by 1024 sbi(TIMSK, 0); // Enable TCNT0 TOF interrupt ISR every 28 ms. approx