LTC6803-2 and -4 - Multicell Battery Stack Monitor

Features

  • Measures Up to 12 Battery Cells in Series
  • Stackable Architecture
  • Supports Multiple Battery Chemistries and Supercapacitors
  • Individually Addressable Serial Interface
  • 0.25% Maximum Total Measurement Error
  • Engineered for ISO26262 Compliant Systems
  • 13ms to Measure All Cells in a System
  • Passive Cell Balancing:
    – Integrated Cell Balancing MOSFETs
    – Ability to Drive External Balancing MOSFETs
  • Onboard Temperature Sensor and Thermistor Inputs
  • 1MHz Serial Interface with Packet Error Checking
  • Safe with Random Connection of Cells
  • Built-In Self Tests
  • Delta-Sigma Converter With Built-In Noise Filter
  • Open-Wire Connection Fault Detection
  • 12μA Standby Mode Supply Current
  • High EMI Immunity
  • 44-Lead SSOP Package
Designed for Automotive and Transportation Applications
AEC-Q100 generic family data available for specific packages


Typical Application

LTC6803-2 Typical Application
LTC6803-2 Typical Application

Description

The LTC6803 is a 2nd generation, complete battery monitoring IC that includes a 12-bit ADC, a precision voltage reference, a high voltage input multiplexer and a serial interface. Each LTC6803 can measure up to 12 series connected battery cells or supercapacitors. Many LTC6803 devices can be stacked to measure the voltage of each cell in a long battery string. Each LTC6803-2/LTC6803-4 has an individually addressable serial interface, allowing up to 16 LTC6803-2/LTC6803-4 devices to interface to one control processor and operate simultaneously. Each cell input has an associated MOSFET switch for discharging overcharged cells. The LTC6803-2 connects the bottom of the stack to V internally. It is pin compatible with the LTC6802-2, providing a drop-in upgrade. The LTC6803-4 separates the bottom of the stack from V, improving cell 1 measurement accuracy.

The LTC6803 provides a standby mode to reduce supply current to 12μA. Furthermore, the LTC6803 can be powered from an isolated supply, providing a technique to reduce battery stack current draw to zero.

The related LTC6803-1 and LTC6803-3 offer a serial interface that allows the serial ports of multiple LTC6803-1 or LTC6803-3 devices to be daisy chained without optocouplers or isolators.

  SPI Interface Isolated V- LTC6802 Pin Compatible
LTC6803-1 Daisy Chain No Yes
LTC6803-2 Addressable No Yes
LTC6803-3 Daisy Chain Yes No
LTC6803-4 Addressable Yes No

Packaging

CAD Symbols and Footprints: The downloadable Zip file below contains the schematic symbol and PCB footprints.

For complete and up to date package information and drawings, please refer to our packaging page

Part Number Package Code Temp Package
Drawing
RoHS
LTC6803HG-2#PBF SSOP-44 G H 05-08-1754 Yes
LTC6803HG-2#TRPBF SSOP-44 G H 05-08-1754 Yes
LTC6803HG-4#PBF SSOP-44 G H 05-08-1754 Yes
LTC6803HG-4#TRPBF SSOP-44 G H 05-08-1754 Yes
LTC6803IG-2#PBF SSOP-44 G I 05-08-1754 Yes
LTC6803IG-2#TRPBF SSOP-44 G I 05-08-1754 Yes
LTC6803IG-4#PBF SSOP-44 G I 05-08-1754 Yes
LTC6803IG-4#TRPBF SSOP-44 G I 05-08-1754 Yes


LTC6803-2 Package Drawing
LTC6803-2 Package Drawing

Order Info

  • Part numbers ending in PBF are lead free. Solder plated terminal finish (SnPb) versions are non-standard and special terms and conditions and pricing applies if available. Please contact LTC marketing for information.
  • Part numbers containing TR or TRM are shipped in tape and reel or 500 unit mini tape and reel, respectively
  • Please refer to our general ordering information or the product datasheet for more details

Package Variations and Pricing

Part Number Package Temp Price
(1-99)
Price
(1k)*
RoHS
LTC6803HG-2#PBF SSOP-44 H $15.53 $11.14 Yes
LTC6803HG-2#TRPBF SSOP-44 H $15.59 $11.20 Yes
LTC6803HG-4#PBF SSOP-44 H $15.53 $11.14 Yes
LTC6803HG-4#TRPBF SSOP-44 H $11.20 Yes
LTC6803IG-2#PBF SSOP-44 I $13.86 $9.95 Yes
LTC6803IG-2#TRPBF SSOP-44 I $10.01 Yes
LTC6803IG-4#PBF SSOP-44 I $13.86 $9.95 Yes
LTC6803IG-4#TRPBF SSOP-44 I $10.01 Yes
Buy NowRequest Samples
* The USA list pricing shown is for BUDGETARY USE ONLY, shown in United States dollars (FOB USA per unit for the stated volume), and is subject to change. International prices may differ due to local duties, taxes, fees and exchange rates. For volume-specific price or delivery quotes, please contact your local Linear Technology sales office or authorized distributor.

Demo Boards

Linear Technology offers many demo boards free of charge to qualified customers. Contact your local sales office or distributor to inquire about a demo board. Certain demo boards are also available for sale via credit card on this website. Demo boards are for evaluation purposes only. It remains the customer’s responsibility to verify proper and reliable operation in the actual end application.

Part Number Description Price Documentation
DC1652A LTC6803-2 (Requires DC590B) | Demo Board $150.00
DC1835A LTC6803-4 (Requires DC590B) | Demo Board $150.00
DC2064A LTC3300ILXE-1 | LTC6803IG-2 High Frequency Bidirectional Multicell Battery Balancer- Companion Board DC590B $475.00
Buy Now

Companion Boards

Part Number Description Price Documentation
DC2026C Linduino One Isolated USB Demo Board: An Arduino- and QuikEval-Compatible Code Development Platform $75.00
DC590B Isolated USB Serial Controller for Linear Technology QuikEval-Compatible Demo Boards $50.00
Buy Now
Click here to view our complete list of demo boards

Designed for Automotive and Transportation Applications

Please contact your local sales representative for more information regarding reliability reports and AEC-Q100 data or to inquire about parts that are not included. For more information, view our Automotive and Transportation page

Part Number Package Temp Price
(1-99)
Price
(1k)*
RoHS
LTC6803HG-2#PBF SSOP-44 H $15.53 $11.14 Yes
LTC6803HG-2#TRPBF SSOP-44 H $15.59 $11.20 Yes
LTC6803HG-4#PBF SSOP-44 H $15.53 $11.14 Yes
LTC6803HG-4#TRPBF SSOP-44 H $11.20 Yes
LTC6803IG-2#PBF SSOP-44 I $13.86 $9.95 Yes
LTC6803IG-2#TRPBF SSOP-44 I $10.01 Yes
LTC6803IG-4#PBF SSOP-44 I $13.86 $9.95 Yes
LTC6803IG-4#TRPBF SSOP-44 I $10.01 Yes
Buy NowRequest Samples
* The USA list pricing shown is for BUDGETARY USE ONLY, shown in United States dollars (FOB USA per unit for the stated volume), and is subject to change. International prices may differ due to local duties, taxes, fees and exchange rates. For volume-specific price or delivery quotes, please contact your local Linear Technology sales office or authorized distributor.

Applications

  • Electric and Hybrid Electric Vehicles
  • High Power Portable Equipment
  • Backup Battery Systems
  • Electric Bicycles, Motorcycles, Scooters

Product Notifications

Please login to your MyLinear account for notifications of datasheet updates, new document releases and LTspice model announcements for your favorite products. If you do not have a MyLinear account you may Sign Up Now.

Forgot your password? Click here.
Need help? Email mylinear@linear.com with questions and comments.

Design Tools

Linduino

Linduino is an Arduino compatible platform for developing and distributing firmware libraries and code for SPI and I²C-compatible integrated circuits. The Linduino One board interfaces to more than 300 QuikEval demonstration cards, supporting a variety of product types including analog-to-digital converters (ADCs)digital-to-analog converters (DACs)power monitors, and more. Firmware libraries for individual devices are written in C and designed to be portable to a wide variety of processors and microcontrollers. Each library has a demonstration program that can be uploaded to the Linduino One platform to allow the circuit and software to be quickly and easily verified.

Click here for more information on Linduino

Code

Linduino is Linear Technology's Arduino compatible system for developing and distributing firmware libraries and example code for Linear Technology’s integrated circuits. The code below can be downloaded or copied and pasted into your project. Please visit the Linduino Home Page for demo board, manual and setup information.

This part is Code Supported: There is example code available for this part. The code below may rely on other drivers available in the full library.

Download LTC6803-2 - DC1652A.ino

/*!
Linear Technology DC1652A Demonstration Board.
LTC6803-2: Battery stack monitor

@verbatim

NOTES
 Setup:
   Set the terminal baud rate to 115200 and select the newline terminator.
   Ensure all jumpers on the demo board are installed in their default positions from the factory.
   Refer to Demo Manual DC1652.
 

 Menu Entry 1: Write Configuration
   Writes the configuration register of the LTC6803s on the stack. This command can be used to turn on
   the reference and shorten ADC conversion Times. 
   
 Menu Entry 2: Read Configuration
   Reads the configuration register of the LTC6803, the read configuration can differ from the written configuration.
   The GPIO pins will reflect the state of the pin

 Menu Entry 3: Start Cell voltage conversion
    Starts a LTC6803 cell channel adc conversion.

 Menu Entry 4: Read cell voltages
    Reads the LTC6803 cell voltage registers and prints the results to the serial port.
 
 Menu Entry 5: Start Auxiliary voltage conversion
    Starts a LTC6803 Temp channel adc conversion.

 Menu Entry 6: Read Auxiliary voltages
    Reads the LTC6803 Temp registers and prints the Temp voltages to the serial port.
 
 Menu Entry 7: Start cell voltage measurement loop
    The command will continuously measure the LTC6803 cell voltages and print the results to the serial port.
    The loop can be exited by sending the MCU a 'm' character over the serial link.
 
USER INPUT DATA FORMAT:
 decimal : 1024
 hex     : 0x400
 octal   : 02000  (leading 0)
 binary  : B10000000000
 float   : 1024.0
@endverbatim

REVISION HISTORY
$Revision: 3538 $
$Date: 2015-1-8 

Copyright (c) 2015, Linear Technology Corp.(LTC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.

Copyright 2015 Linear Technology Corp. (LTC)
 */


/*! @file 
    @ingroup LTC68032 
*/ 

#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include "UserInterface.h"
#include "LTC68032.h"
#include <SPI.h>

const uint8_t TOTAL_IC = 1;//!<number of ICs in the daisy chain

/******************************************************
 *** Global Battery Variables received from 6803 commands
 These variables store the results from the LTC6803
 register reads and the array lengths must be based 
 on the number of ICs on the stack
 ******************************************************/
uint16_t cell_codes[TOTAL_IC][12]; 
/*!< 
  The cell codes will be stored in the cell_codes[][12] array in the following format:
  
  |  cell_codes[0][0]| cell_codes[0][1] |  cell_codes[0][2]|    .....     |  cell_codes[0][11]|  cell_codes[1][0] | cell_codes[1][1]|  .....   |
  |------------------|------------------|------------------|--------------|-------------------|-------------------|-----------------|----------|
  |IC1 Cell 1        |IC1 Cell 2        |IC1 Cell 3        |    .....     |  IC1 Cell 12      |IC2 Cell 1         |IC2 Cell 2       | .....    |
****/

uint16_t temp_codes[TOTAL_IC][3];
/*!<
 The Temp codes will be stored in the temp_codes[][3] array in the following format:
 
 |  temp_codes[0][0]| temp_codes[0][1]|temp_codes[0][2] | temp_codes[1][0]| temp_codes[1][1]|   .....   |
 |------------------|-----------------|-----------------|-----------------|-----------------|-----------|
 |IC1 Temp1         |IC1 Temp2        |IC1 ITemp        |IC2 Temp1        |IC2 Temp2        |  .....    |
*/

uint8_t tx_cfg[TOTAL_IC][6];
/*!<
  The tx_cfg[][6] stores the LTC6803 configuration data that is going to be written 
  to the LTC6803 ICs on the daisy chain. The LTC6803 configuration data that will be
  written should be stored in blocks of 6 bytes. The array should have the following format:
  
 |  tx_cfg[0][0]| tx_cfg[0][1] |  tx_cfg[0][2]|  tx_cfg[0][3]|  tx_cfg[0][4]|  tx_cfg[0][5]| tx_cfg[1][0] |  tx_cfg[1][1]|  tx_cfg[1][2]|  .....    |
 |--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|--------------|-----------|
 |IC1 CFGR0     |IC1 CFGR1     |IC1 CFGR2     |IC1 CFGR3     |IC1 CFGR4     |IC1 CFGR5     |IC2 CFGR0     |IC2 CFGR1     | IC2 CFGR2    |  .....    |
 
*/

uint8_t rx_cfg[TOTAL_IC][7];
/*!<
  the rx_cfg[][8] array stores the data that is read back from a LTC6803-2 daisy chain. 
  The configuration data for each IC  is stored in blocks of 7 bytes. Below is an table illustrating the array organization:

|rx_config[0][0]|rx_config[0][1]|rx_config[0][2]|rx_config[0][3]|rx_config[0][4]|rx_config[0][5]|rx_config[0][6]  |rx_config[1][0]|rx_config[1][1]|  .....    |
|---------------|---------------|---------------|---------------|---------------|---------------|-----------------|---------------|---------------|----------|
|IC1 CFGR0      |IC1 CFGR1      |IC1 CFGR2      |IC1 CFGR3      |IC1 CFGR4      |IC1 CFGR5      |IC1 PEC          |IC2 CFGR0      |IC2 CFGR1      |  .....    |
*/


//! Inititializes hardware and variables
void setup()                  
{
  Serial.begin(115200);
  LTC6803_initialize();  //Initialize LTC6803 hardware
  init_cfg();        //initialize the 6803 configuration array to be written
  print_menu();              
}


//! main loop
void loop()                     
{
  
  if (Serial.available())           // Check for user input
    {
      uint32_t user_command;
      user_command = read_int();      // Read the user command
      Serial.println(user_command);
      run_command(user_command);
    }
}


/*!*****************************************
  \brief executes the user inputted command
  
  Menu Entry 1: Write Configuration \n
   Writes the configuration register of the LTC6803. This command can be used to turn on the reference 
   and increase the speed of the ADC conversions. 
   
 Menu Entry 2: Read Configuration \n
   Reads the configuration register of the LTC6803, the read configuration can differ from the written configuration.
   The GPIO pins will reflect the state of the pin

 Menu Entry 3: Start Cell voltage conversion \n
   Starts a LTC6803 cell channel adc conversion.

 Menu Entry 4: Read cell voltages \n
    Reads the LTC6803 cell voltage registers and prints the results to the serial port.
 
 Menu Entry 5: Start Temp voltage conversion \n
    Starts a LTC6803 Temp channel adc conversion.

 Menu Entry 6: Read Temp voltages \n
    Reads the LTC6803 axiliary registers and prints the GPIO voltages to the serial port.
 
 Menu Entry 7: Start cell voltage measurement loop \n
    The command will continuously measure the LTC6803 cell voltages and print the results to the serial port.
    The loop can be exited by sending the MCU a 'm' character over the serial link.
 
*******************************************/
void run_command(uint32_t cmd)
{
  int8_t error = 0;
  
  char input = 0;
  switch(cmd)
  {
   
  case 1:
    
    LTC6803_wrcfg(TOTAL_IC,tx_cfg);
    print_config();
    break;
    
  case 2:
    
    error = LTC6803_rdcfg(TOTAL_IC,rx_cfg);
    if (error == -1)
    {
     Serial.println(F("A PEC error was detected in the received data"));
    }
    print_rxconfig();
    break;

  case 3:
    
    LTC6803_stcvad();
    delay(3);
    Serial.println(F("cell conversion completed"));
    Serial.println();
    break;
    
  case 4:
   
    error = LTC6803_rdcv(TOTAL_IC,cell_codes); // Set to read back all cell voltage registers
    if (error == -1)
    {
       Serial.println(F("A PEC error was detected in the received data"));
    }
    print_cells();
    break;
    
  case 5:
    
    LTC6803_sttmpad();
    delay(3);
    Serial.println(F("aux conversion completed"));
    Serial.println();
    break;
    
  case 6:
    
    error = LTC6803_rdtmp(TOTAL_IC,temp_codes); // Set to read back all aux registers
    if (error == -1)
    {
      Serial.println(F("A PEC error was detected in the received data"));
    }
    print_temp();
    break;
  
  case 7:
    Serial.println(F("transmit 'm' to quit"));
   
    LTC6803_wrcfg(TOTAL_IC,tx_cfg);
    while (input != 'm')
    {
      if (Serial.available() > 0)
      {
        input = read_char();
      }
      
   
      LTC6803_stcvad();
      delay(10);
      
      error = LTC6803_rdcv(TOTAL_IC,cell_codes);
      if (error == -1)
      {
       Serial.println(F("A PEC error was detected in the received data"));
      }
      print_cells();
    
 
    if (error == -1)
    {
     Serial.println(F("A PEC error was detected in the received data"));
    }
   // print_rxconfig();
   
      delay(500);
    }
    print_menu();
    break;  
 
  default:
     Serial.println(F("Incorrect Option"));
     break; 
  }
}


//! Initializes the configuration array
void init_cfg()
{
  for(int i = 0; i<TOTAL_IC;i++)
  {
    tx_cfg[i][0] = 0xF1;
    tx_cfg[i][1] = 0x00 ; 
    tx_cfg[i][2] = 0x00 ;
    tx_cfg[i][3] = 0x00 ; 
    tx_cfg[i][4] = 0x00 ;
    tx_cfg[i][5] = 0x00 ;
  }
 
}


//! Prints the main menu 
void print_menu()
{
  Serial.println(F("Please enter LTC6803 Command"));
  Serial.println(F("Write Configuration: 1"));
  Serial.println(F("Read Configuration: 2"));
  Serial.println(F("Start Cell Voltage Conversion: 3"));
  Serial.println(F("Read Cell Voltages: 4"));
  Serial.println(F("Start Aux Voltage Conversion: 5"));
  Serial.println(F("Read Aux Voltages: 6"));
  Serial.println(F("loop cell voltages: 7"));
  Serial.println(F("Please enter command: "));
   Serial.println();
}




 //! Prints cell coltage codes to the serial port
void print_cells()
{

  
  for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++)
  {
    Serial.print(" IC ");
    Serial.print(current_ic+1,DEC);
    for(int i=0; i<12; i++)
    {
      Serial.print(" C");
      Serial.print(i+1,DEC);
      Serial.print(":");
      Serial.print(cell_codes[current_ic][i]*0.0015,4);
      Serial.print(",");
    }
     Serial.println(); 
  }
    Serial.println(); 
}


 //! Prints GPIO voltage codes and Vref2 voltage code onto the serial port
void print_temp()
{
  
  for(int current_ic =0 ; current_ic < TOTAL_IC; current_ic++)
  {
    Serial.print(" IC ");
    Serial.print(current_ic+1,DEC);
    for(int i=0; i < 2; i++)
    {
      Serial.print(" Temp-");
      Serial.print(i+1,DEC);
      Serial.print(":");
      Serial.print(temp_codes[current_ic][i]*0.0015,4);
      Serial.print(",");
    }
     Serial.print(" ITemp");
     Serial.print(":");
     Serial.print((temp_codes[current_ic][2]*0.1875)-274.15,4);
     Serial.println();
  }
  Serial.println(); 
}

//! Prints the configuration data that is going to be written to the LTC6803 to the serial port.
void print_config()
{
  int cfg_pec;
  
  Serial.println("Written Configuration: ");
  for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++)
  {
    Serial.print(" IC ");
    Serial.print(current_ic+1,DEC);
    Serial.print(": ");
    Serial.print("0x");
    serial_print_hex(tx_cfg[current_ic][0]);
    Serial.print(", 0x");
    serial_print_hex(tx_cfg[current_ic][1]);
    Serial.print(", 0x");
    serial_print_hex(tx_cfg[current_ic][2]);
    Serial.print(", 0x");
    serial_print_hex(tx_cfg[current_ic][3]);
    Serial.print(", 0x");
    serial_print_hex(tx_cfg[current_ic][4]);
    Serial.print(", 0x");
    serial_print_hex(tx_cfg[current_ic][5]);
    Serial.print(", Calculated PEC: 0x");
    cfg_pec = pec8_calc(6,&tx_cfg[current_ic][0]);
    serial_print_hex((uint8_t)(cfg_pec));
    Serial.println(); 
  }
   Serial.println(); 
}


//! Prints the configuration data that was read back from the LTC6803 to the serial port.
void print_rxconfig()
{
  Serial.println("Received Configuration ");
  for (int current_ic=0; current_ic<TOTAL_IC; current_ic++)
  {
    Serial.print(" IC ");
    Serial.print(current_ic+1,DEC);
    Serial.print(": 0x");
    serial_print_hex(rx_cfg[current_ic][0]);
    Serial.print(", 0x");
    serial_print_hex(rx_cfg[current_ic][1]);
    Serial.print(", 0x");
    serial_print_hex(rx_cfg[current_ic][2]);
    Serial.print(", 0x");
    serial_print_hex(rx_cfg[current_ic][3]);
    Serial.print(", 0x");
    serial_print_hex(rx_cfg[current_ic][4]);
    Serial.print(", 0x");
    serial_print_hex(rx_cfg[current_ic][5]);
    Serial.print(", Received PEC: 0x");
    serial_print_hex(rx_cfg[current_ic][6]);
    
    Serial.println(); 
  }
   Serial.println(); 
}

//! Print Data Byte in Hex Format
void serial_print_hex(uint8_t data)
{
    if (data < 16)
    {
      Serial.print("0");
      Serial.print((byte)data,HEX);
    }
    else
      Serial.print((byte)data,HEX);
}

Download LTC6803-2 Linduino Header File

/*!
LTC6803-2 Multicell Battery Monitor

/************************************
REVISION HISTORY
$Revision: 3536 $
$Date: 2015-01-8

Copyright (c) 2015, Linear Technology Corp.(LTC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.

Copyright 2015 Linear Technology Corp. (LTC)
*/

/*! @file
    @ingroup LTC68032
    Library Header File for LTC6803-2 Multicell Battery Monitor
*/

#ifndef LTC68032_H
#define LTC68032_H


#ifndef LTC6803_CS
#define LTC6803_CS QUIKEVAL_CS
#endif

#define PEC_POLY 7

//!Initializes the SPI port
//! @return void
void LTC6803_initialize();

//! Function to start Cell Voltage measurement
//! @return void
void LTC6803_stcvad();

//! Function to start Temp channel voltage measurement
//! @return void
void LTC6803_sttmpad();

//! Function that reads Cell Voltage registers
//! @returns  This function will return a 0 if there is no PEC error and will return -1 if there is a PEC error
uint8_t LTC6803_rdcv(uint8_t total_ic, 			//!< total_ic number of LTC6803 ICs in stack
					 uint16_t cell_codes[][12]	//!< The Function will put the parsed measured cell voltages into this array
					 );
					 
//! Function that reads Temp Voltage registers	
//! @returns  This function will return a 0 if there is no PEC error and will return -1 if there is a PEC error
int8_t LTC6803_rdtmp(uint8_t total_ic,			//!< total_ic number of LTC6803 ICs in stack
					 uint16_t temp_codes[][3]	//!< The Function will put the parsed measured Temp voltages into this array
					 );
					 
//! Function that writes configuration of LTC6803-2/-4					 
//! @return void
void LTC6803_wrcfg(uint8_t total_ic,			//!< total_ic number of LTC6803 ICs in stack
				   uint8_t config[][6]			//!< The function will write the 6803 CFGR register with data in the config array
				   );

//! Function that reads configuration of LTC6803-2/-4			   
//! @returns  This function will return a 0 if there is no PEC error and will return -1 if there is a PEC error
int8_t LTC6803_rdcfg(uint8_t total_ic, 			//!< total_ic number of LTC6803 ICs in stack
					 uint8_t r_config[][7]		//!< The Function will put the read config register data into this array
					 );
//! Function that calculates PEC byte
//! @returns The calculated CRC8
uint8_t pec8_calc(uint8_t len,					//!< the length of the data array
				  uint8_t *data					//!< data array
				  );
				  
//! Writes an array of bytes out of the SPI port
//! @return void
void spi_write_array(uint8_t length,			//!< length of the data array being written on the SPI port
					 uint8_t *data				//!< the data array to be written on the SPI port
					 );

//! Writes and read a set number of bytes using the SPI port.					 
//! @return void
void spi_write_read(uint8_t *TxData,			//!< array of data to be written on the SPI port
					uint8_t TXlen,				//!< length of the tx_data array
					uint8_t *rx_data,			//!< array that read data will be written too.
					uint8_t RXlen				//!< number of bytes to be read from the SPI port.
					);

#endif

Download LTC6803-2 Linduino.CPP

/*!
  LTC6803-2 Multicell Battery Monitor
@verbatim
  The LTC6803 is a 2nd generation multicell battery stack
  monitor that measures up to 12 series connected cells. The
  cell measurement range of -0.3V to 5V makes the LTC6803
  suitable for most battery chemistries.

  Using the LTC6803-2, multiple devices can be connected in
  parallel with one host processor connection for all
  devices.
@endverbatim
REVISION HISTORY
$Revision: 3537 $
$Date: 2015-1-8

Copyright (c) 2015, Linear Technology Corp.(LTC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.

Copyright 2015 Linear Technology Corp. (LTC)
***********************************************************/
//! @defgroup LTC68032 LTC6803-2: Multicell Battery Monitor

/*! @file
    @ingroup LTC68032
    Library for LTC6803-2 Multicell Battery Monitor
*/

#include <stdint.h>
#include <Arduino.h>
#include "Linduino.h"
#include "LT_SPI.h"
#include "LTC68032.h"
#include <SPI.h>

/***************************************************************************
***********6803 Functions***************************************************
***************************************************************************/


//!Initializes the SPI port
void LTC6803_initialize()
{
  quikeval_SPI_connect();
  spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock

}




// Function that writes configuration of LTC6803-2/-3
void LTC6803_wrcfg(uint8_t total_ic,uint8_t config[][6])
{
  uint8_t BYTES_IN_REG = 6;
  uint8_t CMD_LEN = 4+7;
  uint8_t *cmd;
  uint16_t cfg_pec;
  uint8_t cmd_index; //command counter

  cmd = (uint8_t *)malloc(CMD_LEN*sizeof(uint8_t));
  for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
  {
    cmd[0] = 0x80 + current_ic;
    cmd[1] = pec8_calc(1,cmd);

    cmd[2] = 0x01;
    cmd[3] = 0xc7;

    cmd_index = 4;


    for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++)
    {
      cmd[cmd_index] = config[current_ic][current_byte];
      cmd_index = cmd_index + 1;
    }

    cfg_pec = pec8_calc(BYTES_IN_REG, &config[current_ic][0]);    // calculating the PEC for each ICs configuration register data
    cmd[cmd_index ] = (uint8_t)cfg_pec;
    cmd_index = cmd_index + 1;


    output_low(LTC6803_CS);
    spi_write_array(CMD_LEN, cmd);
    output_high(LTC6803_CS);
  }
  free(cmd);
}


//!Function that reads configuration of LTC6803-2/-3
int8_t LTC6803_rdcfg(uint8_t total_ic, //Number of ICs in the system
                     uint8_t r_config[][7] //A two dimensional array that the function stores the read configuration data.
                    )
{
  uint8_t BYTES_IN_REG = 7;

  uint8_t cmd[4];
  uint8_t *rx_data;
  int8_t pec_error = 0;
  uint8_t data_pec;
  uint8_t received_pec;

  rx_data = (uint8_t *) malloc((BYTES_IN_REG*total_ic)*sizeof(uint8_t));



  for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)       //executes for each LTC6803 in the daisy chain and packs the data
  {
    //into the r_config array as well as check the received Config data
    //for any bit errors

    cmd[0] = 0x80 + current_ic;
    cmd[1] = pec8_calc(1,cmd);
    cmd[2] = 0x02;
    cmd[3] = 0xCE;


    output_low(LTC6803_CS);
    spi_write_read(cmd, 4, rx_data, (BYTES_IN_REG*total_ic));
    output_high(LTC6803_CS);


    for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++)
    {
      r_config[current_ic][current_byte] = rx_data[current_byte];
    }

    received_pec =  r_config[current_ic][6];
    data_pec = pec8_calc(6, &r_config[current_ic][0]);
    if (received_pec != data_pec)
    {
      pec_error = -1;
    }
  }

  free(rx_data);
  return(pec_error);
}


//!Function that starts Cell Voltage measurement
void LTC6803_stcvad()
{
  output_low(LTC6803_CS);
  spi_write(0x10);
  spi_write(0xB0);
  output_high(LTC6803_CS);
}


//! Function that Temp channel voltage measurement
void LTC6803_sttmpad()
{
  output_low(LTC6803_CS);
  spi_write(0x30);
  spi_write(0x50);
  output_high(LTC6803_CS);
}



//!Function that reads Temp Voltage registers
int8_t LTC6803_rdtmp(uint8_t total_ic, uint16_t temp_codes[][3])
{
  int data_counter = 0;
  int pec_error = 0;
  uint8_t data_pec = 0;
  uint8_t received_pec = 0;
  uint8_t cmd[4];
  uint8_t *rx_data;
  rx_data = (uint8_t *) malloc((7)*sizeof(uint8_t));
  for (int i=0; i<total_ic; i++)
  {
    cmd[0] = 0x80 + i;
    cmd[1] = pec8_calc(1,cmd);
    cmd[2] = 0x0E;
    cmd[3] = 0xEA;
    output_low(LTC6803_CS);
    spi_write_read(cmd, 4,rx_data,6);
    output_high(LTC6803_CS);

    received_pec =  rx_data[5];
    data_pec = pec8_calc(5, &rx_data[0]);
    if (received_pec != data_pec)
    {
      pec_error = -1;
    }

    int cell_counter = 0;
    data_counter = 0;
    int temp,temp2;

    temp = rx_data[data_counter++];
    temp2 = (rx_data[data_counter]& 0x0F)<<8;
    temp_codes[i][0] = temp + temp2 -512;
    temp2 = (rx_data[data_counter++])>>4;
    temp =  (rx_data[data_counter++])<<4;
    temp_codes[i][1] = temp+temp2 -512;
    temp2 = (rx_data[data_counter++]);
    temp =  (rx_data[data_counter++]& 0x0F)<<8;
    temp_codes[i][2] = temp+temp2 -512;
  }
  free(rx_data);
  return(pec_error);
}


//! Function that reads Cell Voltage registers

uint8_t LTC6803_rdcv( uint8_t total_ic, uint16_t cell_codes[][12])
{
  int data_counter =0;
  int pec_error = 0;
  uint8_t data_pec = 0;
  uint8_t received_pec = 0;
  uint8_t *rx_data;
  uint8_t cmd[4];
  rx_data = (uint8_t *) malloc((19)*sizeof(uint8_t));

  for (int i=0; i<total_ic; i++)
  {
    cmd[0] = 0x80 + i;
    cmd[1] = pec8_calc(1,cmd);
    cmd[2] = 0x04;
    cmd[3] = 0xDC;
    output_low(LTC6803_CS);
    spi_write_read(cmd, 4,rx_data,19);
    output_high(LTC6803_CS);

    received_pec =  rx_data[18];
    data_pec = pec8_calc(18, &rx_data[0]);
    if (received_pec != data_pec)
    {
      pec_error = -1;
    }

    int cell_counter = 0;
    data_counter = 0;
    uint16_t temp,temp2;

    for (int k = 0; k<12; k=k+2)
    {
      temp = rx_data[data_counter++];
      temp2 = (uint16_t)(rx_data[data_counter]&0x0F)<<8;
      cell_codes[i][k] = temp + temp2 -512;
      temp2 = (rx_data[data_counter++])>>4;
      temp =  (rx_data[data_counter++])<<4;
      cell_codes[i][k+1] = temp+temp2 -512;
    }

  }
  free(rx_data);
  return(pec_error);
}

//!Function that calculates PEC byte

uint8_t pec8_calc(uint8_t len, uint8_t *data)
{

  uint8_t  remainder = 0x41;//PEC_SEED;


  /*
   * Perform modulo-2 division, a byte at a time.
   */
  for (int byte = 0; byte < len; ++byte)
  {
    /*
     * Bring the next byte into the remainder.
     */
    remainder ^= data[byte];

    /*
     * Perform modulo-2 division, a bit at a time.
     */
    for (uint8_t bit = 8; bit > 0; --bit)
    {
      /*
       * Try to divide the current data bit.
       */
      if (remainder & 128)
      {
        remainder = (remainder << 1) ^ PEC_POLY;
      }
      else
      {
        remainder = (remainder << 1);
      }
    }
  }

  /*
   * The final remainder is the CRC result.
   */
  return (remainder);

}


//! Writes an array of bytes out of the SPI port
void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port
                     uint8_t data[] //Array of bytes to be written on the SPI port
                    )
{
  for (uint8_t i = 0; i < len; i++)
  {
    spi_write((int8_t)data[i]);
  }
}


//!Writes and read a set number of bytes using the SPI port.
void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
                    uint8_t tx_len, //length of the tx data arry
                    uint8_t *rx_data,//Input: array that will store the data read by the SPI port
                    uint8_t rx_len //Option: number of bytes to be read from the SPI port
                   )
{
  for (uint8_t i = 0; i < tx_len; i++)
  {
    spi_write(tx_Data[i]);

  }

  for (uint8_t i = 0; i < rx_len; i++)
  {
    rx_data[i] = (uint8_t)spi_read(0xFF);
  }

}

Technical Support