The Software
You will require the latest (as of July, 2002) version of GCC, version 3.2 as provided on the AVRFreaks GCC web page, to be able to program the ATMEGA8 and take advantage of direct I/O register assignment mode which is new in this release.
Here is the set of c code files. Take a look at the notes.txt file. It describes the IAR to GCC conversion, the mods made to Atmels software, uC resources used, pin assignments and general notes about the software.
The main file is BC.c. Program flow starts with setup then moves directly into the LiIon fast charge algorithm in LiIon.c. It is here that the program checks for the existence of a Smart Battery. If detected charger settings are based on the information received from the battery, if not, settings are based on the on-board dip switch settings.
The charger then checks for over/under battery temperature and over voltage and flags an error if any of these are detected, sending a short error message to the PC. If OK control proceeds to the Constant Current loop where the PWM signal on-time is adjusted up or down until the measured current matches the specified fast charge current. The charge LED flashes quickly during this mode. When the Maximum Charge Voltage setting is reached then the mode switches to Constant Voltage and a new loop is entered that uses the same method as above to control voltage at the Maximum Charge Voltage point. The LED now flashes more slowly. This continues until 30 minutes after the charge current, which is decreasing with time in constant voltage mode, reaches the minimum (set at 50 mA per 1600 mAH of capacity). The charger then shuts off and the LED goes on steady.
The Atmel software included a trickle charging algorithm that I left intact but commented out. I don't see myself using it. I also removed most references to alternate battery chemistries. The program was designed to have the charge settings, specified in the BC_defs.h file, defined at compile time. I converted all of these settings to variables which are defined in various ways as described above. I deleted the BC_defs.h file and consolidated the user setup area in LiIon.h. Be sure to review this file and update important parameters such as Maximum Charger Current before firing things up. The preset settings (pick up to 8 different batteries) are set near the end of the LiIon.c file.
The voltage, current and temperature analogs must be calibrated. I used my calculation sheet to determine nominal resistor values, as described in the App Note, then fine tuned them by setting the VOLTAGE_STEP and CURRENT_STEP. This gives the number of mV or mA per each of the 1024 steps of the 10 bit A/D input. The thermistor values never leave the raw state though I see an NTC look-up table which was never implemented by Atmel.
The Smart Battery routines, located in sbcomm.c, are based on bit-banged I2C 68HC11/Imagecraft software. I converted them to AVR/GCC and added information and functions specific to the Smart Battery spec. Take a look at SBComm.h for the available SB commands. The ATMEGA8 has a built in I2C port but I did not use it. These routines could be extracted and used separately from the charger if desired, say, to monitor battery status of your robot during use. It provides some useful information such as voltage, amps, time remaining until recharge required (based on current usage rate), percent capacity, temperature, status flags, etc.
Also worth discussing are my StdDefs files. I have included in StdDefs.c routines that I seem to use in almost all programs such as putchar, putBCD, putstr, run_led, msleep, etc. StdDefs.h includes defines that simplifies changing uC models and crystal frequencies, primarily with respect to the UART, and has some other standard macros that I frequently use.
I removed the Atmel debug statements and used my own putchar / putstr / putBCD routines instead. All errors will report a string back to the PC. The error handling system has not been well tested - To date everything has worked and I haven't needed it.
Start-up
Once wired up and with the software installed you should be ready to go. I like to have my scope on during this phase to watch the PWM signal and check for data on the SMBus. The PC was connected to the UART and running HyperTerminal. I started off using load resistors instead of the battery just in case. I found a couple 7.5 ohm 25 watt resistors that were ideal. I then calibrated my voltage and current measurement by adjusting VOLTAGE_STEP and CURRENT_STEP until the readings reported on the PC agreed with my voltmeter measurements. You need to be sure your meter is pretty accurate as the maximum charge voltage needs to be accurately maintained to ensure the battery takes its full charge.
By changing LiIon_CELL_VOLTAGE and CAPACITY I was able to force the charger into both operating modes. The PWM circuit worked right from the start which was a relief after the struggles I had had with the MAX745 circuit. Once I was confident that the PWM worked and the charging routines were working I connected the battery power. The PC feedback looked good and the voltage was slowly rising in Constant Current mode. I then connected the Thermistor / Smart battery connector and troubleshot those two functions.
Operation
Note that the software is set up as a single pass. The uC must be reset to restart the sequence or to accept new charge settings from either the Smart Battery or the dip switches.
If a Smart Battery is connected then there is nothing to do but plug in the battery, then plug in the power and let it charge. If not you need to select the correct charge settings for your particular battery. In custom mode you use on board dip switches and the variable resistor to set CELLS, LiIon_CELL_VOLTAGE and CAPACITY (same as max charge current). If the "Custom" dip switch is not selected then the software goes to the GetBatteryData() function where it selects a predefined set of parameters based on the PreDef0, 1 and 2 switch settings. You can define up to 8 different batteries in the GetBatteryData() routine.
NB!!!! You must be very careful at this point not to select a battery with higher current or voltage settings than the battery you have connected. I would recommend monitoring voltage and current via the PC or with a volt-ammeter to be sure. My Smart Battery reports back a Max Charge Current of 0 if the voltage is above the max charge voltage.
Conclusion
The article assumes you are familiar with basic operation and programming of an AVR microcontroller. If not, a visit to AVRFreaks.com is in order. The AVR is a very straightforward uC to learn. If you use the c language then you will enjoy using GCC which is powerful, easy to set up and free. You can have a complete development environment set up for the cost of a micro and a few support parts and an AVR-ISP programmer which is about $35.
You can see there are some risks associated with charging LiIon batteries. I would not attempt to construct this charger if you do not have the skills necessary to safely build, program and test it. Even then care is required when switching between batteries. Using the charger for a specific battery only is the safest method.
Good luck with your project and contact Don Carveth, don@botgoodies.com if you have any questions or comments.