598|4

11

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【极海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 的整数倍值,实际的情况需要根据你的电机霍尔安装位置来进行准确赋值,如果赋值准确的话,两条线应该是基本重合的。可以看出例程所给出的滑膜观测器对转子的电角度的观测值是基本与霍尔电角度基本吻合的,是可以完美控制电机的

最新回复

这个滑膜,电机可以反转吗?   详情 回复 发表于 2024-12-13 15:50
点赞 关注
 
 

回复
举报

6534

帖子

9

TA的资源

版主

沙发
 

这是软件自动测量的吗?  

点评

自己弄的代码测试出来的,例程代码不带这些  详情 回复 发表于 2024-12-12 14:36
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
秦天qintian0303 发表于 2024-12-12 12:18 这是软件自动测量的吗?  

自己弄的代码测试出来的,例程代码不带这些

 
 
 

回复

248

帖子

0

TA的资源

纯净的硅(初级)

4
 

这个滑膜,电机可以反转吗?

点评

可以的,有拨码可以控制正反转  详情 回复 发表于 2024-12-14 21:07
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

5
 
qiao--- 发表于 2024-12-13 15:50 这个滑膜,电机可以反转吗?

可以的,有拨码可以控制正反转

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表