APPLICATION NOTE Software to Getting Started with Atmel ATA6870 ATA6870 Software Components This description covers the main components for starting communication between the Atmel® ATA6870 and the microcontroller. It provides the basis for creating your own battery-management setup. The software was written in the AVR Studio® environment, version 4.16, using GNU C compiler. The description includes: ● Definitions of specific variables for the microcontroller ● Serial Peripheral interface (SPI) communication functions ● Functions for converting and calculating received data ● Dedicated functions for battery management ● An example program showing how to use functions 9180D-AUTO-07/15 1. Definitions 1.1 Clock Frequency The microcontroller system clock is set to 8 MHz, and is necessary for: ● ADC synchronization and ● SPI timing, see Section 2.2 “Microcontroller Initalizing” on page 4 #ifndef F_CPU #define F_CPU 8000000UL #endif 1.2 SPI Variables ● ● Port and pin definitions of the SPI The interface is realized by the hardware SPI on the microcontroller #define #define #define #define #define #define ● 1.3 DDR_SPI DDRB PORT_SPI PORTB MOSI_1 PINB1 MISO PINB0 SCK_1 PINB7 SS PIND3 Pin assignment is specific to the ATmega32M1 microcontroller. Requirements for other microcontrollers will need to be adapted according to their datasheets. Delay Delays are realized by delay library functions: #include <util/delay.h> The delay functions are mainly used to generate timing for SPI synchronization ● _delay_ms() ● 2 _delay_us() ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 2. SPI Communication 2.1 SPI Master-slave Interconnection Figure 2-1. Master - Slave - Connection MSB MASTER LSB MISO MISO MSB 8 Bit Shift Register SLAVE LSB 8 Bit Shift Register MOSI MOSI SHIFT ENABLE SPI Clock Generator SCK SCK Figure 2-1 Master - Slave - Connection shows the interconnection between master and slave CPUs. The system consists of two shift registers, and a master clock generator. The SPI master initiates the communication cycle when pulling the slave select (SS) pin of the required slave to low. Master and slave prepare the data to be sent in their respective shift registers, and the master generates the required clock pulses on the serial clock (SCK) line to interchange data. Data is always shifted from master to slave on the Master Out Slave In (MOSI) line, and from slave to master on the Master In Slave Out (MISO) line. After each data packet, the master synchronizes the slave by setting the SS line to high. When configured as a master, the SPI has no automatic control of the SS line. The initial start and stop of SPI data transfer via the SS pin must be managed by user software. Writing a byte to the SPI data register (SPDR) starts the SPI clock generator, and the hardware shifts the eight bits to the slave. After shifting the byte, the SPI clock generator stops, which sets the end of transmission flag (SPIF). If the SPI interrupt enable (SPIE) bit is set in the SPI control register (SPCR), an interrupt is requested. Interrupts are not needed for the initial steps to set up simple communication. The master can continue to shift the next byte by writing it to the SPDR, or signal the end of the packet by pulling the SS line to high. The last incoming byte will be kept in the buffer register for later use. ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 3 2.2 Microcontroller Initalizing ● ● ● 2.2.1 Two independent microcontroller clocks are necessary for Atmel® ATA6870 operation: 1. SCK is the clock for SPI communication 2. CLK synchronizes the ADCs of the different Atmel ATA6870s CLK pin is configured with a permanent clock rate of 500kHz Maximum SCK frequency is half of CLK frequency, 250kHz ATA6870 Initialisation { // turn on ATA6870 DDRC |= (1<< PINC0); // set PD_N_OPTO_HI as output PORTC = (1<< PINC0); // PD_N_OPTO_HI pulling High // CLK init DDRD |= (1<< PIND2); // OC1A Output Pin synchronisation Clock TCCR1A = (1<<COM1A0)|(1<<WGM11)|(1<<WGM10); // Toggle on match, Phase correct TCCR1B = (1<<WGM13)|(1<<CS10); //no prescaling (datasheet 16 bit Timer/Counter Register Description) OCR1A = 0x0004; // Top value } 2.2.2 SPI Initialisation void SPI_Master_Init(void) { // set MOSI, SCK and SS output, MISO Input DDRD |= (1<<SS); DDR_SPI |= (1<<MOSI_1)|(1<<SCK_1); DDR_SPI &= ~(1<<MISO); // Enable SPI, Master mode, set clock rate fck/32 SCK // (datasheet ATmega32M1 SPI Control Register, SPI Status Register) SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1); SPSR = (1<<SPI2X); } 4 ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 2.3 Send and Receive uint8_t SPI_Transfer(uint8_t sByte) { SPDR = sByte; while(!(SPSR & (1<<SPIF))); return SPDR; } ● Send one byte void SPI_Send( uint8_t wrorrd ,uint8_t chipnr,uint8_t addr,uint8_t command) { PORTD &= ~(1<<SS); SPI_Transfer(wrorrd); SPI_Transfer(chipnr); SPI_Transfer(addr); SPI_Transfer(command); PORTD |= (1<<SS); } ● Send four bytes as a command void SPI_SendBurst(uint8_t wrorrd_1 uint8_t chipnr_1, uint8_t command_1, uint8_t* sendV, uint8_t* receiveV, uint8_t* sendT, uint8_t* receiveT) { uint8_t i=0; PORTD &= ~(1<<SS); SPI_Transfer(wrorrd_1); // choice whether to write or read SPI_Transfer(chipnr_1); // choice of chip number SPI_Transfer(command_1); // choice kind of command for(i=0;i<12;i++) { *receiveV=SPI_Transfer(*sendV++); // send 12 bytes and receive 12 *receiveV++; // bytes at the same time } for(j=0;j<2;j++) { *receiveT=SPI_Transfer(*sendT++); *receiveT++; } PORTD |= (1<<SS); } A complete voltage measurement burst consists of 17 bytes: ● The first 3 bytes are dummies with a value of 0x00 ● ● 12 bytes have relevant information for calculating cell voltage 2 bytes have relevant information for calculating temperature ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 5 2.4 Data Processing and Cell-voltage Calculation 2.4.1 Data Conversion for Voltage and Temperature void data_conversionV(uint16_t* data1, uint8_t* data2) { uint8_t i=0; for(i=0;i<6;i++) { *data1 = *data2; // push first byte in 16 bit variable *data2++; // take next byte *data1 = *data1*256; // push first byte in high byte of 16 bit // variable *data1 |= *data2; // link low byte of 16 bit variable with next byte *data2++; // take next 8 bit *data1++; // take next 16 bit } } void data_conversionT(uint16_t* data1, uint8_t* data2) { *data1 = *data2; // push first byte in 16 bit variable *data2++; // take next byte *data1 = *data1*256; // push first byte in high byte of 16 bit variable *data1 |= *data2; // link low byte of 16 bit variable with next byte } ● ● 2.4.2 Conversion of two 8-bit words into a 16-bit word ATmega32M1 is an 8-bit microcontroller and allows 8-bit data transfer only Voltage Calculation void calculateV(float * vbat, uint16_t* acq, uint16_t* offset) { uint8_t i=0; float var2, var3; for (i=0;i<6;i++) { var2 =(float)*acq++; // casting data from adc - value to float var3 =(float)*offset++; *vbat++ = ((var2-var3)/(3031-var3) * 4); // take all values and calculate vbat } } ● The equation for calculating voltage, according to the ATA6870 datasheet adc (AcqV) – adc (VOffset) Cellvoltage VBAT = ------------------------------------------------------------------- 4V 3031 – adc (VOffset) 6 ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 3. Dedicated Battery Management Functions 3.1 Cell Undervoltage Detection void undervoltage(float under, float *vbat_1) { uint8_t a=0x00, b=0x00, c=0x00, d=0x00, e=0x00, f=0x00; // cell voltage below undervoltage detection level if (vbat_1[0]<under){a=0x20;} if (vbat_1[1]<under){b=0x10;} if (vbat_1[2]<under){c=0x08;} if (vbat_1[3]<under){d=0x04;} if (vbat_1[4]<under){e=0x02;} if (vbat_1[5]<under){f=0x01;} // Possible to program if (a==0x20) {} if (b==0x10) {} if (c==0x08) {} if (d==0x04) {} if (e==0x02) {} if (f==0x01) {} } ● 3.2 a warning, other protections or start charging // sixth cell is detected // fifth cell is detected // fourth cell is detected // third cell is detected // second cell is detected // first cell is detected “under” sets the threshold to detect undervoltage, e.g. an occurrence of deep discharge Cell Overvoltage Detection void discharge(float upper, float *vbat_1) { uint8_t a=0x00, b=0x00, c=0x00, d=0x00, e=0x00, f=0x00, g=0x00; //determine whether there is an overload on that cell if (vbat_1[0]>upper) {a=0x20;} if (vbat_1[1]>upper) {b=0x10;} if (vbat_1[2]>upper) {c=0x08;} if (vbat_1[3]>upper) {d=0x04;} if (vbat_1[4]>upper) {e=0x02;} if (vbat_1[5]>upper) {f=0x01;} g=0x00|a|b|c|d|e|f; if (g != 0x00) { // command to discharge detected cells SPI_Send(0x00,0x01,0x13,g); } else { // command to stop discharge SPI_Send(0x00,0x01,0x13,0x00); } } ● “upper” sets the threshold to detect overvoltage, e.g. an overload occurrence ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 7 4. Main Program float VBAT[6]; int main(void) { ATA6870_Init(); SPI_MasterInit(); // Variable uint8_t sendDataV[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; uint8_t sendDataT[2]={0x00,0x00}; uint8_t receiveDataV[12]; // definition of the arrays to use it as buffer uint8_t receiveDataT[2]; uint16_t acquisition[6]; uint16_t offset[6]; while (1) // Main loop { //write8Bit,chip1,addr5,data02 # wakeup irq suppressed SPI_Send(0x00,0x01,0x0B,0x02); _delay_ms(10); //write8Bit,chip1,addr2,data03 #acquisition V SPI_Send(0x00,0x01,0x05,0x03); _delay_ms(10); //read8Bit,chip1,addr6 #read status reg SPI_Send(0x00,0x01,0x0C,0x00); _delay_ms(10); //burst_read,chip1 SPI_SendBurst(0x00,0x01,0xFE,&sendDataV[0],&receiveDataV[0], &sendDataT[0],&receiveDataT[0]); data_conversionV(&acquisition[0],&receiveDataV[0]); //write8Bit,chip1,addr2,data01 #acquisition offset SPI_Send(0x00,0x01,0x05,0x01); _delay_ms(10); //read8Bit,chip1,addr6 #read status reg SPI_Send(0x00,0x01,0x0C,0x00); _delay_ms(10); //burst_read,chip1 SPI_SendBurst(0x00,0x01,0xFE,&sendDataV[0],&receiveDataV[0], &sendDataT[0],&receiveDataT[0]); _delay_ms(10); data_conversionV(&offset[0],&receiveDataV[0]); // Calculation calculateV(&VBAT[0],&acquisition[0],&offset[0]); undervoltage(2.8,&VBAT[0]); // Undervoltage Detection Threshold discharge(4.1,&VBAT[0]); // Discharge Voltage Threshold return 0; } 8 ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 First, the main program calls the function SPI_MasterInit() to initialize the microcontroller. Next, all data arrays required for battery management are defined. Battery management occurs in a permanently repeating “while(1)” -loop, which includes functions to read cell voltage values. The program acquires, reads-out, and converts data, as well as calculating cell voltages. Finally, there is the detection function, which checks the upper and lower thresholds. Table 4-1. Sequence of Command Set Number Command 1 Suppresses an unwanted interrupt by a timer 2 Requests data 3 Reads the status register 4 Acquires the data burst 5 Converts data in an array Data acquisition is repeated 2 times (commands 2 to 5) to acquire voltage and offset. The acquisition time can be reduced by assuming that offset are stable, and reading the voltage value only. The length of the delays between commands depends on the number of ATA6870s in the string (refer to the ATA6870 “Acquisition Time and Clocking” datasheet). For further details, please refer to the ATA6870 datasheet or contact [email protected] ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 9 5. Revision History Please note that the following page numbers referred to in this section refer to the specific revision mentioned, not to this document. 10 Revision No. History 9180D-AUTO-07/15 Put document in the latest template ATA6870 Software Interface [APPLICATION NOTE] 9180D–AUTO–07/15 XXXXXX Atmel Corporation 1600 Technology Drive, San Jose, CA 95110 USA T: (+1)(408) 441.0311 F: (+1)(408) 436.4200 | www.atmel.com © 2015 Atmel Corporation. / Rev.: 9180D–AUTO–07/15 Atmel®, Atmel logo and combinations thereof, Enabling Unlimited Possibilities®, AVR®, and others are registered trademarks or trademarks of Atmel Corporation in U.S. and other countries. Other terms and product names may be trademarks of others. DISCLAIMER: The information in this document is provided in connection with Atmel products. No license, express or implied, by estoppel or otherwise, to any intellectual property right is granted by this document or in connection with the sale of Atmel products. EXCEPT AS SET FORTH IN THE ATMEL TERMS AND CONDITIONS OF SALES LOCATED ON THE ATMEL WEBSITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED OR STATUTORY WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS AND PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Atmel makes no representations or warranties with respect to the accuracy or completeness of the contents of this document and reserves the right to make changes to specifications and products descriptions at any time without notice. Atmel does not make any commitment to update the information contained herein. Unless specifically provided otherwise, Atmel products are not suitable for, and shall not be used in, automotive applications. Atmel products are not intended, authorized, or warranted for use as components in applications intended to support or sustain life. SAFETY-CRITICAL, MILITARY, AND AUTOMOTIVE APPLICATIONS DISCLAIMER: Atmel products are not designed for and will not be used in connection with any applications where the failure of such products would reasonably be expected to result in significant personal injury or death (“Safety-Critical Applications”) without an Atmel officer's specific written consent. Safety-Critical Applications include, without limitation, life support devices and systems, equipment or systems for the operation of nuclear facilities and weapons systems. Atmel products are not designed nor intended for use in military or aerospace applications or environments unless specifically designated by Atmel as military-grade. Atmel products are not designed nor intended for use in automotive applications unless specifically designated by Atmel as automotive-grade.