【极海APM32M3514电机通用评估板】电机调试和AD采样数据分析
[复制链接]
本帖最后由 IllusionXX 于 2024-12-10 13:34 编辑
接上篇,如果使用内部8MHz晶振会导致电机无法正常运行,还是改用外部晶振,打印口变更为烧录口的PA14的SWCLK,但是在串口初始化之前,我们需要增加一个延时函数,防止一上电,SWCLK就被初始化成串口而无法烧录程序。
如图接好电机,我们将调速器逆时针转到底,此时应该是最大的速度,未设置parameter.h的参数前,电机会因为IQ的KP和KI以及速度环的KP和KI过大,由于电机转子起转较慢,导致电机无法起转成功,
我们可以先将IQ的KP调小,KI调为0,发现可以转动一定角度,后来转子就无法跟上观测器设置的电角度,此时将速度环的Ki调小,此时基本完美启动,再将IQ的Ki值加上,所以造成无法电机无法启动的原因基本就是给定的启动值和加速度太大,电机转子无法跟上设定的速度,造成启动失败。以下是我的电机参数和调试的参数
/*电流环PI参数设定*/
#define CUR_PI_Q (15) // 15 or 10, can't select others, 15:Q15 format KP&KI, 10:Q10 format KP&KI
#define M1_IQ_KP (500) // Q15 format KP of Q-axis Current loop
#define M1_IQ_KI (1) // Q15 format KI of Q-axis Current loop
#define M1_ID_KP (500) // Q15 format KP of D-axis Current loop
#define M1_ID_KI (1) // Q15 format KI of D-axis Current loop
/*速度环PI参数设定*/
#define SPD_PI_Q (15) // 15 or 10, can't select others, 15:Q15 format KP&KI, 10:Q10 format KP&KI
#define M1_SPEED_KP (16384) // Q15 format KP of speed loop
#define M1_SPEED_KI (16) // Q15 format KI of speed loop
起转视频:
下面测试稳定转动时UVW的三相电流,程序上添加打印程序如下:
user_uart.h
/**/
#define DEBUG_MAX_NUM 1024
typedef struct
{
int16_t debug_num;
int16_t U[DEBUG_MAX_NUM];
int16_t V[DEBUG_MAX_NUM];
int16_t W[DEBUG_MAX_NUM];
} debugdata_S;
extern debugdata_S debug_data;
FOC_Ctrl.c
void Get_ADC_Result(Motor_TypeDef *Motor)
{
int16_t s16Ib_Temp, s16Ia_Temp;
int16_t s16IbusTemp;
/*get the two phase current */
s16Ib_Temp = (int16_t)ADC_GetValue(CURR_CHANNEL_V) << 3;
s16Ia_Temp = (int16_t)ADC_GetValue(CURR_CHANNEL_U) << 3;
s16IbusTemp = (int16_t)ADC_GetValue(IBUS_CHANNEL) << 3;
if(Motor->User.s8Direction != -1)
{
Motor->Foc.stc_Iuvw.s16q15_V = (-s16Ib_Temp + Motor->Foc.stc_IuvwOffset.s16q15_V) * IGAIN_Q10 >>10 ;
Motor->Foc.stc_Iuvw.s16q15_U = (-s16Ia_Temp + Motor->Foc.stc_IuvwOffset.s16q15_U) * IGAIN_Q10 >>10 ;
}
else
{
Motor->Foc.stc_Iuvw.s16q15_U = (-s16Ib_Temp + Motor->Foc.stc_IuvwOffset.s16q15_V) * IGAIN_Q10 >>10 ;
Motor->Foc.stc_Iuvw.s16q15_V = (-s16Ia_Temp + Motor->Foc.stc_IuvwOffset.s16q15_U) * IGAIN_Q10 >>10 ;
}
static uint32_t cnt=0;
cnt++;
if(cnt>=100000)
{
if(debug_data.debug_num<=1000)
{
debug_data.debug_num++;
debug_data.U[debug_data.debug_num]=Motor->Foc.stc_Iuvw.s16q15_U;
debug_data.V[debug_data.debug_num]=Motor->Foc.stc_Iuvw.s16q15_V;
debug_data.W[debug_data.debug_num]=0-debug_data.U[debug_data.debug_num]-debug_data.V[debug_data.debug_num];
}
}
if(cnt==1)
{
}
Motor->Foc.s16q15Ibus = (s16IbusTemp - Motor->Foc.s16q15IbusOffset) * IGAIN_Q10 >>10 ;
/*LPF fc:200hz*/
Motor->Foc.s16q15Ibusfilt = (Motor->Foc.s16q15Ibusfilt * 30382 + Motor->Foc.s16q15Ibus * 2386)>>15;
Motor->Foc.s16Vbus = (int16_t)ADC_GetValue(VDC_CHANNEL) << 3;
Motor->Foc.u32Power = (abs(Motor->Foc.s16q15Ibusfilt) * Motor->Foc.s16Vbus >>15) * 29075 >> 9;
/*LPF fc:100hz*/
Motor->Foc.u32PowerFilt = (Motor->Foc.u32PowerFilt * 31530 + Motor->Foc.u32Power * 1238)>>15;
if(Motor->Foc.u32PowerFilt <= 32767)
{
Motor->Foc.s16PowerFilt = Motor->Foc.u32PowerFilt;
}
else
{
}
// Motor->Foc.s16q15AdVot = (int16_t)ADC_GetValue(IPM_TEMP) << 3;
Motor->User.s16Vsp = ((int16_t)ADC_GetValue(Handle_CHANNEL) << 3);
if(Motor->User.bDirSwitchEnable == true)
{
Motor->User.s16Vsp = 0 ;
}
}
mian.c while循环中
if(debug_data.debug_num==1000)
{
debug_data.debug_num++;
for(int32_t i = 0;i<DEBUG_MAX_NUM +1;i++)
{
// printf("NUM=%d U=%d V=%d W=%d\n\n",i,debug_data.U[i],debug_data.V[i],debug_data.W[i]);
printf("%d,%d,%d\n",debug_data.U[i],debug_data.V[i],debug_data.W[i]);
}
}
以上程序在电机转动一定时间后开始收据数据,在收集一定量数据后在main函数while中打印采集的数据,从而不影响电机转动
以下是我采集到的三相电流数据并绘制的波形图
其中U相和V相电流数据是采集到的,W相电流数据是根据基尔霍夫电流定律计算得到的,以上数据是标幺化的数据,并没有转成0-3.3的形式
可以看到在提供的电机例程中,其电机驱动的代码很好的让无刷电机驱动起来,并让其产生的电流以比较完美的正弦波展现出来
以上数据是对电流环ID轴的Kp和Ki值并未进行深入调试,理论上可以将三相电流正弦波形展现的更完美
补充内容 (2025-1-10 17:33):
转动视频在1楼
|