APM32F035作为一款32位FoC矢量控制MCU,内置Vector Computer多种专用数学运算加速器,提供整套FoC控制算法支持。该款新品具有优异的高效运算与处理速度,丰富的模拟与连接特性赋予电机更多的新功能属性,有效提升电机驱动性能并降低用户产品运行成本,助力国内电机企业全面迈入“IE3高效时代”。
APM32F035具备满足各种电机控制应用的外设与内存,多种核心电机控制算法大幅提升电机效率,满足行业结构升级需求,广泛应用于风机、水泵、电动工具、园林工具、电动两/三轮车、冰箱压缩机等细分场景。
前段时间在芯查查商城上面申请的APM32F035开发板,当初为了学习直流无刷电机的控制方式,也很幸运可以申请到该块开发板。也是苦于忙其他的项目,抽空在的时候在淘宝上面买了一个DC 24V的直流无刷电机,今天就和大家分享一下心得。
1:整体硬件设计
由于我购买的直流无刷电机是DC24V,所以电源输入电压我配置的是DC24V 2A的电源输入, 输入电压并经过U2LM5164转换为 12V,为Gate driver IC提供稳定的电压输入;5V、经过U4SPX3819 3.3V 电压输出给到MCU微处理器,硬件上的电平转换如下:
功率开关管则直接使用 24V 电源。同时,该方案采用可变电阻旋钮调节 0~3.3V 的电压输入作为速度命令的输入端, 以此调节电机转速。
使用可直接通过转动可变电阻旋钮以此调节输入电压,同时当输入电压值超过起动阈值时, 电机将会启动运行, 而当电压值低于阈值时电机将会关闭运行。
当电机启动后, APM32F035 处理器通过内置的运算放大器并经由相应的采样电路可获取三相的相电流 Iu、 Iv 与 Iw, 并将该数据经过坐标轴的转换后进而控制电机的力矩电流大小及相位;通过FOC 控制计算环节后调节 TMR1 外设输出相应的三路互补的 PWM 波控制逆变器的开关元器件。
2:相电流采样电路
这里设计的最大可以到达16.5A的电流,完全可以满足需要。
3:霍尔检测电路:
当时调试的时候这个地方检测也是研究了一段时间,才把这个电路研究明白。
4:电机实物图片1:部分代码如下所示:
#define _USER_FUNCTION_C_
/** Files includes */
#include "user_function.h"
#include "parameter.h"
#include "BLDC_SensorLess.h"
void spd_pi_init(pi_para_t *pstc)
{
pstc->s16_Error = 0;
pstc->s32_Pterm = 0;
pstc->s32_Iterm = 0;
pstc->s32_ItermPre = 0;
pstc->s32_OutTemp = 0;
pstc->s32_Out = 0;
pstc->s16q10_Kp = M1_SPEED_KP_Q10;
pstc->s16q10_Ki = M1_SPEED_KI_Q10;
pstc->s32_Umax = 8000;
pstc->s32_Umin = 0;
}
void Motor_stcRampInit(void)
{
Motor_stcRampCal.u16Freq = 1;
Motor_stcRampCal.i16Gain = 40u;//ui_u16RampGain;
Motor_stcRampCal.i16Offset =20u;// ui_u16AlignPwmDuty;
Motor_stcRampCal.i16Out = 460u;//ui_u16AlignPwmDuty;
Motor_stcRampCal.i16Angle = 0;
Motor_stcRampCal.i16OutMax = 460u;//ui_u16RampDutyMax;
Motor_stcRampCal.bRampFinFlag = FALSE;
}
/**
* @brief Initializes the Motor control parameters
* @retval None
*/
void Init_Parameter(Motor_TypeDef *Motor)
{
/* PWM setting */
Motor->USER.u16PWMFreq = PWMFREQ; /* PWM Frequence*/
Motor->USER.u16DeadTime = SYSCLK_HSE_72MHz / 1000000 * DEAD_TIME; /* Dead time */
Motor->USER.s16RampUp = Q15(RAMP_UP / SLOWLOOP_FREQ); //1000 rmp/s
Motor->USER.s16RampDown = Q15(RAMP_DOWN / SLOWLOOP_FREQ); //1000 rmp/s
/* Protection */
Motor->USER.s16OVPCmd = Q15(DCBUS_OVER / UDC_MAX);
Motor->USER.s16UVPCmd = Q15(DCBUS_UNDER / UDC_MAX);
Motor->USER.s16OIPCmd = IBUS_OVER_CMD;
Motor->USER.u16FaultReleaseTimeCmd = FAULTRELEASE_TIME * SLOWLOOP_FREQ;
Motor->USER.u16PWMPeriod = SYSCLK_HSE_72MHz / Motor->USER.u16PWMFreq;
Motor->USER.u16SlowLoopDiv = PWMFREQ / SLOWLOOP_FREQ;
Motor->USER.u16AlignTimeCmd = ALIGN_TIME;
Motor->USER.u16StartupTimeCmd = STARTUP_TIME;
Motor->BLDC.u32StartUp_PwmValue = 460;
Motor->BLDC.u8SpeedReachedFlag = FALSE;
Motor->BLDC.u32PwmValue = STARTUP_PWMVALUE1; //Motor startup PWM value
Motor->BLDC.u8Direction = ECCW; //Motor rotation direction
Motor->BLDC.u32ForceCommutationThreshold = FORCED_COMMUTATION_TIME; //Motor's Forced commutation time
Motor->USER.u16ForceCommutationCnt = 133;//此为 40000 / 300 rpm = 133 cnt
Motor->BLDC.u16Startup_CommuteTime = 133;
//Zeroing back electromotive force zero-crossing voltage
MovingAvgInit(&u16ZcdBemfU);
MovingAvgInit(&u16ZcdBemfV);
MovingAvgInit(&u16ZcdBemfW);
spd_pi_init(&Motor->stc_SpdPi);
/*Initialize feedback speed filter array*/
//MovingAvgInit(&SpeedFdk);
InitNormalization(300,3796,3000,&Motor->USER.RP);
/*Initialize acceleration curve parameters*/
LoopCmp_Init(&Motor->BLDC.RPValue);
}
/**
* @brief Reset the Motor control parameters
* @retval None
*/
void variable_reset(Motor_TypeDef *Motor)
{
Motor_1st.USER.u16AlignTimeCnt = 0; /* Motor Align time cnt */
Motor_1st.USER.u16RampCnt = 0; /* Motor ramp time cnt */
Motor_1st.BLDC.u8Phase = 0; /* Motor phase sequence */
Motor_1st.BLDC.u8PhaseShadow = 0; /* Motor phase sequence Shadow */
Motor_1st.BLDC.u8flag_zcd = 0; /* BMEF crossing-zero flag */
Motor_1st.BLDC.u32ForceCommutationCnt = 0; /* Motor's Forced commutation time cnt */
Motor_1st.BLDC.u32PwmValue = 0; /* PWM Output value */
Motor_1st.BLDC.u32CntElectricalPeriodNumber = 0; /* Record the number of electrical cycles */
Motor_1st.BLDC.u16Startup_CommuteTime = 133;
Motor_1st.BLDC.u8_StepCnt = 0;
spd_pi_init(&Motor->stc_SpdPi);
Motor_stcRampInit();
}
#define _USER_FUNCTION_C_
/** Files includes */
#include "user_function.h"
#include "parameter.h"
#include "BLDC_SensorLess.h"
void spd_pi_init(pi_para_t *pstc)
{
pstc->s16_Error = 0;
pstc->s32_Pterm = 0;
pstc->s32_Iterm = 0;
pstc->s32_ItermPre = 0;
pstc->s32_OutTemp = 0;
pstc->s32_Out = 0;
pstc->s16q10_Kp = M1_SPEED_KP_Q10;
pstc->s16q10_Ki = M1_SPEED_KI_Q10;
pstc->s32_Umax = 8000;
pstc->s32_Umin = 0;
}
void Motor_stcRampInit(void)
{
Motor_stcRampCal.u16Freq = 1;
Motor_stcRampCal.i16Gain = 40u;//ui_u16RampGain;
Motor_stcRampCal.i16Offset =20u;// ui_u16AlignPwmDuty;
Motor_stcRampCal.i16Out = 460u;//ui_u16AlignPwmDuty;
Motor_stcRampCal.i16Angle = 0;
Motor_stcRampCal.i16OutMax = 460u;//ui_u16RampDutyMax;
Motor_stcRampCal.bRampFinFlag = FALSE;
}
/**
* @brief Initializes the Motor control parameters
* @retval None
*/
void Init_Parameter(Motor_TypeDef *Motor)
{
/* PWM setting */
Motor->USER.u16PWMFreq = PWMFREQ; /* PWM Frequence*/
Motor->USER.u16DeadTime = SYSCLK_HSE_72MHz / 1000000 * DEAD_TIME; /* Dead time */
Motor->USER.s16RampUp = Q15(RAMP_UP / SLOWLOOP_FREQ); //1000 rmp/s
Motor->USER.s16RampDown = Q15(RAMP_DOWN / SLOWLOOP_FREQ); //1000 rmp/s
/* Protection */
Motor->USER.s16OVPCmd = Q15(DCBUS_OVER / UDC_MAX);
Motor->USER.s16UVPCmd = Q15(DCBUS_UNDER / UDC_MAX);
Motor->USER.s16OIPCmd = IBUS_OVER_CMD;
Motor->USER.u16FaultReleaseTimeCmd = FAULTRELEASE_TIME * SLOWLOOP_FREQ;
Motor->USER.u16PWMPeriod = SYSCLK_HSE_72MHz / Motor->USER.u16PWMFreq;
Motor->USER.u16SlowLoopDiv = PWMFREQ / SLOWLOOP_FREQ;
Motor->USER.u16AlignTimeCmd = ALIGN_TIME;
Motor->USER.u16StartupTimeCmd = STARTUP_TIME;
Motor->BLDC.u32StartUp_PwmValue = 460;
Motor->BLDC.u8SpeedReachedFlag = FALSE;
Motor->BLDC.u32PwmValue = STARTUP_PWMVALUE1; //Motor startup PWM value
Motor->BLDC.u8Direction = ECCW; //Motor rotation direction
Motor->BLDC.u32ForceCommutationThreshold = FORCED_COMMUTATION_TIME; //Motor's Forced commutation time
Motor->USER.u16ForceCommutationCnt = 133;//此为 40000 / 300 rpm = 133 cnt
Motor->BLDC.u16Startup_CommuteTime = 133;
//Zeroing back electromotive force zero-crossing voltage
MovingAvgInit(&u16ZcdBemfU);
MovingAvgInit(&u16ZcdBemfV);
MovingAvgInit(&u16ZcdBemfW);
spd_pi_init(&Motor->stc_SpdPi);
/*Initialize feedback speed filter array*/
//MovingAvgInit(&SpeedFdk);
InitNormalization(300,3796,3000,&Motor->USER.RP);
/*Initialize acceleration curve parameters*/
LoopCmp_Init(&Motor->BLDC.RPValue);
}
/**
* @brief Reset the Motor control parameters
* @retval None
*/
void variable_reset(Motor_TypeDef *Motor)
{
Motor_1st.USER.u16AlignTimeCnt = 0; /* Motor Align time cnt */
Motor_1st.USER.u16RampCnt = 0; /* Motor ramp time cnt */
Motor_1st.BLDC.u8Phase = 0; /* Motor phase sequence */
Motor_1st.BLDC.u8PhaseShadow = 0; /* Motor phase sequence Shadow */
Motor_1st.BLDC.u8flag_zcd = 0; /* BMEF crossing-zero flag */
Motor_1st.BLDC.u32ForceCommutationCnt = 0; /* Motor's Forced commutation time cnt */
Motor_1st.BLDC.u32PwmValue = 0; /* PWM Output value */
Motor_1st.BLDC.u32CntElectricalPeriodNumber = 0; /* Record the number of electrical cycles */
Motor_1st.BLDC.u16Startup_CommuteTime = 133;
Motor_1st.BLDC.u8_StepCnt = 0;
spd_pi_init(&Motor->stc_SpdPi);
Motor_stcRampInit();
}
全部评论