充电器进阶,原边恒流,单片机控制小电流(预充电)的方案

时间:2024-04-23 09:24:30

前言

很多充电器,为了能控制电流输出,也就是充电时需要有小电流、大电流的情况,都会用副边及单片机进行控制,但因为是副边控制,需要一个比较器、一个二极管、若干电阻、若干电容,整体BOM成本可能多了三毛钱左右。这里介绍了原边恒流的实现方法,并提出了一种原边恒流,单片机控制小电流的方案。

有纰漏请指出,转载请说明。

学习交流请发邮件 1280253714@qq.com

副边及单片机控制输出电流

之前的文章有提到:

I_CTRL输出电压和电流采样电阻的电压进行比较,当I_CTRL大于I_SENSE时,也就是输出电流还没到设定的电流时,此时比较器输出高电平,相当于二极管不导通,也就是电流环此时不起作用,而是由电压环控制。

当I_CTRL小于I_SENSE时,也就是输出电流大于设定的电流时,此时比较器输出低电平,二极管导通,也就是电流环此时起主导作用, 导致流经TL431的电流变大,光耦PC817的灯变亮,导致晶体管阻值变小,CR6885的FB端电压变小(FB内部有一个电阻),GATE输出的占空比变小,抑制输出电流的增大,使电流保持在设定的值。

如果单片机通过PWM控制I_CTRL电压,此时就可以进行输出电流的调节。

这种情况下,如果去掉电流环,电源IC工作在CV模式,整个电路相当于适配器的架构,这种情况不适合对电池包进行充电,CV模式对电池包进行充电,可能会反复出现过载/过流保护而重启的可能。

原边控制输出电流

之前的文章对于KP201介绍到,KP201支持CC/CV模式,这款IC内置了通用原边恒流(CC)控制功能,简化了需要输出恒流调节的隔离式电源设计,;其中CS为电流感应输入引脚,用于检测电源输出电流的大小,用来调整PWM信号的占空比,以实现恒流控制:

反激电源控制芯片解读——以KP201为例_反激芯片规格书-****博客

 

对整个周期的电流进行积分后除以总时长,求得平均电流。

在上面的描述中,Is(t) 代表次级电感或整流二极管的电流,Ip(t) 代表初级电感的电流,N 是变压器初级到次级的匝数比。通过检测变压器初级绕组的电流,可以换算出次级输出的电流。

电子工程师在应用时,只需调节Rcs的阻值即可求得输出电流。

单片机控制输出电流

上述原边恒流的方案,如果设置空载电压为21V,那么可能到电池包电压为20.7才进入恒压控制,也就是输出电压接近空载电压时,电流才会下降。

如果想在电池包电压很低时进行小电流充电,那么上述方法就行不通了。

那么,如果单片机能够控制充电器的空载电压,让空载电压接近电池包电压,不就可以一直处于恒压模式吗?也就是说,在电池包电压为8-12V时,充电器电压始终比电池包电压高一点,就可以一直进入小电流充电模式。

这时候最简单的控制方式是:检测输出电流的大小,当充电电流小于设定的电流时,让空载电压高一点;当充电电流大于设定的电流时,让空载电压低一点。逻辑大概是这样:

// 假设有以下变量和常量  
const float SET_CURRENT = 1.0; // 设定的电流值  
const float VOLTAGE_INCREASE = 0.1; // 充电电流小于设定值时,电压增加的量  
const float VOLTAGE_DECREASE = 0.1; // 充电电流大于设定值时,电压减少的量  
float voltCtrlPwm = 0.0; // 当前控制输出电压的占空比  
float outputCurrent; // 输出电流,通过ADC或其他方式读取  
  
// 读取当前输出电流  
outputCurrent = readCurrentFromADC(); // 这是一个假设的函数,用于从ADC读取电流值  
  
// 根据电流大小调整输出电压  
if (outputCurrent < SET_CURRENT) {  
    // 充电电流小于设定值,增加空载电压  
        voltCtrlPwm += VOLTAGE_INCREASE;  
    if (voltCtrlPwm > MAX_VOLTAGE) { // MAX_VOLTAGE是电压的上限值对应的占空比 
        voltCtrlPwm = MAX_VOLTAGE;  
    }  
} else if (outputCurrent > SET_CURRENT) {  
    // 充电电流大于设定值,降低空载电压  
    currentOutputVoltage -= VOLTAGE_DECREASE;  
    if (currentOutputVoltage < MIN_VOLTAGE) { // MIN_VOLTAGE是电压的下限值对应的占空比  
        currentOutputVoltage = MIN_VOLTAGE;  
    }  
}  
  
// 设置新的输出电压  
setVoltage(voltCtrlPwm ); // 这是一个假设的函数,用于设置输出电压

当然,这种控制方式实际上可能行不通,如果用PID的方式,代码大概是这样:

// PID控制器参数  
float Kp = 1.0; // 比例系数  
float Ki = 0.1; // 积分系数  
float Kd = 0.01; // 微分系数  
float setCurrent = 1.0; // 设定的电流值  
float error = 0.0; // 误差值  
float previousError = 0.0; // 上一次的误差值  
float integral = 0.0; // 误差的积分  
float derivative = 0.0; // 误差的微分  
float voltCtrlPwm = 0.0; // 当前输出电压对应的占空比  
float voltageAdjustment = 0.0; // 电压调整量  
  
// PID控制函数  
void pidControl() {  
    // 读取当前输出电流  
    float currentOutputCurrent = readCurrentFromADC();  
      
    // 计算误差  
    error = setCurrent - currentOutputCurrent;  
      
    // 计算误差的积分  
    integral += error;  
      
    // 计算误差的微分  
    derivative = error - previousError;  
      
    // 更新之前的误差值  
    previousError = error;  
      
    // 计算PID输出  
    voltageAdjustment = Kp * error + Ki * integral + Kd * derivative;  
      
    // 限制电压调整量在合理范围内  
    if (voltageAdjustment > MAX_ADJUSTMENT) {  
        voltageAdjustment = MAX_ADJUSTMENT;  
    } else if (voltageAdjustment < -MAX_ADJUSTMENT) {  
        voltageAdjustment = -MAX_ADJUSTMENT;  
    }  
      
    // 调整输出电压  
    voltCtrlPwm += voltageAdjustment;  
      
    // 限制输出电压在安全范围内  
    if (voltCtrlPwm > MAX_VOLTAGE) {  
        voltCtrlPwm = MAX_VOLTAGE;  
    } else if (voltCtrlPwm < MIN_VOLTAGE) {  
        voltCtrlPwm = MIN_VOLTAGE;  
    }  
      
    // 设置新的输出电压  
    setVoltage(voltCtrlPwm );  
}  
  
// 在主循环中调用PID控制函数  
void mainLoop() {  
    // ... 其他代码 ...  
      
    pidControl(); // 执行PID控制  
      
    // ... 其他代码 ...  
}

总结

实际上,原边恒流、单片机控制小电流的方案和副边控制电流的方法是类似的,只不过是通过代码的方式实现了电流环。

二者的本质都是当前电流与目标电流进行比较,通过控制光耦的反馈量调整电源IC输出的占空比。