Amazon

Thursday 30 April 2015

Interfacing with the BQ24725 battery charger

The BQ24725 is a 1-4 cell battery charge manager with SMBus protocol from Texas Instruments. Here's an example C firmware to interface with the charger using a PIC16 from Microchip. This example is made to charge a 2-cell Lithium-Ion battery 8.4V, 10000 mAh. Note that it is using I2C protocol which is equivalent to SMBUS.


#define CHARGER_OPTIONS_INIT_H 0x09
#define CHARGER_OPTIONS_INIT_L 0x24 //Charger init options
                                                                           //BAT Depletion 62.65%                                                                                                                                                         //(~2.631V/cell),charge current
#define CHARGER_CURRENT_L 0x00
#define CHARGER_CURRENT_H 0x08 //Set Charger current to 2048mA
#define CHARGER_VOLTAGE_L 0xD0
#define CHARGER_VOLTAGE_H 0x20 //Set Charger voltage to 8400mV
#define INPUT_CURRENT_L 0x00 
#define INPUT_CURRENT_H 0x0D //Set Input current to 3328mA
#define Charger_addr 0x12                                 //I2C address of BQ24725

void CHARGER_init()                          //BQ24725 initialization
{
SSP2CON1bits.SSPEN = 1;

    //Set Option to Iout = charge current
I2C_SendCommand_2Bytes(Charger_addr,0x12,CHARGER_OPTIONS_INIT_L,CHARGER_OPTIONS_INIT_H);  

    //Set Charger current                                                                                              
I2C_SendCommand_2Bytes(Charger_addr,0x14,CHARGER_CURRENT_L,CHARGER_CURRENT_H);

   //Set Charger voltage 
I2C_SendCommand_2Bytes(Charger_addr,0x15,CHARGER_VOLTAGE_L,CHARGER_VOLTAGE_H);

    //Set input current
I2C_SendCommand_2Bytes(Charger_addr,0x3F,INPUT_CURRENT_L,INPUT_CURRENT_H);

SSP2CON1bits.SSPEN = 0;
}


void CHARGER_ChargingEnable(char enabled)         //Enable / Disable the charging
{
enabled = 1 - enabled;

SSP2CON1bits.SSPEN = 1;

    //Send the Instruction to the charger
I2C_SendCommand_2Bytes(Charger_addr,0x12,CHARGER_OPTIONS_INIT_L+enabled, CHARGER_OPTIONS_INIT_H);

SSP2CON1bits.SSPEN = 0;
}


If you need a routine for the I2C communication:


void I2C_SendCommand_2Bytes(unsigned char Address, unsigned char Command, unsigned char LowByte, unsigned char HighByte)
{
SSP2CON1bits.SSPEN = 1;
SSP2CON2bits.SEN = 1; //Send start
WaitBufferEmpty();

SSP2BUF = Address;
WaitBufferEmpty();

SSP2BUF = Command; //Send command
WaitBufferEmpty();

SSP2BUF = LowByte; //Send low byte
WaitBufferEmpty();

SSP2BUF = HighByte; //Send high byte
WaitBufferEmpty();

SSP2CON2bits.PEN = 1; //Send stop
WaitBufferEmpty();
return;
}

unsigned char I2C_ReadCommand(unsigned char Address, unsigned char Command)
{
unsigned char Byte_read;

SSP2CON2bits.SEN = 1; //Send start
WaitBufferEmpty();

SSP2BUF = Address;
while (SSP2CON2bits.ACKSTAT); //wait for ACK received
WaitBufferEmpty();

SSP2BUF = Command; //Send command
WaitBufferEmpty();

SSP2CON2bits.RSEN = 1; //Send repeat start
WaitBufferEmpty();

SSP2BUF = Address+1;
while (SSP2CON2bits.ACKSTAT); //wait for ACK received
WaitBufferEmpty();

SSP2CON2bits.RCEN = 1; //Set in receive
WaitBufferEmpty();

Byte_read = SSP2BUF; //Read buffer

SSP2CON2bits.ACKDT = 0;
SSP2CON2bits.ACKEN = 1; //Start Acknowledge sequence
WaitBufferEmpty();

return Byte_read;;
}

unsigned char I2C_ReadByte()
{
char Byte_read;

SSP2CON2bits.RCEN = 1; //Set in receive
WaitBufferEmpty();

Byte_read = SSP2BUF; //Read buffer

SSP2CON2bits.ACKDT = 1;
SSP2CON2bits.ACKEN = 1; //Start Not Acknowledge sequence
WaitBufferEmpty();
SSP2CON2bits.PEN = 1; //Send stop
WaitBufferEmpty();

  return Byte_read;;
}

void WaitBufferEmpty()
{
if (SSP2CON1bits.WCOL)
SSP2CON1bits.WCOL = 0;

SSP2IF = 0;
}





Friday 10 April 2015

Interfacing with TPL9201 relay driver using a PIC

The TPL9201 is a 8-channel relay driver that uses serial communication. For the purpose of this article, I will be using a PIC16F1782 from Microchip to interface but the code can be used with any microcontroller from the PIC16 family. The C compiler used is from Hi-Tech

To interface with the TPL9201, you need 3 I/O pins from the microcontroller; Chip Select (CS), Data (SDO), and Clock (SCK).

In this example, relays that are used are EC2-5NU from NEC. To activate a relay, you need to send a "1" to the corresponding control register bit of the TPL9201. On the other hand, if you want to release the relay, you need to send a "0".
The control register is illustrated below:

MSB                                           LSB 
IN8 IN7 IN6 IN5 IN4 IN3 IN2 IN1 
 0      0      0     0      0     0      0     0 

INn = 0: Output OFF 
INn = 1: Output ON

Following is the code to activate all 8 relays and then release them.

#include "htc.h"
#include "pic16f1782.h"

#ifndef _XTAL_FREQ
#define _XTAL_FREQ 16000000
#endif

#define CS RA5
#define SCK RC3
#define SDO RC5

void spi_writebit(unsigned char SPI_DATAbit)
{
SDO = SPI_DATAbit;
__delay_ms(1);
SCK = 1;
__delay_ms(1);
SCK = 0;
}

void spi_write(unsigned char SPI_DATA)
{
char Bit_counter;
char Bit_send;

CS = 0;
SDO = 0;
SCK = 0;
__delay_ms(1);

for (Bit_counter = 0;Bit_counter<=7;Bit_counter++)
{
Bit_send = (SPI_DATA>>(7-Bit_counter))&0x01;
spi_writebit(Bit_send);
}
SCK = 0;
SDO = 0;
__delay_ms(1);
CS = 1;
}

void Relay_Control(unsigned char Relay_no, unsigned char Relay_State)
{
if (Relay_State)
Buffer_Value = Buffer_Value | (1<<(Relay_no-1));
else
Buffer_Value = Buffer_Value & (0xFF - (1<<(Relay_no-1)));

spi_write(Buffer_Value);
}

void main()
{
  int Relay_number;

  for (Relay_number = 0;Relay_number<=7;Relay_number++)
Relay_Control(Relay_number,1); //Activate all 8 relays

for (Relay_number = 0;Relay_number<=7;Relay_number++)
Relay_Control(Relay_number,0); //Release all 8 relays
}