双路foc工程源码 节省芯片资源 双路foc 每路8k,互相不影响,可单路控制,主控f4。 送源码keil工程,原理图pdf。

最近在调试双路FOC方案时发现个有意思的现象——大部分开源项目都是单路电机控制,想玩双电机得靠堆芯片。这显然不符合咱嵌入式工程师的"抠门"传统,于是我整了个双路FOC共用一个STM32F4的方案。

先看主控资源分配:两套独立定时器分别驱动两路PWM,TIM1+TIM8这对黄金搭档各带三路互补输出。ADC采样也别闲着,注入通道和规则通道分开伺候两路电流采样。实测每路FOC周期控制在8kHz时,CPU利用率还能剩30%左右摸鱼。

重点看电流环中断的处理:

void TIM1_CC_IRQHandler(void) {
    if(LL_TIM_IsActiveFlag_CC1(TIM1)) {
        LL_TIM_ClearFlag_CC1(TIM1);
        MotorA.CurrentSample();  //A电机电流采样
        MotorA.FOC_Calc();       //A电机Park变换
    }
}

void TIM8_CC_IRQHandler(void) {
    if(LL_TIM_IsActiveFlag_CC1(TIM8)) {
        LL_TIM_ClearFlag_CC1(TIM8);
        MotorB.CurrentSample();  //B电机电流采样
        MotorB.FOC_Calc();       //B电机Clarke变换
    }
}

这两个中断互不干扰的秘密在于TIM1/TIM8的中断控制器映射到不同通道。实测关掉其中一路的中断,另一路FOC照跑不误,这对需要单电机调试的场景太友好了。

双路foc工程源码 节省芯片资源 双路foc 每路8k,互相不影响,可单路控制,主控f4。 送源码keil工程,原理图pdf。

资源优化方面有个小技巧:把SVPWM的sin/cos计算换成查表法。实测用uint16t格式的512点查找表,配合线性插值,比armsin_f32省了0.3us运算时间。对于F4这种带DSP指令的芯片来说可能不明显,但要是换F1系列就真香了。

说到控制接口,工程里埋了个彩蛋:

void Motor_Ctrl(uint8_t motor_id, float target) {
    static float last_target[2] = {0};
    if(motor_id & 0x01) {
        MotorA.Target = target * (1 - dead_zone) + last_target[0] * dead_zone;
        last_target[0] = MotorA.Target;
    }
    if(motor_id & 0x02) {
        MotorB.Target = target * (1 - dead_zone) + last_target[1] * dead_zone;
        last_target[1] = MotorB.Target;
    }
}

这个带死区补偿的平滑处理函数,专治手柄控制时的电机抽搐。参数dead_zone设成0.2左右,能让双电机动起来像抹了黄油似的顺滑。

整套方案最得意的还是硬件设计——用双运放做电流采样,配合模拟开关切换采样电阻,比传统方案省了两组运放和一堆电阻。原理图里标黄的部分就是省料秘诀,欢迎下载后放大查看。

需要源码的老铁注意:工程里用了HAL库的LL层驱动,编译前记得装好STM32CubeF4的1.27版软件包。遇到PWM输出不对的情况,先检查Advanced Timer的Break功能是不是忘关了,这个坑已经让三个同事加班到凌晨了。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐