1、設計原因
由於我經常開發一些奇奇怪怪的小東西,所以手上有較多鋰電池,長時間保存對我這種懶人帶來的困擾,正常邏輯是每次充電完成後,由人工更換下一個電池充電,如此往復,如使用多個充電器同時進行此項工作(並行),成本與效率均較高,於是設計了這個邏輯充電器,其最大支持4塊電池充電,但每次充電一塊,單塊充電完成後,由單片機讀取充電芯片信號,後關閉該通道充電,並開啓下一個充電通道,如此往復,是一種用時間換效率和成本的雞肋設計。
實物如下圖1所示、散熱片下是TC4056充電芯片(TP4056可替換),主控單片機爲N76E003。
2、運行邏輯
其中帶隙電壓(band·gap)讀取相關文章可以看這裏
此外,檢測充電完成時,首先使用單片機檢測充電芯片STDBY引腳電平變化,其原理及電路如下圖3、4、5所示,當STDBY引腳拉低後,5V電源通過10k電阻及LED,其管腳電壓變化爲3.2V左右,此時配置爲輸入模式(高阻態)的單片機管腳即可採集到該信號。
使能及關斷充電工作,均使用其TC4056的CE管腳,原理如下圖6、7所示,單片機配置爲PP(推輓輸出),串聯一SS24肖特基二極管到CE管腳上進行控制
3、程序代碼
#include "N76E003.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "Common.h"
#include "Delay.h"
#include <intrins.h>
#include "ADCBG.h"
#define uchar unsigned char
#define uint unsigned int
//控制TP4056啓停,高電平驅動
sbit TC0=P0^0;
sbit TC1=P0^4;
sbit TC2=P0^5;
sbit TC3=P0^1;
//檢測充電是否完成,高阻輸入模式,低電平完成/高電平正在
sbit Flash0=P1^0;
sbit Flash1=P0^3;
sbit Flash2=P0^2;
sbit Flash3=P1^5;
uint ADC_BAT[4];
uchar TP_TC[4];
char ZTJJ=-1;
/***************************************
功能:檢測4個端口的電池電壓,送入數組中,分配
充電任務。
參數:無
說明:無
***************************************/
void ADC_Sampling()
{
//---------ADC_Bat----------------------
Enable_ADC_AIN0;
ADC_Single();//0通道
ADC_BAT[0]=ADC_VC*2;
Timer1_Delay10ms(10);
Enable_ADC_AIN1;
ADC_Single();//1通道
ADC_BAT[1]=ADC_VC*2;
Timer1_Delay10ms(10);
Enable_ADC_AIN2;
ADC_Single();//2通道
ADC_BAT[2]=ADC_VC*2;
Timer1_Delay10ms(10);
Enable_ADC_AIN3;
ADC_Single();//3通道
ADC_BAT[3]=ADC_VC*2;
Timer1_Delay10ms(10);
}
/***************************************
功能:分配充電順序
參數:無
說明:無
***************************************/
void BAT_Logic()
{
uchar i;
for(i=0;i<4;i++)
{
//需要充電,開啓
if(ADC_BAT[i]>1000&&ADC_BAT[i]<4100)
{
TP_TC[i]=1;//無實際作用,僅調試用
ZTJJ=i;
}
if(ADC_BAT[i]>=4100)TP_TC[i]=2;//充電完成的,開啓(置2,可不遵守順序充電)
if(ADC_BAT[i]<=1000)TP_TC[i]=0;//不存在電池,關閉
}
//充電完成的,不計入邏輯順序
if(TP_TC[0]==2)
{
TC0=1;
}
if(TP_TC[1]==2)
{
TC1=1;
}
if(TP_TC[2]==2)
{
TC2=1;
}
if(TP_TC[3]==2)
{
TC3=1;
}
switch(ZTJJ)
{
case 0:
TC0=1;
break;
case 1:
TC1=1;
break;
case 2:
TC2=1;
break;
case 3:
TC3=1;
break;
default:
break;
}
}
/*
操作流程
1、TC0-3全關,使用AIN0-AIN3進行檢測找到低於閾值(1000-4000)
2、當發現高於閾值時,開啓對應充電,使其指示燈亮。
2、按照0-3順序分配充電任務,開啓對應4056。
3、等待對應充電芯片Flash信號發出,確認完成(保持開啓,指示燈亮)。
5、檢測到對應ZTJJ充電完成後,再使用一次ADC_Sampling、BAT_Logic
*/
int main()
{
Set_All_GPIO_Quasi_Mode;
P10_Input_Mode;
P03_Input_Mode;
P02_Input_Mode;
P15_Input_Mode;
P00_PushPull_Mode;
P04_PushPull_Mode;
P05_PushPull_Mode;
P01_PushPull_Mode;
TC0=0;
TC1=0;
TC2=0;
TC3=0;
Timer3_Delay100ms(20);
READ_BANDGAP();//讀取內部基準電壓,獲得修正Coe
ADC_Sampling();
ADC_Sampling();
ADC_Sampling();
ADC_Sampling();
ADC_Sampling();
BAT_Logic();
while(1)
{
switch(ZTJJ)
{
case 0:
if(!Flash0)
{
ADC_Sampling();
BAT_Logic();
}
break;
case 1:
if(!Flash1)
{
ADC_Sampling();
BAT_Logic();
}
break;
case 2:
if(!Flash2)
{
ADC_Sampling();
BAT_Logic();
}
break;
case 3:
if(!Flash3)
{
ADC_Sampling();
BAT_Logic();
}
break;
default:
break;
}
Timer3_Delay100ms(10);
}
}
4、原理圖