【极海APM32M3514电机通用评估板】滑膜观测器电角度与霍尔采集到的电角度数据比对
[复制链接]
本帖最后由 IllusionXX 于 2024-12-12 10:57 编辑
这次官方只提供了无感的例程,我手头上的电机是带有霍尔线的,于是想要将滑膜观测器观测得到的电角度与霍尔采集到的电角度进行比较一下,看一下滑膜观测器是性能参数
首先在官方例程代码中加入HALL GPIO的初始化:因为只是简单的读取IO口,所以并没有加入中断,如果使用霍尔观测器那么是需要加入霍尔口的中断的
void HALL_GPIO_Init(void)
{
GPIO_Config_T GPIO_InitStructure;
GPIO_InitStructure.pin = GPIO_PIN_3;
GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
GPIO_InitStructure.mode = GPIO_MODE_IN;
GPIO_InitStructure.pupd = GPIO_PUPD_NO;
GPIO_Config(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.pin = GPIO_PIN_1;
GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
GPIO_InitStructure.mode = GPIO_MODE_IN;
GPIO_InitStructure.pupd = GPIO_PUPD_NO;
GPIO_Config(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.pin = GPIO_PIN_0;
GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
GPIO_InitStructure.mode = GPIO_MODE_IN;
GPIO_InitStructure.pupd = GPIO_PUPD_NO;
GPIO_Config(GPIOA, &GPIO_InitStructure);
}
定义一个存储用的结构体:
user_uart.h
typedef struct
{
int16_t debug_num;//记录当前计数的个数
// int16_t U[DEBUG_MAX_NUM];
// int16_t V[DEBUG_MAX_NUM];
// int16_t W[DEBUG_MAX_NUM];
int16_t LOC[DEBUG_MAX_NUM];//滑膜观测器的电角度
uint8_t HALL[DEBUG_MAX_NUM];//采集到的霍尔值
} debugdata_S;
extern debugdata_S debug_data;
在相关代码加入数据的采集,同样也是在电机稳定运行后采集数据
static void M1_RunSpinFast(void)
{
Motor_type.Foc.s16CmdTheta += Motor_type.stc_SmoPara.s16q15SpdObs*Motor_type.Foc.s16SpdToTheta >> 15;
Motor_type.Foc.stc_SinCos = sin_cos_cal(Motor_type.Foc.s16CmdTheta);
static uint32_t cnt=0;
cnt++;
if(cnt>=100000)
{
// printf("cnt =10000\n");
if(debug_data.debug_num<=1000)
{
debug_data.debug_num++;
debug_data.LOC[debug_data.debug_num] = Motor_type.Foc.s16CmdTheta;//采集滑膜观测器的电角度
debug_data.HALL[debug_data.debug_num] = (GPIO_ReadInputBit(GPIOA,GPIO_PIN_3)<<2) + (GPIO_ReadInputBit(GPIOA,GPIO_PIN_1)<<1) + (GPIO_ReadInputBit(GPIOA,GPIO_PIN_0));//采集霍尔值
}
}
if(cnt==1)
{
// printf("cnt =0\n");
}
/*Current loop*/
current_ctrl(&Motor_type);
Motor_type.Foc.u16q15Vdq_sqrt = isqrt32((uint32_t)(Motor_type.Foc.stc_Vdq.s16q15_D * Motor_type.Foc.stc_Vdq.s16q15_D + Motor_type.Foc.stc_Vdq.s16q15_Q * Motor_type.Foc.stc_Vdq.s16q15_Q));
/* observation */
Motor_type.stc_SmoPara.s16q15_Ialpha = Motor_type.Foc.stc_Iab.s16q15_A;
Motor_type.stc_SmoPara.s16q15_Ibeta = Motor_type.Foc.stc_Iab.s16q15_B;
Motor_type.stc_SmoPara.s16q15_Ualpha = Motor_type.Foc.stc_Vab.s16q15_A;
Motor_type.stc_SmoPara.s16q15_Ubeta = Motor_type.Foc.stc_Vab.s16q15_B;
smo_cal(&Motor_type.stc_SmoPara);
/* PLL */
Motor_type.stc_PiPll.s16_Error = ((-Motor_type.stc_SmoPara.s16q15_Ealpha*Motor_type.Foc.stc_SinCos.s16q15_Cos)
- (Motor_type.stc_SmoPara.s16q15_Ebeta*Motor_type.Foc.stc_SinCos.s16q15_Sin)) >> 15;
anti_pi(&Motor_type.stc_PiPll);
Motor_type.stc_SmoPara.s16q15SpdObs = Motor_type.stc_PiPll.s32_Out;
/* svpwm */
Motor_type.Foc.stc_SvpwmPara.s16q15_Vbus = Motor_type.Foc.s16Vbus;
Motor_type.Foc.stc_SvpwmPara.s16q15_Valpha = Motor_type.Foc.stc_Vab.s16q15_A;
Motor_type.Foc.stc_SvpwmPara.s16q15_Vbeta = Motor_type.Foc.stc_Vab.s16q15_B;
svpwm7_cal(&Motor_type.Foc.stc_SvpwmPara);
PWM_Update(&Motor_type);
}
main.c while循环中添加数据采集完成后打印数据,并进行霍尔电角度线性化的代码:
debug_data.debug_num++;
for(int32_t i = 0;i<DEBUG_MAX_NUM +1;i++)
{
static int16_t hall_loc;//霍尔值赋对应电角度后的值
static uint8_t last_hall=0;//上一次霍尔值,线性化霍尔电角度使用,用来进行插补
static uint8_t same_hall=0;//相同霍尔值的次数,线性化霍尔电角度使用,用来进行插补
static uint8_t last_same_hall=0;//上次相同霍尔值的次数,线性化霍尔电角度使用,用来进行插补
if(last_hall!=debug_data.HALL[i])//与上次霍尔值不同
{
last_hall = debug_data.HALL[i];
last_same_hall = same_hall;
same_hall = 0;
if(debug_data.HALL[i]==5)
{
hall_loc = 0;
}
else if(debug_data.HALL[i]==1)
{
hall_loc = 10922;
}
else if(debug_data.HALL[i]==3)
{
hall_loc = 21844;
}
else if(debug_data.HALL[i]==2)
{
hall_loc = -32767;
}
else if(debug_data.HALL[i]==6)
{
hall_loc = -21845;
}
else if(debug_data.HALL[i]==4)
{
hall_loc = -10923;
}
else
{
hall_loc = 0;
}
}//与上次霍尔值相同
else
{
same_hall++;
// hall_loc+=32767/3/last_same_hall;//可注释,不注释进行霍尔值电角度线性化
}
printf("%d,%d,%d\n",debug_data.LOC[i],debug_data.HALL[i],hall_loc);
}
}
下面是我对读取到的霍尔值简单赋值对应电角度所得到的数据,对应不同的电机,以及正转还是反转,赋的值会有不同,上面代码赋的值只适配与我的电机
红线为滑膜观测的电角度,蓝线为霍尔值赋对应电角度的值
这样看并不明显,下面将我们的对霍尔电角度插补来进行线性化,下面是我线性化的结果
红线为滑膜观测的电角度,蓝线为霍尔值赋对应电角度进行线性化后的值
可以看到滑膜观测器的电角度值是紧跟采集到的霍尔电角度值,上面图片两条线有一定相位偏移是因为我的代码在赋值霍尔电角度时只是简单的在霍尔变化时候赋32768/3 的整数倍值,实际的情况需要根据你的电机霍尔安装位置来进行准确赋值,如果赋值准确的话,两条线应该是基本重合的。可以看出例程所给出的滑膜观测器对转子的电角度的观测值是基本与霍尔电角度基本吻合的,是可以完美控制电机的
|