通用充电器参考程序

来源:互联网 发布:切腹女视频真假 知乎 编辑:程序博客网 时间:2024/04/28 04:03

/************************程序版权说明************************/
//Copyright (c) 2007,sxqstudy@163.com,All rights reserved.
//Filename:Normal Charger
//sxqstudy.blog.163.com
//Date:2007-10-10
//Starting...
/************************头文件与宏定义************************/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
/************************公共全局变量池************************/
uchar data N_PWM,pwm,i,j,k;
uchar bdata Data_AD;
uint data couter;
bit bdata ready;
float data V_Iset,Vbatt,V_DAC,I_Batt,old_v,deta_v;

sbit CLK=P3^0;
sbit CS=P3^1;
sbit DI=P3^2;
sbit DO=P3^3;
sbit Iset=P3^4;
sbit C_F=P3^5;
sbit ON=P3^7;
sbit Cell2=P1^7;
sbit OFFV=P1^2;
sbit LED_RED=P1^3;
sbit LED_YELL1=P1^4;
sbit LED_YELL2=P1^5;
sbit LED_GREEN=P1^6;
sbit LED_BLUE=P1^7;

sbit Data_AD_0=Data_AD^0;
sbit Data_AD_1=Data_AD^1;
sbit Data_AD_2=Data_AD^2;
sbit Data_AD_3=Data_AD^3;
sbit Data_AD_4=Data_AD^4;
sbit Data_AD_5=Data_AD^5;
sbit Data_AD_6=Data_AD^6;
sbit Data_AD_7=Data_AD^7;

/************************子函数声明空间************************/
void Delay_10();
void V_I_Batt(uchar c);
void Set_Ibatt(float cur);
void Set_Vpwm(uchar N_PWM);
void Test();
/************************中断子函数部分************************/
//功能:供PWM实用
//入口:无
//返回:无
//全局变量:Iset
//是否审核:
void CT0(void) interrupt 1//用于PWM调制输出
{
    if(pwm==N_PWM) Iset=~Iset;
    pwm++;
    if(pwm==256) pwm=0;
}
////////////////////////////////////////////////////////////////
//功能:供延迟定时用
//入口:无
//返回:无
//全局变量:couter
//是否审核:
void CT1(void) interrupt 3//用于10分钟延迟
{
    couter++;//uint(1200)
}
/************************主函数实现部分************************/
////////////////////////////////////////////////////////////////
//功能:检测电池类型并进行充电
//入口:无
//返回:无
//全局变量:V,Vbatt,old_v
//是否审核:
void main()
{
    //单片机系统初始化
    C_F=0;//放电控制
    ON=0;//充电电流控制
    Cell2=1;//LI电池节数
    OFFV=1;//电压调节禁止
    Iset=0;//PWM电流调节
 ready=0;

    LED_RED=0;//红灯
    LED_YELL1=0;//黄灯1
    LED_YELL2=0;//黄灯2
    LED_GREEN=0;//绿灯
    LED_BLUE=0;//等待按键指示灯

    //检测电池是否被正确安装
    V_I_Batt(0);//uchar returned
    Vbatt=Data_AD*3.3*3/256;//实际电压值
    if(Vbatt<0.1)//电池断路、短路、接反报警
    {
        LED_RED=1;//红灯闪烁
        for(;;)//直到系统重新复位
        {
            j=100;
            i=50000;
            --i;
            if(i==0)
            {
                i=50000;
                --j;
                if(j==0)
                {
                    LED_RED=~LED_RED;//0.5S闪烁
                    j=100;
                }
            }
        }
    }
    else//检测电池类型并按类型实施充电
    {
        i=2000;//100S定时
        j=50000;
        LED_BLUE=1;//按键等待指示灯亮
        for(;i>0;)
        {
            --j;
            if(j==0)
            {
                --i;
                j=50000;
            }
        }
        LED_BLUE=0;//按键等待结束指示

        //判断正常情况下的电池类型:1~2节镍电池或1~2节锂电池
        ON=1;//开启充电电流
        Set_Ibatt(0.1);//0.1A 恢复性试充电
        Delay_10();//延迟10分钟
        ON=0;//关闭充电电流

        V_I_Batt(0);//检测电池电压
        Vbatt=Data_AD*3.3*3/256;
        if(Vbatt<2.2)//Ni类电池最高2V
        {
            //加上对满容量电池的判断程序
            LED_YELL1=1;//镍类充电指示灯亮
            C_F=1;//开始放电
            Vbatt=2;//初始化Vbatt以进入循环语句
            for(;Vbatt>1.0;)//黄灯闪烁表示正在放电
            {
                V_I_Batt(0);
                Vbatt=Data_AD*3.3*3/256;

                j=100;
                i=50000;
                --i;
                if(i==0)
                {
                    i=50000;
                    --j;
                    if(j==0)
                    {
                        LED_YELL1=~LED_YELL1;//0.5S闪烁
                        j=100;
                    }
                }
            }
            C_F=0;//停止放电
            LED_YELL1=1;//黄灯恢复正常显示

            ON=1;//开启充电电流准备充电
            Set_Ibatt(0.2);//0.2A 升温预充电
            Delay_10();//延迟10分钟
            //判断镍电池节数//无须判断了,因为最大只能提供1A电流
            //if(Num_Ni==0)//而且可以省略一个I/O口Num_Ni
            //{
            Set_Ibatt(1.0);//1A
            Delay_10();//延迟10分钟
            Delay_10();//延迟10分钟

            for(;deta_v>0.015;)
            {
                V_I_Batt(0);//检测电池电压
                Vbatt=Data_AD*3.3*3/256;
                deta_v=old_v-Vbatt;
                old_v=Vbatt;
            }
            ON=0;//立即关闭Ibatt
            LED_GREEN=1;//绿灯亮充电完毕
        }
        else//Li电池,1~2节用是否大于5V判断
        {
            ON=1;//开电流
            Set_Ibatt(0.2);//0.2A 升温预充电
            Delay_10();//延迟10分钟

            V_I_Batt(0);//检测电池电压
            Vbatt=Data_AD*3.3*3/256;
            if(Vbatt<4.8)//一节电池
            {
                Cell2=0;//充一节
            }
            ON=1;//开电流
            Set_Ibatt(0.5);
            for(;Vbatt<4.1;)
            {
                V_I_Batt(0);
                Vbatt=Data_AD*3.3*3/256;
            }
            ON=0;//关电流
            OFFV=0;//激活电压调节
            ON=1;//开电流
            Set_Ibatt(0);//ADC输出为0V
   for(i=0;i<10;i++) Delay_10();//延迟100分钟
            for(;ready==0;)//大约再过20分钟自动停止
            {
                j=200;
                i=50000;
    k=1200; 
    --i;
                if(i==0)
                {
                    i=50000;
                    --j;
                    if(j==0)
                    {
                        --k;
                        j=100;
                    }
                    if(k==0)//约20分钟
                    {
                        ready=1;
                    }
                }
                ready=0;
                V_I_Batt(0);
                Vbatt=Data_AD*3.3*3/256;
                if(Vbatt>8.35) break;
            }
            ON=0;//关电流
            OFFV=1;//关调节
            LED_GREEN=1;
        }
    }
    //加入2051节电控制程序
    PCON=PCON|0x02;//PD=1掉电运行
}
/************************子函数实现部分************************/
//功能:
//入口:高电平数N_PWM
//返回:无
//全局变量:N_PWM
//是否审核:
void Set_Vpwm(uchar N_PWM)
{
    TR0=0;//先关定时
    TMOD=0x02;//8位自动重装方式
    TH0=256-N_PWM;//装入初值
    TL0=TH0;
    pwm=0;
    Iset=1;//初始化PWM首先输出高电平
    TR0=1;//再开定时
    EA=1;
    ET0=1;
}
////////////////////////////////////////////////////////////////
//功能:定时延迟10分钟
//入口:无
//返回:无
//全局变量:couter(uint)
//是否审核:
void Delay_10()
{
    TR1=0;//先关定时
    TMOD=0x10;//CT1,16位方式
    TH1=0xc3;//50000/256;//装入初值
    TL1=0x50;//50000%256;
    TR1=1;//再开定时
    EA=1;
    ET1=1;
    for(;couter!=1200;);
    TR1=0;//先关定时
    couter=0;
}
////////////////////////////////////////////////////////////////
//功能:设置充电电流大小
//入口:电流大小(A)
//返回:无
//全局变量:N_PWM,I_Batt
//是否审核:
void Set_Ibatt(float cur)
{
    if(cur==0)
    {
        TR0=0;//先关定时
        Iset=0;
    }
    else
    {
        N_PWM=0;
        I_Batt=0;//使循环可以进行
        while(I_Batt<cur)
        {
            Test();
            N_PWM++;
        }
        N_PWM=0;
    }
}
////////////////////////////////////////////////////////////////
//功能:测试电池充电电流
//入口:无
//返回:无
//全局变量:N_PWM,V_Iset,V,Vbatt,V_DAC,I_Batt
//是否审核:
void Test()
{
    Set_Vpwm(N_PWM);
    V_I_Batt(0);
    Vbatt=Data_AD*3.3*3/256;
    V_I_Batt(1);
    V_Iset=Data_AD*3.3/256;
    V_DAC=N_PWM*3.3/256;
    I_Batt=(22*V_Iset-V_DAC)/20-Vbatt;
}
////////////////////////////////////////////////////////////////
//功能:获取电池电压和电流(电压)
//入口:A/D转换通道选择
//返回:相应采样点电压值
//全局变量:CLK,CS,DI,DO,Data_AD(0-7)
//是否审核:
void V_I_Batt(uchar c)
{
    uchar i;

    CLK=0;
    CS=0;
    DI=1;

    CLK=1;//时钟1
    CLK=1;
    CLK=0;

    CLK=1;//时钟2
    CLK=1;
    CLK=0;

    if(c==0) DI=0;
    else DI=1;

    CLK=1;//时钟3
    CLK=1;
    CLK=0;

    for(i=7;i>0;--i)
    {
        CLK=1;//8个时钟
        CLK=1;
        CLK=0;
    }

    CLK=1;//data0
    Data_AD_0=DO;
    CLK=0;

    CLK=1;//data1
    Data_AD_1=DO;
    CLK=0;

    CLK=1;//data2
    Data_AD_2=DO;
    CLK=0;

    CLK=1;//data3
    Data_AD_3=DO;
    CLK=0;

    CLK=1;//data4
    Data_AD_4=DO;
    CLK=0;

    CLK=1;//data5
    Data_AD_5=DO;
    CLK=0;

    CLK=1;//data6
    Data_AD_6=DO;
    CLK=0;

    CLK=1;//data7
    Data_AD_7=DO;
    CLK=0;
}

 

摘自:http://sxqstudy.blog.163.com/blog/static/34562512007105115433905/

原创粉丝点击