⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chongdian0418.c

📁 89C52单片机控制的48V快速通电机原码
💻 C
字号:
#include <reg52.h>     //   充电选择
#include <absacc.h>
#include <intrins.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#define DAC0832 XBYTE[0xfeff]   /* 定义DAC0832端口地址 */
#define samples 10   //采样点数6--100?:根据试验结果选择合适数值

//电压电流数据采集位定义

sbit  AD_CLK =  P1^1;      //TLC2543
sbit  DIN    =  P1^2;
sbit  DOUT   =  P1^3;
sbit  AD_CS  =  P1^4;
sbit  EOC    =  P1^0;

sbit  FlagYa     = P3^2;   //D3 恒压
sbit  FlagLiu    = P3^3;   //D2 恒流
sbit  chongstyle = P3^4;   //充电方式

unsigned char bdata flag;
sbit hengliu =flag^0;      //恒流充
sbit hengya =flag^1;       //恒压充
sbit fuchongFlag =flag^2;  //浮充
sbit kuaichong =flag^3;
sbit nonect =flag^4;

float voltage;          //最终显示或控制用电压值
float current;          //最终显示或控制用电流值
unsigned int count=0;                 //过渡计数
unsigned int v[samples],c[samples];   //采样保存点

extern   void delay(unsigned int);
unsigned int  ADRead(unsigned char);
void          dac(unsigned char);

unsigned char AV=0; //调节电压控制值
float maxck=50.0;   //快充方式:恒流阶段充电,最大电流值:根据需要修改
float maxcp=30.0;   //普通方式:恒流阶段充电,最大电流值:根据需要修改
float maxc;         //实际恒流阶段充电最大电流值=maxck或者maxcp
float maxv=59.1;    //最高充电电压:和电池特性有关
float ra=0.217,rc=0.0305;      // 采样系数
float difc=0.31,difv=0.21;     //==电流电压允许波动范围
unsigned char pos=0;           //==当前先进先出FIFO的位置
unsigned int ncount=0,nstop=0; //==几个计数器

unsigned int getv(void)  //==采样电压值
{ ADRead(0x00);
  return ADRead(0x00); }

unsigned int getc(void)  //==采样电流值
{ ADRead(0x20);
  return ADRead(0x20); }

void dispnocont(void)   //显示开路状态:灯交替闪烁
{ ncount=ncount+1;      //交替闪烁计数器
  nonect=1;             //必须重新上电,才能开始工作
  AV=0;
  dac(AV);  //关断IGBT
  if ((ncount % 50) < 25 )   //大约一秒的周期: 点亮恒压灯D3,恒流灯D2灭
    { FlagYa=0;  FlagLiu=1; }
  else
    { FlagYa=1;  FlagLiu=0; }
}

void getac(void)  //==采样,并处理数据
{ unsigned char i;   
  v[pos]=getv();
  delay(1);
  c[pos]=getc();
  delay(1);                 //==采样一个周期,约2毫秒
  pos++;
  if (pos>=samples) pos=0;
  voltage=0;
  current=0;
  for(i=0; i<samples; i++) 
    { voltage=voltage+v[i];
      current=current+c[i];
    } 
  voltage=voltage/samples;  //==取平均值
  current=current/samples;
  voltage=voltage*ra;
  current=current*rc;
} 

/******************************************
1、先以maxc电流恒流充电,充到maxv,再恒压充
2、9脚:补偿端工作电压范围为1.5V到5.2V。
*******************************************/
main()
{ unsigned char n;
  P1=0xff;
  P2=0xff;
  P3=0xff;
  chongstyle=1;  //P0=0xff;
  hengliu=1;
  hengya=0;      //==首先为恒流充电
  fuchongFlag=0;
  nonect=0;      //==开路标志
  AV=80;         //==输出初始电压值
  dac(AV);
  delay(1);
  dac(AV);
  delay(100);  //==稍延时,等待电路稳定?

/*************阶段一:开机10A过渡********************/
  for(n=0;n<200;n++)  //开机10A过渡
  { getac();  //==采样
    nstop=nstop+1;
    if (nstop>150)    //==稍延时后再判断开路处理
      if ((current<0.4) || nonect)  //==开路处理:灯交替闪烁?
        { dispnocont();      //显示开路状态:灯交替闪烁
          continue;        //循环继续!
        }  // end of nonect

    if(voltage>maxv)  //maxv为蓄电池的最高安全充电电压,如超过,须降压处理
      { FlagYa=0;       //点亮恒压灯D3
        FlagLiu=1;
        if(AV>4) { AV=AV-4; dac(AV); }
      }
    else  //恒流充电
      { FlagLiu=0;  //点亮恒流灯D2
        FlagYa=1;
        if(current<10.0)  //==电流小,加大
          { if(AV<255) { AV=AV+1; dac(AV); } }
        if(current>10.0) //==电流大,减小
          { if(AV>4)   { AV=AV-4; dac(AV); } }
      }
    delay(30);
  }  // end of for n

/*************阶段二:正常恒流充电过程 ******************/

  while(1)
  { getac();  //==采样
    kuaichong=chongstyle;
    if(kuaichong) maxc=maxck;  /****** 快速充电处理过程 ******/
    else maxc=maxcp;           /****** 普通充电处理过程 ******/

    if ((current<0.4) || nonect)  //==开路处理:灯交替闪烁?
      { dispnocont();
        continue;    //==循环继续!实际上,必须重新上电才能工作,因为IGBT关断了
      }  // end of nonect

    if(voltage>maxv)    //==首先判断安全电压
      { if(count<0xfffe) count++;    //==通过试验确定逼近恒压的计数值
        else { hengya=1; break; }    //==进入恒压充电状态标志,跳出恒流充电过程!
        FlagYa=0;         //点亮恒压灯D3
        if(voltage>(maxv+difv))  //=超压处理
          { if(AV>1) { AV=AV-1; dac(AV);  } }
      }  //== end of 判断安全电压
    else  //===恒流充电处理过程
      { FlagLiu=0;  //点亮恒流灯D2
        FlagYa=1;
        if(current<(maxc-difc))  //==判断恒流电流:偏小
          { if(AV<255) { AV=AV+1; dac(AV); } }
        if(current>(maxc+difc)) //==电流偏大
          { if(AV>1)   { AV=AV-1; dac(AV); } }
      } //==end of else
    delay(30);  //==适当延时:控制循环周期
  } // end of while

/*************阶段三:正常恒压和浮充电过程 ******************/
  while(hengya)
  { getac();  //==采样
    if ((current<0.4) || nonect)  //==开路处理:灯交替闪烁?
      { dispnocont();
        continue;    //==循环继续!实际上,必须重新上电才能工作,因为IGBT关断了
      }  // end of nonect

    FlagYa=0;  //点亮恒压灯D3
    FlagLiu=1;
    if(voltage<maxv)  // maxv-difv ?
      { if(AV<255) { AV=AV+1; dac(AV); } }

    if(voltage>(maxv+difv))
      { if(AV>1)   { AV=AV-1; dac(AV); } }
    delay(30);  //==适当延时:控制循环周期
  }  //==end of while
} //==主程序结束

unsigned int ADRead(unsigned char channel)    //channel=0x00,选择0通道;channel=0x10,选择1通道。返回结果为整型变量DATA,里面
{
    unsigned int ad_regist=0;
    unsigned char i;
    AD_CLK = 0;
    AD_CS=1;
    _nop_();                        //存的为AD转换结果,格式为D11~D0,共12位
    AD_CS=0;
    _nop_();
    _nop_();
    for(i=0;i<8;i++)
    {
    	  ad_regist=_irol_(ad_regist,1);
          ad_regist|=DOUT;
          DIN=channel&0x80;
          channel=_crol_(channel,1);
          AD_CLK = 1;                        //先读取AD的'D11,D10,D9。。。D4'高8位
          AD_CLK = 0;
    }
    for(i=0;i<4;i++)
    {
    	  ad_regist=_irol_(ad_regist,1);
          ad_regist|=DOUT;
          AD_CLK = 1;                        //先读取AD的'D11,D10,D9。。。D4'高8位
          AD_CLK = 0;
     }                  //后读取AD的'D3,D2,D1,D0'低4位
     AD_CS=1;
     return ad_regist;
}

void dac(unsigned char AdjVoltage)
{
	DAC0832=AdjVoltage;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -