随着老百姓生活水平的提高,室内养殖观赏型鱼类的人越来越多,这就催生了鱼缸内小型潜水泵的市场发展。 早期鱼缸潜水泵都采用的方波驱动的控制器。随着技术的进步和芯片成本的下降,本文介绍的基于无感FOC算法潜水泵控制器已经成熟应用并且大批量产, 新型的正弦波FOC控制器相比较早期的方波控制器有如下几点优点:

平滑水流: 正弦波控制器可以产生平滑的电流输出,从而驱动潜水泵产生平滑的水流,有助于水族生物的健康生长。 节能: 正弦波控制器能够以更高效的方式驱动潜水泵,节省能源并降低能源消耗成本。 精确控制: 正弦波控制器可以精确控制潜水泵的转速和水流量,根据需要调节水流强度,提供更好的水族环境。 减少噪音: 正弦波控制器驱动的潜水泵通常运行更平稳,产生的噪音相对较少,提供一个更安静的水族环境。 长寿命: 正弦波控制器的稳定输出可以减少潜水泵的振动和磨损,延长潜水泵的使用寿命。

本控制器采用国产凌鸥芯片LKS32MC037电机开发平台,采用先进的FOC算法,FOC(Field-Oriented Control,场向量控制)是一种电机控制技术, 旨在实现对三相交流电机的精确控制。在无感FOC水泵控制器中,该技术被应用于控制水泵的电机,以实现更高效、更精确的水流控制。 实现潜水泵的小功率低噪声平稳运行。

主要代码实现如下:

1.主代码函数框架

程序框架主要由,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_control控制模块的矢量电机控制的框架包括坐标转换、电流控制、磁场定向、速度调节和闭环控制等步骤, 通过精确控制电机的电流和转矩,实现对电机的高效、高性能的控制。

2.Foc控制算法

2.1 FOC框图

无感FOC控制软件主运动控制包含速度环+D轴电流环+Q轴电流环+SVPWM模块组成, 采用目标速度和当前测量的速度值Error产生速度环的输入,与设定的速度Ramp进行比较,运行速度环, 通过最大速度的限制.速度环的输出作为Q轴电流环的输入, D轴电流环的设定值恒为0。经过两路电流环的计算,输入到反PARK变换,最后经过SVPWM模块,生成3路三路相差120度的交流波形。

2.2 无感观测器

软件模块 FluxObserveParaCalc() 用于估计系统状态变量,它基于系统的数学模型和测量输出, 通过一个动态补偿器来估计系统的状态,并输出估计值。龙贝格观测器通过观测系统的输出,如电压或电流, 以及已知的系统模型,推断系统的内部状态变量,例如电网频率和相位。通过比较实际输出和观测器估计的输出,可以不断调整观测器的参数, 使其逼近实际状态。PLL算法(Phase-Locked Loop):原理: PLL算法是一种用于跟踪信号频率和相位的闭环控制技术。 它通过比较输入信号和本地参考信号的相位差,并根据相位差的变化调整本地参考信号的频率和相位,使其与输入信号同步。 龙伯格观测器+PLL收敛算法,适用于大部分的水泵驱动方案,硬件要求低,启动稳定,能满足大部分需求! 本观测器已批量匹配应用三段式 Align+OpenLoop+CloseLoop无感启动方式.

3.部分代码

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;
   }
}

4.硬件原理图

批量生产的原理图。