基于凌鸥LKS32MC037的鱼缸用FOC潜水泵控制器详解
基于凌鸥LKS32MC037的鱼缸用FOC潜水泵控制器详解
随着生活水平的提高,室内养鱼越来越普及,这推动了鱼缸内小型潜水泵市场的发展。早期的鱼缸潜水泵大多采用方波驱动控制器,但随着技术进步和芯片成本下降,基于无感FOC算法的潜水泵控制器已逐渐成熟并实现大规模量产。本文将详细介绍这种新型控制器的技术原理和实现方法。
FOC控制器的优势
新型的正弦波FOC控制器相比早期的方波控制器具有以下优势:
平滑水流:正弦波控制器可以产生平滑的电流输出,从而驱动潜水泵产生平滑的水流,有助于水族生物的健康生长。
节能:正弦波控制器能够以更高效的方式驱动潜水泵,节省能源并降低能源消耗成本。
精确控制:正弦波控制器可以精确控制潜水泵的转速和水流量,根据需要调节水流强度,提供更好的水族环境。
减少噪音:正弦波控制器驱动的潜水泵通常运行更平稳,产生的噪音相对较少,提供一个更安静的水族环境。
长寿命:正弦波控制器的稳定输出可以减少潜水泵的振动和磨损,延长潜水泵的使用寿命。
技术实现
本控制器采用国产凌鸥芯片LKS32MC037电机开发平台,采用先进的FOC算法。FOC(Field-Oriented Control,场向量控制)是一种电机控制技术,旨在实现对三相交流电机的精确控制。在无感FOC水泵控制器中,该技术被应用于控制水泵的电机,以实现更高效、更精确的水流控制。
主代码函数框架
程序框架主要由State_machine状态机接口模块、Foc_Control控制模块、Fault故障检测模块组成。
Static_machine程序模块:主要由Task_Scheduler()时间片执行函数组成,包含1ms任务调度,主要包括FaultCheck()函数模块和sys_state_machine()状态机函数模块。10ms、100ms的时间调度,用来处理反应不是特别快的进程。
Foc_Control控制模块:主要由McPWM0_IRQhandler()中断处理函数组成,包含FOC_Model函数进程模块。Foc_Model()模块包含AdcSampleCal()、OpenCloseAngleSwitch()、CurrentLoopReg()、Svpwm()等Foc控制模块的主要组成部分,能实现FOC的电流检测,检测Clark、Park变化,以及DQ方向轴上的电流环,最后输出产生SVPWM电压信号。
FOC控制算法
- FOC框图:无感FOC控制软件主运动控制包含速度环+D轴电流环+Q轴电流环+SVPWM模块组成。采用目标速度和当前测量的速度值Error产生速度环的输入,与设定的速度Ramp进行比较,运行速度环,通过最大速度的限制。速度环的输出作为Q轴电流环的输入,D轴电流环的设定值恒为0。经过两路电流环的计算,输入到反PARK变换,最后经过SVPWM模块,生成3路三路相差120度的交流波形。
- 无感观测器:软件模块FluxObserveParaCalc()用于估计系统状态变量,它基于系统的数学模型和测量输出,通过一个动态补偿器来估计系统的状态,并输出估计值。龙贝格观测器通过观测系统的输出,如电压或电流,以及已知的系统模型,推断系统的内部状态变量,例如电网频率和相位。通过比较实际输出和观测器估计的输出,可以不断调整观测器的参数,使其逼近实际状态。PLL算法(Phase-Locked Loop)是一种用于跟踪信号频率和相位的闭环控制技术。龙伯格观测器+PLL收敛算法,适用于大部分的水泵驱动方案,硬件要求低,启动稳定,能满足大部分需求!本观测器已批量匹配应用三段式Align+OpenLoop+CloseLoop无感启动方式。
部分代码
int main(void) {
SoftDelay(50000); /* 延时等待硬件初始化稳定 10000--2.56ms*/
__disable_irq(); /* 关闭中断 中断总开关 */
Hardware_init(); /* 硬件初始化 */
sys_init(); /* 系统初始化 */
__enable_irq(); /* 开启总中断 */
for(;;)
{
Task_Scheduler(); /* 任务调度函数,根据时间分片处理 */
}
}
/*******************************************************************************
函数名称: void Sys_State_Machine(stru_FOC_CtrProcDef *this)
功能描述: 系统状态机 电机状态各状态切换调度
输入参数: 无
输出参数: 无
返 回 值: 无
其它说明:
修改日期 版本号 修改人 修改内容
---
2020/8/5 V1.0 Howlet Li 创建
*******************************************************************************/
void Sys_State_Machine(void)
{
switch (struFOC_CtrProc.eSysState)
{
case IDLE:
{ /* 空闲状态 */
if (struFOC_CtrProc.bMC_RunFlg)
{
StateInit();
#if (ROTOR_SENSOR_TYPE == ROTOR_SENSORLESS)
struFOC_CtrProc.eSysState = CHARGE; /* 进入充电状态 */
#else
#if ((ROTOR_SENSOR_TYPE == ROTOR_HALL_SENSOR)||(ROTOR_SENSOR_TYPE ==ROTOR_HALL2SENSORLESS))
if(GET_HALL_LEARN_STATE())
{ /* 进入HALL自学习状态 */
PWMOutputs(MCPWM0, ENABLE);
struFOC_CtrProc.eSysState = HALL_LEARN;
}
else
{
StateInit();
PWMOutputs(MCPWM0, ENABLE);
struFOC_CtrProc.eSysState = HALL_RUN; //有Hall运行
}
#endif
#endif
}
break;
}
case CHARGE:
{
StateCharge(); //预充电处理函数
break;
}
case BEMF_CHECK: /*反电动势检测*/
{
StateBemfDirCheck(); //反电势检测函数
break;
}
case DIR_CHECK: //顺逆风检测状态
{
StateDirCheck(); //顺逆风处理函数
break;
}
case INIT:
{ /* 初始化状态 */
StateInit();
#if (ROTOR_SENSOR_TYPE == ROTOR_SENSORLESS)
{
struFOC_CtrProc.eSysState = ALIGN;
}
#elif (ROTOR_SENSOR_TYPE == ROTOR_HALL_SENSOR)
{ //纯有感 根据hall 反馈
struFOC_CtrProc.eSysState = HALL_RUN;
}
#endif
break;
}
case POS_SEEK: //初始位置检测状态
{
StatePosSeek(); //初始位置检测处理函数
struFOC_CtrProc.eSysState = INIT;
break ;
}
case ALIGN: //预定位状态
{
PWMOutputs(MCPWM0, ENABLE);
StateAlign(); //预定位处理函数
break ;
}
case OPEN_RUN: //开环强拖状态
{
StateOpen(); //开环处理函数
break ;
}
case RUN:
{ /* 运行状态 */
StateRun(); //闭环处理函数
break;
}
case HALL_RUN:
{
StateHallRun();
break;
}
case HALL_LEARN:
{
#if ((ROTOR_SENSOR_TYPE == ROTOR_HALL_SENSOR)||(ROTOR_SENSOR_TYPE == ROTOR_HALL2SENSORLESS))
if(GET_HALL_LEARN_STATE() == HALL_LEARN_FINISH)
{
PWMOutputs(MCPWM0, DISABLE);
SetTimeOut_Counter(struFOC_CtrProc.nSetTimeLeftCnt, STATE_MACHINE_200MS);
struFOC_CtrProc.eSysState = WAIT;
}
#endif
break;
}
case BRAKE:
{ /* 电机刹车状态 */
StateStop(); //停止判定处理函数
SetTimeOut_Counter(struFOC_CtrProc.nSetTimeLeftCnt, STATE_MACHINE_200MS);
break;
}
case BEMF_BRAKE: /* 反电势刹车处理*/
{
StateBemfStop();
break;
}
case WAIT:
{ /* 等待状态 */
if (SetTime_IsElapsed(struFOC_CtrProc.nSetTimeLeftCnt))
{
struFOC_CtrProc.eSysState = IDLE;
}
break;
}
case FAULT:
{ /* 故障状态 */
StateFault(); //故障处理函数
if(stru_Faults.R == 0)
{
struFOC_CtrProc.eSysState = IDLE;
}
break;
}
default:
{
break;
}
}
if((struFOC_CtrProc.bMC_RunFlg == 0) && (stru_Faults.R == 0)) //无故障并且启动标志位清0,关闭输出,进入空闲状态
{
PWMOutputs(MCPWM0, DISABLE);
SetTimeOut_Counter(struFOC_CtrProc.nSetTimeLeftCnt, STATE_MACHINE_200MS);
struFOC_CtrProc.eSysState = WAIT;
}
}
硬件原理图
批量生产的原理图。