VF强拖和IF强拖介绍:

      强拖就是人工给定电角度,斜坡强拖就是电角度增加的速度不是固定的而是缓慢增加的,直到最后电角度的速度增加到给定速度为止;VF强拖就是电压开环强拖,给定一个固定的Ud和Uq,然后执行反Park变换和SVPWM(此时不需要执行完整的FOC环路,最易实现),IF强拖则是给定一个固定的id_ref和iq_ref,然后执行FOC电流环让id和iq逐渐接近给定的id_ref和iq_ref(此时需要保证电流环的PID参数是合理的,稍微复杂,但比VF强拖更稳定);

    不管是VF强拖还是IF强拖,本质都是不去获取真实电角度,而是人为给定一个电角度,在无法获取准确电角度又想让电机转动的情况下可以使用;

/************* 斜坡强拖具体代码实现   (浮点和定点)*****************/

/*RPM_ref
*/
#define  PWM_Time   100 //FOC中断执行间隔时间,单位us
uint32_t IF_VF_RUN(uint16_t RPM_ref, uint16_t Time_ms)
{
      static float Angular_Speed;
      static float Angular_Angle = 0;
    
    uint64_t Angular_Speed_ref = (uint64_t)(RPM_ref)*65536ULL/60ULL*(uint64_t)Hall_Three.Poles;     //计算目标电角速度  Q16格式的 rad/s
    uint32_t IF_FOC_num = (uint32_t)Time_ms*1000 / PWM_Time; //爬坡过程FOC中断次数  
      uint32_t Angular_Speed_step = Angular_Speed_ref / IF_FOC_num;  //每次FOC中断的爬坡电角速度步进值

    Angular_Speed += Angular_Speed_step;  //计算本次电角速度
      if( Angular_Speed >= Angular_Speed_ref)
            Angular_Speed = Angular_Speed_ref;
            
    Angular_Angle = Angular_Angle + Angular_Speed * (float)Hall_Three.Speed_PWM_Time / 1000000;  //计算本次电角度
    if(Angular_Angle >= 65536)
        Angular_Angle -= 65536;
    uint32_t Angular_Angle_Q16 = (uint32_t)(Angular_Angle);  //将电角度转换为Q15格式

    return Angular_Angle_Q16;  //返回Q16格式的电角度
}

#define Two_PI 6.28318530718f
float IF_VF_RUN_Float(float RPM_ref, float Time_ms)
{
	  Angular_Speed_ref = RPM_ref*6.28f/60.0f*Pole; 	//计算目标电角速度
      IF_FOC_num = Time_ms * 1000 / (float)PWM_Time;   //爬坡过程FOC中断次数
	  Angular_Speed_step = Angular_Speed_ref / IF_FOC_num;  //每次FOC中断的爬坡电角速度步进值

    Angular_Speed += Angular_Speed_step;  //计算本次电角速度
	  if( Angular_Speed >= Angular_Speed_ref)
			Angular_Speed = Angular_Speed_ref;
			
    Angular_Angle = Angular_Angle + Angular_Speed * 50.0f / 1000000.0f;  //计算本次电角度
    if(Angular_Angle >= Two_PI)
        Angular_Angle -= Two_PI;
   
	 return  Angular_Angle;  //返回电角度
}

实际使用案例:

    VF强拖就是直接在电流环PID控制后面给一个固定的Ud和Uq,IF强拖则是在电流环PID控制前面给定一个固定的iq_ref和id_ref

/*FOC中断*/
void HAL_ADCEx_InjectedConvCpltCallback( ADC_HandleTypeDef *hadc)
{
		
		/***********************   1、Processing Eleangle  ***************************/
	
		Predict_eleangle = VF_IF_RUN_Float(600.0f, 6000.0f);  	//强拖提供电角度

		

		/***********************   2、Processing ADC  ***************************/
		
		adc1_in1 =  ADC1->JDR1;   
	  adc2_in2  =  ADC2->JDR1;  

    foc_abc_current_i.ia  =  ((float)adc1_in1 - ADCSampPare.OffsetPhaseU_Curr) * 0.0201416f;
		foc_abc_current_i.ib  =  ((float)adc2_in2 - ADCSampPare.OffsetPhaseV_Curr) * 0.0201416f;	//3.3/4096 /(40V/V) / (0.001Ω)
		foc_abc_current_i.ic = - foc_abc_current_i.ia - foc_abc_current_i.ib;
		
		/***********************   FOC Algorithm   ***************************/
		Angle_Sin_Cos(Predict_eleangle, &foc_sin_cos);  //
		Clark(foc_abc_current_i, &foc_alpha_beta_i);
		Park(foc_alpha_beta_i, foc_sin_cos, &foc_dq_i);
	
		foc_dq_i.iq = Lpf(foc_dq_i.iq, foc_dq_i.iq_last,0.8f);
		foc_dq_i.iq_last = foc_dq_i.iq;
		
		foc_dq_i.id = Lpf(foc_dq_i.id, foc_dq_i.id_last,0.8f);
		foc_dq_i.id_last = foc_dq_i.id;
		
		current_q_pid.fbk = foc_dq_i.iq;
		current_d_pid.fbk = foc_dq_i.id;

       //		current_q_pid.ref = 0.1f;   //电流强拖
       //		current_d_pid.ref = 0.0f;
		current_pid_Control(&current_q_pid);
		current_pid_Control(&current_d_pid); 
 		//      foc_dq_v.vq = 1.0f;  //电压强拖
        //      foc_dq_v.vd = 0.0f;
		
		Reverse_Park(foc_sin_cos, foc_dq_v, &foc_alpha_beta_v);
	 /*Overmodulation prevention*/
		RevPark_Circle_Limitation_cmsis(&foc_alpha_beta_v.v_alpha, &foc_alpha_beta_v.v_beta,
																				Udc, 0.95f);
		Foc_Svpwm(foc_alpha_beta_v, &foc_pwm, Udc, PWM_PERIOD);
		
		TIM1->CCR1 = foc_pwm.pwm_u;
		TIM1->CCR2 = foc_pwm.pwm_v;
		TIM1->CCR3 = foc_pwm.pwm_w;
	}
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐