FOC(笔记二)

时间:2024-07-15 06:59:06

 接上篇文章:FOC算法(笔记一)_马鞍波和三角波调制合成-****博客

        前面已经对FOC的开环控制进行了介绍,下面对FOC的闭环控制进行介绍。

本次使用的电机参数如下图所示:

一、HALL传感器

1.1、霍尔传感器的角度、速度计算

        因为本次使用的是120°安装的三相霍尔编码器,所以霍尔德精度是非常低的,如下图所示的,每圈只能检测6次,对角度的精度是比较低的,所以较低速度情况下如无法获得电机的角度和角速度信息的。

        所以通过计算上一个60°的电机的转速,作为下一个60°来临之前的速度,乘以ADC检测时间就可以算出中间检测时间。

(1) 如下图所示的,通过判断霍尔三相GPIO的电平可以判断当前霍尔的角度在第几个60°。 

(2)一般电机三相的0角度为Ud=1、Uq=0电平的时候转子所在位置,所以转子的0°和霍尔德0°,也即是如下图所示0x50位置所示的0°,两个是不一样的,所以需要对角度进行补偿,具体补偿如下代码所示:

#define PHASE_SHIFT_ANGLE (float)(220.0f/360.0f*2.0f*PI)

(3)只知道是多少个60°,精度太低,所以通过定时器对三相霍尔德编码器进行霍尔(HALL)模式的检测,当有上升沿、下降沿的时候就触发定时器的中断,之后通过中断的时间和60°角度计算出来电机的转速,后面在ADC检测中使用角度自增的时候,直接用速度乘以ADC检测时间就可以计算出来每次ADC检测角度的增量。从而平滑的获得角度递增的锯齿波结果。

(4)上面(3)中计算出来的速度是电机的角速度,在速度闭环控制的时候,使用的机械速度,并且两者都是弧度制的,所以应该将角速度转化为机械速度(转/min、r/min)角速度(°/s)/360°/60s*极对数.

2.2、霍尔编码器嵌入式程序

        如下面代码所示的是TIM4定时器的编码器模式,在检测到三相上有电平变化的时候产生中断,中断中调用下面的回调函数,回调函数中计算速度(机械角度频率,转/分钟,rmp/min),ADC一个检测周期角度增加值。

(1)HallTemp = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);
(2)HallThetaAdd = (PI/3)/(HallTemp/3200000)/10000;          
(3)HallSpeed = (PI/3)*2/(HallTemp/3200000)*60/(2*PI);

(1)获得触发定时器中断的时间。

(2)计算ADC一个检测周期的角度增加值HallThetaAdd,PI/3表示一个编码器触发周期的角度;HallTemp/3200000表示定时器的计时时间,单位秒,(计数次数/TIM时钟频率);10000标志ADC检测的频率,除以频率等于乘以ADC检测一次时间。

(3)计算电机的速度(rmp/min),2表示电机的极对数,将电角度转化为机械角度;60是将秒转化为分钟;(2*PI)标志一圈的弧度,将弧度转化为圈。

//转子0角度和霍尔零角度的差值补偿
#define PHASE_SHIFT_ANGLE (float)(220.0f/360.0f*2.0f*PI)

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(htim);
	if(htim == &htim4)
	{
		HallTemp = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);
		HallThetaAdd = (PI/3)/(HallTemp/3200000)/10000;          //电角度的速度增量,除以10000是为了提前乘以ADC采样时间。
		HallSpeed = (PI/3)/(HallTemp/3200000)*30/(2*PI);         //角度的计算,60/计数时间,然后将电角度转化为机械角度
    
//    /* 一介低通滤波器,对于高频噪声滤波效果好,运算量小 */
//    HallSpeed_filter = HallSpeed;
//    HallSpeed_filter = (1-(HallTemp/16000))*HallSpeed_last+(HallTemp/16000)*HallSpeed_filter;
//    HallSpeed_last = HallSpeed_filter;
    
    /* 角度的判断,只能60增加的判断 */
	HallReadTemp = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8);
	HallReadTemp |= HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)<<1;
	HallReadTemp |= HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6)<<2;
    if(HallReadTemp==0x05) 
    {
      HallTheta = 0.0f+PHASE_SHIFT_ANGLE;
    }
    else if(HallReadTemp==0x04)
    {
      HallTheta = (PI/3.0f)+PHASE_SHIFT_ANGLE;
    }
    else if(HallReadTemp==0x06)
    {
      HallTheta = (PI*2.0f/3.0f)+PHASE_SHIFT_ANGLE;
    }
    else if(HallReadTemp==0x02)
    {
      HallTheta = PI+PHASE_SHIFT_ANGLE;
    }
    else if(HallReadTemp==0x03)
    {
      HallTheta = (PI*4.0f/3.0f)+PHASE_SHIFT_ANGLE;
    }
    else if(HallReadTemp==0x01)
    {
      HallTheta = (PI*5.0f/3.0f)+PHASE_SHIFT_ANGLE;
    }
    if(HallTheta<0.0f)
    {
      HallTheta += 2.0f*PI;
    }
    else if(HallTheta>(2.0f*PI))
    {
      HallTheta -= 2.0f*PI;
    }	
	}
}

        下面是对上面回调函数中计算的数据的使用。

HallTheta = HallTheta + HallThetaAdd;    //区间角度+角度变化值
if(HallTheta < 0.0f)
{
	HallTheta += 2.0f*PI;
}
else if(HallTheta > (2.0f*PI))
{
	HallTheta -= 2.0f*PI;
}
g_SC.theta = HallTheta;           //当前的角度值
g_SpPI.Speed_now = HallSpeed;     //当前编码器速度

二、电流环闭环

2.1、电流闭环整体框架

        

2.2、电流闭环simulink模型

2.3、电流环PI控制

2.3.1、PI控制器输入输出的限幅

2.3.2、PI控制的Kp、Ki的计算和调整

三、速度环闭环

3.1、速度闭环整体系统框图

3.2、速度闭环simulink模型

3.3、速度环PI控制器

3.3.1、PI控制器输入输出的限幅

3.3.2、PI控制器的Kp、Ki的计算和调整