Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16F684 based lithium ion cell charger

Status
Not open for further replies.
I'm trying to make a li ion battery charger using a PIC because the one I recently bought from Ebay looks like a simple SMPS with no protection or anything.

Anyway the problem I am having is I'm trying to get the PIC to read the voltage from an ADC and turn on a LED (eventually a transistor) to supply current to the cell and switch it off when the voltage reaches 4.0V but I can't see why it's not working - probably something small (syntax, register not setup properly, etc.) All that happens is D1 is on all the time and I can't tell if the ADC part is working or not.

Code:
/*

Main.Single.Cell.Charger.c

Created by: Jules Lewarne
Date: 17/09/2010

*/

#include <htc.h>

  //CONFIGURATION BASED ON 16F684.h and pic.h and CONFIG reg pg 94

  __CONFIG(FCMDIS & IESODIS & BORDIS & UNPROTECT & MCLRDIS & PWRTDIS & WDTDIS & INTIO);

  //  FCMDIS:     Disabled Fail-safe clock monitor because we don't use an ext osc
  //  IESODIS:    Internal/External Switch over is disabled (we aren't using an ext osc)
  //  BORDIS:     Brown Out detection disabled
  //  UNPROTECT:  Disable Program Code Protection
  //  MCLRDIS:    Disables pin 4 on chip from being able to clear memory externally
  //  PWRTDIS:    Allows for a min time before PIC works
  //  WDTDIS:     Disable Watchdog timer
  //  INTIO:      RA4 and RA5 are I/O instead of CLKOUT


//Define Variables

int i,j;
int dlay = 100;
int CellVoltage = 0;
int Current = 0;
int ADCState = 0;


void init(void) 
{
	CMCON0 = 0x07;	//Comparators off. Digital I/O
	PORTA = 0x00;	//Clear PORTA 
	//PORTC = 0x00;	//Clear PORTC
	TRISA = 0b00001111;	//Set PORTA all as outputs
	//TRISC = 0x00;	//Set RC0 and RC1 as outputs, rest to Output

	//ADC Initialize
	ANSEL = 0x01;	//Set AN0 as analogue input
	ADCON0 = 0x01;	//Turn on ADC channel 0
					//Bit 7 - Left Justified
					//Bit 6 - Use Vdd as ref.
					//Bit 4:2 - Channel 0
					//Bit 1 - Do Not Start
					//Bit 0 - Turn on ADC
	ADCON1 = 0x10;	//Select the clock Fosc/8

}


void cellvolt(void)	
{
	switch (ADCState)	//ADC State Machine
					{
					case 0:			//Finished, Start next sample
						GODONE = 1;
						ADCState++;
						break;
					case 1:			//Wait for ADC to complete
						if (!GODONE)
							ADCState++;
						break;
					case 2:			//Save sample value in "CellVoltage"
						CellVoltage = ADRESH;
			
						ADCState = 0;
					
						break;
								
					}
				
}


void main(void) 
{ 
	INTCON = 0;
	init();
        while(1) 
        {
			PORTA = 0b00100000;
			for (i = 0; i < dlay; i++)
			{
				for (j = 0; j < 160; j++) {};
			}
			
				
				cellvolt();	//Read CellVoltage

				if (CellVoltage < 128) //check ADC count is less than 128
					PORTA = 0x00; //switch on D0

				else
					PORTA = 0x10; //switch off D0 when threshold reached
				
						for (i = 0; i < dlay; i++)
					{
						for (j = 0; j < 160; j++) {};
					}
			
        }
}

It's been a couple of months since I was last tinkering with PICs and I was struggling with the basics then.

FYI, I'm using a PICKIT1 and MPLAB 8.53 if that makes a difference.

Jules
 
I thought that was what the switch / state machine was doing. I tried removing the ADC part and just get it to flash the LED on and off but can't even do that. Can someone suggest a simple LED flasher code?

Jules
 
Are you using the pickit1 demo board if so try this
Code:
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT \
  & UNPROTECT & BORDIS & IESODIS & FCMDIS);


int i, j;
int ADCState = 0;               //  Keep Track of ADC Operation
int ADCValue = 0;
int Dlay = 63;                  //  LED Time on Delay Variable
const char PORTAValue[8] = {0b010000, 0b100000, 0b010000, 0b000100, 
                            0b100000, 0b000100, 0b000100, 0b000010};
const char TRISAValue[8] = {0b001111, 0b001111, 0b101011, 0b101011, 
                            0b011011, 0b011011, 0b111001, 0b111001};
const char NOTPORTA[8] = {0, 0, 0, 0, 0, 0, 0, 0};

main()
{

    PORTA = 0;
    CMCON0 = 7;                 //  Turn off Comparators
    ANSEL = 1;                  //  Just RA0 is an Analog Input

    ADCON0 = 0b00000001;        //  Turn on the ADC
                                //   Bit 7 - Left Justified Sample
                                //   Bit 6 - Use VDD
                                //   Bit 4:2 - Channel 0
                                //   Bit 1 - Do not Start
                                //   Bit 0 - Turn on ADC
    ADCON1 = 0b00010000;        //  Selemct the Clock as Fosc/8

    while(1 == 1)               //  Loop Forever
    {
        for (i = 0; i < 8; i++ )
        {                       //  Loop through Each of the 8 LEDS
            for (j = 0; j < Dlay; j++);  //  Display "On" Delay Loop
            if ((ADCValue & (1 << i)) == 0)
                PORTA = NOTPORTA[i];
            else
                PORTA = PORTAValue[i];
            TRISA = TRISAValue[i];
        }  //  rof
        switch (ADCState)       //  ADC State Machine
        {
            case 0:             //  Finished, Start Next Sample
                GODONE = 1;
                ADCState++;
                break;
            case 1:             //  Wait for ADC to complete
                if (!GODONE)
                    ADCState++; //  Sample Finished
                break;
            case 2:             //  Save Sample Value in "ADCValue" 
                ADCValue = ADRESH;
                ADCState = 0;
                break;
        }  // hctiws
    }  //  elihw
}  //  End
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top