前言
很多充电器,为了能控制电流输出,也就是充电时需要有小电流、大电流的情况,都会用副边及单片机进行控制,但因为是副边控制,需要一个比较器、一个二极管、若干电阻、若干电容,整体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输出的占空比。