|
本帖最后由 北方. 于 2023-7-19 16:03 编辑
DK电机驱动的代码分析和运行
1 DK开发板的原理分析
24V 电机驱动开发板系统方块图如下
这个回路是标准的三相电机控制回路,MCU控制双臂MOSFET驱动实现对BLDC的电机电流输出控制,反馈环节是读取电机端电压,相电流和中性点电流,这个图中没有包括Hall传感器的位置信号。如果包括就是3个电压,2个相电流,1个中性点电流和3个Hall传感器位置信号。
主要实现以下功能
输入电压范围 : 12V~30V,MCU 电源使用 5V,支持有/无霍, 方波/弦波驱动,支持1/2/3 Shunt R 三相电流采样,BEMF 电压回授使用ADC 采样,DC Bus 电压, 总电流量测。
在参数设定中,限制了最小电压为15V,这样DK开发板就有5V,12V,>15V三组电压轨,实现不同的功能。如果希望修改参数,需要在parameter.h这个文件中修改。
2 电机控制原理
电机控制的原理相对复杂,这里以PMSM 矢量控制简述如下。 电机的驱动方程为,这个回路的直流电阻Rs通常较小,主要是由磁链的变化形成的感应电压为主,
三相电压和旋转磁场相对应,形成一个正弦波的交变回路,计算中的集体效果电机显现为一个单向旋转的过程,这个过程用一个正交成90度的矢量电流合成表示。换言之,就是通过对三相交流的控制,实现一个单向旋转的单磁极过程,这个过程涉及了Clark变换和反Clark变化,就是用两组公式分别实现这个变换过程。具体可以参考灵动提供的文档。
这个三相电机需要调速运行,也需要控制转矩和保护。这个就需要采集反馈信号量来确定当下的旋转速度,通过调整控制电压的增减来控制转速。矢量控制技术——称磁场定向控制(FOC),FOC 最基本的思想就是将定子电流解耦成一个控制磁场的电流分量和一个控制转矩的电流分量。经过解耦后,两个电流分量独立受控。
无传感器的测量方式是分解反向电动势的方法,使用差分的方式,计算连续测量的反电动势分量,对应于采样时间差值的变量而形成的一个二元一次差分方程求解的方式进行位置计算,这个过程可以节省位置传感器,但是计算的过程需要克服采样的众多干扰和不确定因素,需要各种滤波和算法,提取最终的真实位置。
传感器的方法比较直观,准确性高,但是安装方法比较复杂,也增大成本。这里是用了Hall传感器的方式,计量相对120度分布的3个传感器的位置信号。
这个位置信号是离散的信号组合如下,需要通过PWM插值补全时间
3 代码分析
经过上述分析,在FOC范例代码中实现了这个过程。重要的函数如下,
灵动用封装库的方式提供了电机控制数学库(MLIB)和电机控制数学库(MCFLIB),其中MLIB主要提供基础的计算,MCFLIB提供高层的滤波原理和Clark变换等,提供了使用手册可以查阅和使用。其他的电机控制逻辑完全开放,提供了充分的测试和使用机会,可以根据项目和对于电机的理解自行修改。 主函数是通过polling状态机模式来实现电机的控制。这个是一个低速旋转电机的控制loop。
- int main(void)
- {
- /* Configure the system clock */
- Systick_Init(SystemCoreClock / 1000);
- Systick_Delay(200);
- /* Initialize motor control parameters */
- Init_Parameter(&Motor_1st);
- /* Initialize all GPIO */
- Bsp_Gpio_Init();
- /* Initialize all configured peripherals */
- Peripheral_Init();
- /* Initialize interrupts */
- Interrupt_Init();
- /* Infinite loop */
- while(1)
- {
- /*IWDG_ReloadCounter*/
- IWDG_RELOAD_COUNT();
- if(Motor_1st.USER.bSlowLoopFlag)
- {
- /* Slow Loop Statemachine */
- s_STATE_SLOW[eM1_MainState]();
- Motor_1st.USER.bSlowLoopFlag = 0;
- }
- }
- }
复制代码 状态机模式如下,
- typedef enum _m1_app_mainstate_t
- {
- MainState_Fault = 0,
- MainState_Init = 1,
- MainState_Stop = 2,
- MainState_Run = 3,
- } m1_app_mainstate_t; /* Main States */
- /*! @brief States of machine enumeration */
- typedef enum _m1_run_substate_t
- {
- RunState_Calib = 0,
- RunState_Ready = 1,
- RunState_Align = 2,
- RunState_Startup = 3,
- RunState_Spin = 4,
- RunState_Freewheel = 5,
- } m1_run_substate_t; /* Run sub-states */
- void M1_Fault_Fast(void);
- void M1_Init_Fast(void);
- void M1_Stop_Fast(void);
- void M1_Run_Fast(void);
- void M1_Fault_Slow(void);
- void M1_Init_Slow(void);
- void M1_Stop_Slow(void);
- void M1_Run_Slow(void);
- static void M1_SwitchFaultStop(void);
- static void M1_SwitchInitStop(void);
- static void M1_SwitchStopFault(void);
- static void M1_SwitchStopRun(void);
- static void M1_SwitchRunFault(void);
- //static void M1_SwitchRunStop(void);
- static void M1_RunCalibFast(void);
- static void M1_RunReadyFast(void);
- static void M1_RunAlignFast(void);
- static void M1_RunStartupFast(void);
- static void M1_RunSpinFast(void);
- static void M1_RunFreewheelFast(void);
- static void M1_RunCalibSlow(void);
- static void M1_RunReadySlow(void);
- static void M1_RunAlignSlow(void);
- static void M1_RunStartupSlow(void);
- static void M1_RunSpinSlow(void);
- static void M1_RunFreewheelSlow(void);
- static void M1_SwitchRunCalibReady(void);
- static void M1_SwitchRunReadyAlign(void);
- static void M1_SwitchRunAlignStartup(void);
- static void M1_SwitchRunAlignReady(void);
- static void M1_SwitchRunStartupSpin(void);
- static void M1_SwitchRunStartupFreewheel(void);
- static void M1_SwitchRunSpinFreewheel(void);
- static void M1_SwitchRunFreewheelReady(void);
- static void M1_FaultDetection(void);
- static void Fault_LED_Disp(void);
- static void PWM_Update(Motor_TypeDef *Motor);
复制代码 这个模块化的控制,提供了用户功能定义userfunction.c入口,可以自定义控制模式,控制方法就是直接设定状态机的参数,这里demo提供了参考的编写方式。
那么,在正式运行代码的时候,这个最重要的parameter.h是需要仔细研究并根据电机的参数修订的。包括了控制电压范围,过压设定和低压设定,PWM采样频率等。
- #define SYS_REFV 5.0 // unit:v MCU VCC must be 5.0V or 3.3V
- #define SYSCLK_HSI_60MHz 60000000 // unit:Hz
- #define PWMFREQ 16000 // unit:Hz
- #define DEAD_TIME 1.0 // unit:us determined by Hardware parameter
- #define SLOWLOOP_FREQ 1000 // unit:Hz
- /*Board parameter setting*/
- // Current Sampling
- #define ADC_REFV SYS_REFV
- #define R_SHUNT (0.05) // unit:ohm
- #define CURRENT_OPA_GAIN (5.00) // OPA_GAIN
- #define I_MAX (ADC_REFV/2/CURRENT_OPA_GAIN/R_SHUNT) // unit:A Max current of Hardware
- // Voltage Sampling
- #define UDC_MAX (55.0) // unit:V Max DC Voltage of Hardware
- #define U_MAX (UDC_MAX/1.732) // unit:V Max Voltage
- #define DCBUS_OVER (30.0) // unit:V if DC Bus voltage over this, it will stop motor
- #define DCBUS_UNDER (15.0) // unit:V if DC Bus voltage under this, it will stop motor
- /*State machine setting*/
- // PreCharge stage
- #define PRECHARGE_TIME 100 // unit:ms precharge time setup
- #define STOP_TO_RUN_SPEED 500.0 // unit:RPM if speed command higher this, Switch from Stop to Run state
- #define STARTUP_TO_SPIN_SPEED 400.0 // unit:RPM if actual speed higher this, Switch from Startup to Spin state
- #define FREEWHEEL_SPEED 400.0 // unit:RPM if speed command lower this, Switch to Freewheel state
- // Align state
- #define IQ_ALIGN 1.0 // unit:A q axis current for align
- #define ALIGN_CURRENT_RAMP 1.0 // unit:A/s ramp of align current
- #define ALIGN_TIME 1.0 // unit:s align time
- // Startup state
- #define IQ_STARTUP 1.0 // unit:A q axis current for startup
- #define MAXSTARTUP_SPEED 500.0 // unit:RPM max startup speed
- #define STARTUP_SPEED_RAMP 500.0 // unit:RPM/s ramp of startup speed
- #define SPEED_TO_THETA Q15(2*SPEED_MAX*POLEPAIRS/60.0/PWMFREQ) //unit: speed to theta Integral constant
- #define STARTUP_TIME 1.0 // unit:s
- // run state
- #define RAMP_UP 1000.0 // RPM/s ramp of speed command increase
- #define RAMP_DOWN 1000.0 // RPM/s ramp of speed command decrease
- // freewheel state
- #define FREEWHEEL_TIME 5.0 // unit:s freewheel time
- #define FAULTRELEASE_TIME 20.0 // unit:s fault release time
- /*motor releated paremeter setting*/
- //Motor parameter
- #define Rs 0.5 // unit:ohm
- #define Ls 0.001 // unit:H
- #define POLEPAIRS 2.0 // unit
- #define SPEED_MAX (5000.0) // unit:rpm max speed of motor
- #define MAX_DUTY (0.92) // unit
- #define D_PI_LIMIT (14.0) // unit:V Vd PI output limitation
- #define Q_PI_LIMIT (14.0) // unit:V Vq PI output limitation
- #define SPD_PI_LIMIT (3.0) // unit:A Speed PI output limitation
- // CURRENT LOOP PI PARAMETER
- #define M1_IQ_KP Q15(0.87) // KP Value of Q-axis Current loop
- #define M1_IQ_KP_SHIFT (-5) // KP Shift Value of Q-axis Current loop
- #define M1_IQ_KI Q15(0.88) // KI Value of Q-axis Current loop
- #define M1_IQ_KI_SHIFT (-7) // KI Shift Value of Q-axis Current loop
- #define M1_ID_KP Q15(0.87) // KP Value of D-axis Current loop
- #define M1_ID_KP_SHIFT (-5) // KP Shift Value of D-axis Current loop
- #define M1_ID_KI Q15(0.88) // KI Value of D-axis Current loop
- #define M1_ID_KI_SHIFT (-7) // KI Shift Value of D-axis Current loop
- // SPEED LOOP PI PARAMETER
- #define M1_SPEED_KP Q15(0.6) // KP Value of speed loop
- #define M1_SPEED_KP_SHIFT (0) // KP Shift Value of speed loop
- #define M1_SPEED_KI Q15(0.5) // KI Value of speed loop
- #define M1_SPEED_KI_SHIFT (-9) // KI Shift Value of speed loop
- // SMO Observer
- #define GS_SHIFT (0) // Right Shift the Gs Value to anti overflow
- #define SMO_ERR_MAX Q15(0.3) // Max value of SMO error
- #define SLIDE_GIAN Q15(0.3) // Kslide gain value
- #define IERR_GIAN Q15(0.5) // Current gain value
- #define IERR_GIAN_SHIFT (1) // Shift Value of Current gain
- // track observer
- #define M1_TO_KP_GAIN Q15(0.6528) // KP Value of track observer
- #define M1_TO_KP_SHIFT (1) // KP Shift Value of track observer
- #define M1_TO_KI_GAIN Q15(0.988) // KI Value of track observer
- #define M1_TO_KI_SHIFT (-9) // KI Shift Value of track observer
- #define M1_TO_THETA_GAIN Q15(0.666667)// Theta gain value
- #define M1_TO_THETA_SHIFT (-5) // Theta gain shift value
复制代码
4 参数设定
首先需要在开发板选择运行模式,其中SW1和SW2是选择是无传感器还是Hall传感器
5 下载和运行
编译后下载,
如下连接,这里是无传感器的运行模式
直接上电,就可以实现电机控制和运行了。
|
-
|