基于高频脉冲注入法转子初始位置辨识算法代码,无感启动中最重要的便是初始位置估计,高频注入法无感运行的方法适用于带电机运行,用在初始位置检测时,时间不固定,依赖电机参数。 采用脉冲注入法后,检测时间固定,检测精度高,受电机参数影响小,已在不同型号驱动器量产后,针对各种电机均可以估计出不错的初始角度值,能根据电机电感和额定电流自适应决定注入电压幅值和周期,大多数IPM电机精度在+-5个电角度以内,SPMSM在+-15°以内,检测过程中,转子移动不大于10°电角度。 可以指导该代码移植、帮忙理解、指导调试等

高频脉冲注入这玩意儿在无感启动里绝对算得上技术活里的黑科技。咱今天不整那些虚头巴脑的理论推导,直接带大伙儿撸代码实操。先说个实战中的坑——之前用传统高频注入法调试某款IPM电机,转子角度误差愣是飙到30度电角度,电机启动直接给你表演托马斯回旋。后来切到脉冲注入法,嘿,误差直接压到3度以内。

先看这段注入策略的核心代码:

void HFI_InjectPulse(MotorCtrl* ctrl) {
    // 根据电感自适应选择脉宽
    uint16_t pulse_width = (uint16_t)(ctrl->Ld * 0.78f + ctrl->I_rated * 1.2f);
    PWM_SetDuty(INJ_U_PHASE, pulse_width);
    PWM_SetDuty(INJ_V_PHASE, 0);
    PWM_SetDuty(INJ_W_PHASE, 0);
    
    // 等待电流响应稳定
    delay_us(ctrl->dead_time + 50); 
    CaptureCurrentResponse(&ctrl->adc_data);
}

这里有个骚操作——脉宽计算把电感和额定电流揉在一起了。调试时发现某款36V小电机需要把0.78这个系数改成0.65才能稳定,后来发现是驱动器MOS内阻偏大导致的。所以移植时这个系数得根据硬件特性微调。

响应信号处理这块更考验手艺:

float ProcessHFIResponse(ADCData* adc) {
    // 滑动窗口滤波处理
    static float i_alpha_buf[5], i_beta_buf[5];
    memmove(i_alpha_buf, &i_alpha_buf[1], 4*sizeof(float));
    i_alpha_buf[4] = Clarke_Alpha(adc->Ia, adc->Ib);
    
    // 二次谐波提取
    float hfi_signal = 0;
    for(uint8_t i=0; i<5; i++){
        hfi_signal += i_alpha_buf[i] * hfi_window[i];
    }
    return hfi_signal * hfi_phase_shift; // 相位补偿
}

这段代码里的滑动窗口滤波可不是摆设。某次量产驱动器在产线出现10%的不良率,最后发现是ADC采样时序抖动导致窗口数据错位,把memmove改成环形缓冲区才解决。那个hfiphaseshift参数也别迷信文档,拿示波器抓电流波形和PWM触发信号对比着调才靠谱。

基于高频脉冲注入法转子初始位置辨识算法代码,无感启动中最重要的便是初始位置估计,高频注入法无感运行的方法适用于带电机运行,用在初始位置检测时,时间不固定,依赖电机参数。 采用脉冲注入法后,检测时间固定,检测精度高,受电机参数影响小,已在不同型号驱动器量产后,针对各种电机均可以估计出不错的初始角度值,能根据电机电感和额定电流自适应决定注入电压幅值和周期,大多数IPM电机精度在+-5个电角度以内,SPMSM在+-15°以内,检测过程中,转子移动不大于10°电角度。 可以指导该代码移植、帮忙理解、指导调试等

角度计算才是重头戏:

void EstimateInitialAngle(MotorCtrl* ctrl) {
    float delta_angle[6];
    for(int i=0; i<6; i++){
        HFI_InjectPulse(ctrl);
        delta_angle[i] = ProcessHFIResponse(&ctrl->adc_data);
        RotateInjectionAxis(60.0f);  // 60度电角度步进
    }
    
    // 六步法极值定位
    float max_val = -FLT_MAX;
    uint8_t sector = 0;
    for(int j=0; j<6; j++){
        if(delta_angle[j] > max_val){
            max_val = delta_angle[j];
            sector = j;
        }
    }
    ctrl->init_angle = sector * 60.0f + 30.0f; // 取扇区中间值
}

这个六步法看着简单,调试时可是吃过闷亏。有次测试发现角度总是偏30度,最后发现是PWM死区补偿没做好导致实际注入矢量偏移。建议在初始化时做个自检:固定注入六个方向,用电流钳观察响应是否对称。

参数自适应这块的代码最有意思:

void AutoTuneHFIParams(MotorCtrl* ctrl) {
    float test_voltages[] = {0.5f, 1.0f, 2.0f, 3.0f};
    float response_ratio[4];
    
    for(int i=0; i<4; i++){
        ctrl->V_inj = test_voltages[i];
        HFI_InjectPulse(ctrl);
        response_ratio[i] = GetResponseAmplitude() / ctrl->V_inj;
    }
    
    // 找响应曲线的拐点
    float slope[3];
    for(int j=0; j<3; j++){
        slope[j] = response_ratio[j+1] - response_ratio[j];
    }
    
    // 选择最大斜率对应的电压值
    uint8_t optimal_index = 0;
    for(int k=1; k<3; k++){
        if(slope[k] > slope[optimal_index]){
            optimal_index = k;
        }
    }
    ctrl->V_inj_optimal = test_voltages[optimal_index] * 1.2f; // 留20%余量
}

这个自动整定算法在带载调试时救过命。某客户电机电感量只有标称值的70%,传统固定参数根本没法用,加上这个自整定功能后直接兼容。注意那个1.2的系数,实验室环境可以降到1.1,但考虑到产线电压波动还是保守点好。

调试时必备的骚操作:拿个强磁铁吸在转子上,手动旋转不同角度看估计值是否跟随。遇到过编码器接口受高频干扰的情况,在GPIO上加个220pF电容立竿见影。还有次发现注入时电机微动,把注入时间从500us缩短到300us就稳了——所以说别死磕代码,硬件特性也得门儿清。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐