无刷直流电机(BLDC)的无传感器控制技术是现代电机控制领域的重要技术方向,通过检测反电动势过零点来确定转子位置,实现无位置传感器的精确控制。本文将基于HPMicro SDK中的bldc_over_zero示例,详细介绍BLDC电机的无传感器过零控制技术,包括控制原理、软件架构和实际应用。
当BLDC电机转动时,转子永磁体在定子绕组中运动,根据法拉第电磁感应定律产生反电动势。这一现象的物理本质是磁通量的时间变化率:

其中:
三相反电动势表达式:
对于理想的三相BLDC电机,三相反电动势具有120°相位差:

其中
为反电动势幅值。
反电动势常数的物理意义:
反电动势常数 Ke 与电机的物理结构密切相关:

其中:
N 为每相串联导体数
悬浮相电压的构成:
在三相BLDC电机的六步换相控制中,任意时刻都有一相处于悬浮状态(未导通)。该相的端电压由反电动势和中性点电压共同决定:

中性点电压的计算:
理论上,三相中性点电压为:

但在实际系统中,无法直接测量中性点电压。HPM MCL库采用"虚拟中性点"方法,通过导通两相的电压均值来估算:

过零点的数学条件:
当悬浮相反电动势过零时:

即:

30度延迟的理论依据:
过零点对应转子磁极轴线与定子绕组轴线垂直的瞬间,此时转子位于两个换相点的中间位置。为获得最大转矩,需要在过零点后延迟30°电角度再进行换相:

对应的时间延迟为:

其中
为上一次换相间隔时间。
换相序列的磁场原理:
六步换相控制的本质是在定子中产生旋转磁场,与转子永磁体相互作用产生转矩。每个换相步骤对应60°电角度的磁场位置:

换相序列与过零检测的对应关系:

磁通链与转矩分析:
在每个换相区间内,转矩可表示为:

其中:
为获得最大转矩,需要保持θe − θi = 90°,这正是 30° 延迟换相的理论依据。

系统使用hpm_mcl_over_zero_cfg_t结构体封装过零控制相关数据:
typedef struct hpm_mcl_over_zero_cfg { int32_t adc_u; // U相ADC采样值 int32_t adc_v; // V相ADC采样值 int32_t adc_w; // W相ADC采样值 uint32_t number_consecutive_zeros; // 连续过零次数 uint32_t delay_degree_30; // 30度延迟值 uint32_t interval_tick; // 换相间隔时间 hpm_mcl_dir_t motor_dir; // 电机方向 hpm_mcl_over_zero_interval_t next_interval; // 下一换相区间 uint8_t pole_num; // 极对数 float loop_time_in_sec; // 控制周期 hpm_mcl_over_zero_fsm_t fsm; // 状态机} hpm_mcl_over_zero_cfg_t;
电机物理参数:
sensorless_cfg.pole_num = MOTOR0_POLE_PAIR; // 极对数:2sensorless_cfg.loop_time_in_sec = 0.0001; // 控制周期:100μssensorless_cfg.motor_dir = motor_dir; // 电机方向
PI控制器参数:
pi_para.kp = PI_P_VAL; // 比例系数:124pi_para.ki = PI_I_VAL; // 积分系数:0.15pi_para.integral_max = PI_PWM_OUT_MAX; // 积分限幅pi_para.output_max = PI_PWM_OUT_MAX; // 输出限幅
速度滤波参数:
speed_para.filter_coef = 0.0304; // 滤波系数(100Hz)speed_para.kp = 0.2814; // 速度环比例系数speed_para.ki = 0.0145; // 速度环积分系数
ADC用于采集三相电压信号,实现反电动势检测:
void adc_init(void){ adc_config_t cfg; adc_channel_config_t ch_cfg; // ADC基本配置 cfg.module = BOARD_BLDC_ADC_MODULE; #if BOARD_BLDC_ADC_MODULE == ADCX_MODULE_ADC12 cfg.config.adc12.res = adc12_res_12_bits; // 12位分辨率 cfg.config.adc12.conv_mode = adc12_conv_mode_preemption; // 抢占模式 cfg.config.adc12.adc_clk_div = 2; // 时钟分频 #else cfg.config.adc16.res = adc16_res_16_bits; // 16位分辨率 cfg.config.adc16.conv_mode = adc16_conv_mode_preemption; // 抢占模式 cfg.config.adc16.adc_clk_div = adc16_clock_divider_4; // 时钟分频 #endif // 初始化三相ADC hpm_adc_init(&cfg);}
ADC触发配置:
void init_trigger_cfg(uint8_t trig_ch, bool inten){ adc_pmt_config_t pmt_cfg; pmt_cfg.config.adc12.trig_ch = trig_ch; // 触发通道 pmt_cfg.config.adc12.trig_len = BOARD_BLDC_ADC_PHASE_PREEMPT_TRIG_LEN; pmt_cfg.config.adc12.adc_ch[0] = BOARD_BLDC_ADC_PHASE_CH_U; // U相通道 pmt_cfg.config.adc12.adc_ch[1] = BOARD_BLDC_ADC_PHASE_CH_V; // V相通道 pmt_cfg.config.adc12.adc_ch[2] = BOARD_BLDC_ADC_PHASE_CH_W; // W相通道 hpm_adc_set_preempt_config(&pmt_cfg);}
PWM负责产生六步换相所需的驱动信号:
PWM模块初始化:
void pwm_init(void){ pwm_cmp_config_t cmp_config[3] = {0}; pwm_config_t pwm_config = {0}; // 停止PWM计数器 pwm_stop_counter(MOTOR0_BLDCPWM); // 设置PWM重载值 pwm_set_reload(MOTOR0_BLDCPWM, 0, PWM_RELOAD); pwm_set_start_count(MOTOR0_BLDCPWM, 0, 0); // 配置比较器 cmp_config[0].mode = pwm_cmp_mode_output_compare; cmp_config[0].cmp = PWM_RELOAD >> 1; // 50%占空比 cmp_config[0].update_trigger = pwm_shadow_register_update_on_shlk; // PWM输出配置 pwm_config.enable_output = true; pwm_config.dead_zone_in_half_cycle = 0; // 无死区时间 pwm_config.invert_output = false; // 配置所有PWM通道 pwm_setup_waveform(MOTOR0_BLDCPWM, BOARD_BLDC_UH_PWM_OUTPIN, &pwm_config, cmp_index, cmp_config, 2); // ... 其他五个通道配置}
关键配置参数说明:
定时器用于控制算法的周期执行:
void timer_init(void){ gptmr_channel_config_t config; // 时钟配置 clock_add_to_group(BOARD_BLDC_TMR_CLOCK, 0); gptmr_channel_get_default_config(BOARD_BLDC_TMR_1MS, &config); // 定时器参数配置 config.reload = SENSORLESS_TMR_RELOAD + 1; // 重载值 config.cmp[0] = SENSORLESS_TMR_RELOAD; // 比较值 // 使能中断 gptmr_enable_irq(BOARD_BLDC_TMR_1MS, GPTMR_CH_CMP_IRQ_MASK(BOARD_BLDC_TMR_CH, BOARD_BLDC_TMR_CMP)); gptmr_channel_config(BOARD_BLDC_TMR_1MS, BOARD_BLDC_TMR_CH, &config, true); intc_m_enable_irq_with_priority(BOARD_BLDC_TMR_IRQ, 1);}
定时器参数计算:

系统采用状态机管理过零控制流程:

状态定义:
typedef enum { hpm_mcl_over_zero_fsm_init = 0, // 初始化状态 hpm_mcl_over_zero_fsm_location = 1, // 定位状态 hpm_mcl_over_zero_fsm_running = 2 // 运行状态} hpm_mcl_over_zero_fsm_t;
步骤1:硬件初始化
board_init(); // 板级初始化motor_clock_hz = clock_get_frequency(BOARD_BLDC_QEI_CLOCK_SOURCE);init_pwm_pins(MOTOR0_BLDCPWM); // PWM引脚初始化init_motor_over_zero_sensorless_adc_pins(); // ADC引脚初始化
步骤2:外设初始化
pwm_init(); // PWM初始化adc_init(); // ADC初始化timer_init(); // 定时器初始化
步骤3:控制参数初始化
init_over_zero_para(&sensorless_cfg); // 过零控制参数初始化
// 主循环:速度变化控制while (1) { motor_run = true; if (isadd) { user_setspeed++; // 加速 } else { user_setspeed--; // 减速 } board_delay_ms(100);}// 定时器中断:控制算法执行void isr_gptmr(void){ step_delay = hpm_mcl_over_zero_step_get(&sensorless_cfg); // 获取换相步骤 if (motor_run == true) { speed_para.speed = hpm_mcl_over_zero_cal_speed(&sensorless_cfg); // 计算速度 current_speed = hpm_mcl_over_zero_speed_filter(&speed_para); // 速度滤波 pi_para.target = user_setspeed; // 设置目标速度 pi_para.cur = current_speed; // 当前速度 hpm_mcl_over_zero_pi_contrl(&pi_para); // PI控制 block_pwm_out = pival_to_pwmoutput(pi_para.outval); // 转换为PWM输出 bldc_block_motor0_duty_set(block_pwm_out); // 设置PWM占空比 hpm_mcl_over_zero_pwm_ctrl(BLDC_MOTOR0_INDEX, step_delay); // PWM控制输出 }}
虚拟中性点计算方法:
HPM MCL库采用创新的虚拟中性点方法,简化了过零检测的复杂度:
// 核心检测函数中的关键代码int8_t hpm_mcl_over_zero_step_get(hpm_mcl_over_zero_cfg_t *cfg){ int32_t adc_over_zero_u, adc_over_zero_v, adc_over_zero_w; // 计算三相虚拟中性点电压 adc_over_zero_u = (cfg->adc_w + cfg->adc_v) >> 1; // U相过零检测用 adc_over_zero_v = (cfg->adc_w + cfg->adc_u) >> 1; // V相过零检测用 adc_over_zero_w = (cfg->adc_u + cfg->adc_v) >> 1; // W相过零检测用}
检测原理解析:
的符号变化
case hpm_mcl_over_zero_fsm_init: cfg->last_interval = hpm_mcl_interval_init; cfg->delay_degree_30 = 0; cfg->number_consecutive_zeros_w = 0; cfg->adc_zero_ph = 0; // 过零检测阶段标志 cfg->last_interval_tick = 0; cfg->number_consecutive_zeros = 0; cfg->interval_tick = 0; cfg->speed_tick = 0; cfg->interval = hpm_mcl_interval_init; cfg->fsm = hpm_mcl_over_zero_fsm_location; // 转入定位状态 break;
初始化的关键参数:
定位阶段采用三阶段验证机制,确保初始转子位置检测的可靠性:
case hpm_mcl_over_zero_fsm_location: adc_over_zero_w = (cfg->adc_u + cfg->adc_v) >> 1; // 计算W相虚拟中性点 if (cfg->adc_zero_ph == 0) { // 第一阶段:等待W相反电动势从负变正 if (adc_over_zero_w - cfg->adc_w > 0) { cfg->number_consecutive_zeros_w++; if (cfg->number_consecutive_zeros_w > HPM_OVER_ZERO_INIT_FILTER_TIMES) { cfg->adc_zero_ph = 1; // 进入第二阶段 cfg->number_consecutive_zeros_w = 0; } } else { cfg->number_consecutive_zeros_w = 0; return -1; // 继续等待 } } else if (cfg->adc_zero_ph == 1) { // 第二阶段:再次检测过零,确保稳定 if (adc_over_zero_w - cfg->adc_w > 0) { cfg->number_consecutive_zeros_w++; if (cfg->number_consecutive_zeros_w > HPM_OVER_ZERO_INIT_FILTER_TIMES) { cfg->adc_zero_ph = 2; // 进入第三阶段 } } else { cfg->number_consecutive_zeros_w = 0; return -1; } } else if (cfg->adc_zero_ph == 2) { // 第三阶段:定位完成,设置初始换相区间 cfg->last_interval = hpm_mcl_interval_w_down; cfg->interval = cfg->last_interval; cfg->next_interval = hpm_mcl_interval_w_down; // 根据电机方向设置下一个换相区间 if (cfg->motor_dir == hpm_motor_dir_forward) { cfg->next_interval = (cfg->interval % 6) + 1; } else { cfg->next_interval -= 1; if (cfg->next_interval == 0) { cfg->next_interval = hpm_mcl_interval_u_up; } } cfg->fsm = hpm_mcl_over_zero_fsm_running; // 转入运行状态 } break;
定位算法的关键特点:
运行状态是核心算法,实现六步换相的过零检测:
case hpm_mcl_over_zero_fsm_running: cfg->interval_tick++; // 换相间隔计时 cfg->delay_degree_30++; // 30度延迟计时 // 计算三相虚拟中性点 adc_over_zero_u = (cfg->adc_w + cfg->adc_v) >> 1; adc_over_zero_v = (cfg->adc_w + cfg->adc_u) >> 1; adc_over_zero_w = (cfg->adc_u + cfg->adc_v) >> 1; // 根据当前区间和电机方向进行过零检测 switch (HPM_OVER_ZERO_INDEX_GET(cfg->next_interval, cfg->motor_dir)) { case HPM_OVER_ZERO_INDEX_GET(hpm_mcl_interval_w_down, hpm_motor_dir_forward): if (adc_over_zero_w - cfg->adc_w > 0) { // W相从负过零到正 cfg->number_consecutive_zeros++; } else { cfg->number_consecutive_zeros = 0; } break; case HPM_OVER_ZERO_INDEX_GET(hpm_mcl_interval_w_up, hpm_motor_dir_forward): if (adc_over_zero_w - cfg->adc_w < 0) { // W相从正过零到负 cfg->number_consecutive_zeros++; } else { cfg->number_consecutive_zeros = 0; } break; // ... 其他五个区间的检测逻辑 } // 过零检测成功处理 if (cfg->number_consecutive_zeros >= HPM_OVER_ZERO_FILTER_TIMES) { cfg->number_consecutive_zeros = 0; cfg->last_interval_tick = cfg->interval_tick; // 保存上次换相间隔 cfg->interval_tick = 0; // 重置计数器 cfg->delay_degree_30 = HPM_OVER_ZERO_FILTER_TIMES; // 设置30度延迟 // 计算下一个换相区间 if (cfg->motor_dir == hpm_motor_dir_forward) { cfg->next_interval = (cfg->interval % 6) + 1; } else { cfg->next_interval -= 1; if (cfg->next_interval == 0) { cfg->next_interval = hpm_mcl_interval_u_up; } } } // 30度延迟判断和换相执行 if (cfg->delay_degree_30 > (cfg->last_interval_tick >> 1)) { cfg->speed_tick = cfg->last_interval_tick; // 保存速度计算用数据 cfg->interval = cfg->next_interval; // 执行换相 } break;
运行状态的关键算法:
1. 双重计时器机制:
2. 过零检测的数学条件:
ParseError: KaTeX parse error: Expected & or \\ or \cr or \end at end of input: …erval\_tick}{2}
理论基础与数学推导:
基于换相间隔时间计算电机转速的数学模型:
转换为每分钟转数(rpm):
转换为每秒转数(rps):
HPM MCL库的实际实现:
float hpm_mcl_over_zero_cal_speed(hpm_mcl_over_zero_cfg_t *cfg){ // 原始实现:基于换相间隔计算转速 return ((float)((60.0f / cfg->pole_num) / 360.0f))/(cfg->loop_time_in_sec * (cfg->speed_tick + 1));}
算法分析与优化:
单位统一化:

其中:
精度优化技巧:
速度计算的时序分析:
这种设计确保了速度计算的实时性和准确性。
双环PI控制系统架构:
HPM MCL实现了双层PI控制系统:外环PI控制器 + 内环PWM输出控制。
外环:速度PI控制器:
float hpm_mcl_over_zero_speed_filter(hpm_mcl_over_zero_spd_para_t *par){ float portion_asp = 0; float portion_asi = 0; // 低通滤波器预处理 par->err = par->speed - par->speedout; par->err_last = par->filter_coef * par->err + (1 - par->filter_coef) * par->err_last; // PI控制计算 portion_asp = par->kp * par->err_last; // 比例项 portion_asi = par->ki * par->err_last; // 积分项 portion_asi += par->mem; // 积分累加 // 积分限幅 if (portion_asi > par->integral_max) { portion_asi = par->integral_max; } else if (portion_asi < par->integral_min) { portion_asi = par->integral_min; } par->mem = portion_asi; // 组合PI输出 portion_asi += portion_asp; // 输出限幅 if (portion_asi > par->output_max) { portion_asi = par->output_max; } else if (portion_asi < par->output_min) { portion_asi = par->output_min; } par->speedout = portion_asi; return par->speedout;}
内环:PWM占空比PI控制器:
float hpm_mcl_over_zero_pi_contrl(hpm_mcl_over_zero_pi_para_t *par){ float result = 0; float curerr = 0; float portion_asp = 0; float portion_asi = 0; curerr = par->target - par->cur; // 计算误差 portion_asp = curerr * par->kp; // 比例项 portion_asi = curerr * par->ki + par->mem; // 积分项 // 积分限幅(防止积分饱和) if (portion_asi < par->integral_min) { portion_asi = par->integral_min; } else if (portion_asi > par->integral_max) { portion_asi = par->integral_max; } par->mem = portion_asi; // PI输出组合 result = portion_asi + portion_asp; // 输出限幅(防止PWM超出范围) if (result < par->output_min) { result = par->output_min; } else if (result > par->output_max) { result = par->output_max; } par->outval = result; return result;}
PI控制器的高级特性分析:

控制参数的自适应调优:
系统在实际应用中采用了经验参数:
// 速度环PI参数speed_para.kp = 0.2814; // 比例系数speed_para.ki = 0.0145; // 积分系数speed_para.integral_max = 1000; // 积分上限speed_para.integral_min = -1000; // 积分下限// PWM环PI参数pi_para.kp = PI_P_VAL; // 124pi_para.ki = PI_I_VAL; // 0.15pi_para.integral_max = PI_PWM_OUT_MAX; // PWM最大值pi_para.integral_min = -PI_PWM_OUT_MAX; // PWM最小值
这些参数通过大量实验优化,可以在大多数BLDC电机上直接使用。
滤波系统的分层设计:
HPM MCL采用多级滤波架构,提高系统的抗干扰能力:
连续性验证滤波器:
这是一种独特的数字滤波方法,通过计数器实现:
// 运行状态下的滤波参数#define HPM_OVER_ZERO_FILTER_TIMES 5// 初始化状态下的滤波参数#define HPM_OVER_ZERO_INIT_FILTER_TIMES 15// 滤注逻辑:只有连续检测到相同结果才认为有效if (zero_crossing_detected) { cfg->number_consecutive_zeros++; if (cfg->number_consecutive_zeros >= HPM_OVER_ZERO_FILTER_TIMES) { // 过零检测有效 trigger_commutation(); }} else { cfg->number_consecutive_zeros = 0; // 重置计数器}
传递函数分析:
连续性验证滤波器的传递函数可表示为:

其中NN为连续检测次数。
数字低通滤波器:
在速度环中集成的IIR低通滤波器:

截止频率计算:
滚动均值滤波器的截止频率为:


这接近于设计目标的100Hz。
滤波器的性能优化:
滤波器的实际效果:
换相序列与过零检测的对应关系:
HPM MCL库的六步换相序列实现了精确的PWM控制逻辑:

HPM MCL的PWM控制函数实现:
void hpm_mcl_over_zero_pwm_ctrl(uint8_t motorindex, uint8_t step){ switch (step) { case 2: // UH+WL:U相上桥导通,W相下桥导通,V相悬浮 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UL); // U相下桥关闭 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VH); // V相上桥关闭 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VL); // V相下桥关闭 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WH); // W相上桥关闭 hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_UH); // U相上桥导通 hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_WL); // W相下桥导通 break; case 1: // UH+VL:U相上桥导通,V相下桥导通,W相悬浮 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_UH); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_VL); break; case 6: // VL+WH:V相下桥导通,W相上桥导通,U相悬浮 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_VL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_WH); break; case 5: // UL+WH:U相下桥导通,W相上桥导通,V相悬浮 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_UL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_WH); break; case 4: // UL+VH:U相下桥导通,V相上桥导通,W相悬浮 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_UL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_VH); break; case 3: // VH+WL:V相上桥导通,W相下桥导通,U相悬浮 hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WH); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_WL); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_VH); break; }}
PWM强制输出的底层实现:
void hpm_mcl_bldc_pwm_enable(uint8_t motor_index, uint8_t pin_name){ motor_index -= 1; // 转换为数组索引 #if defined(HPMSOC_HAS_HPMSDK_PWM) pwm_disable_pwm_sw_force_output(motor_pwm_tbl[motor_index], pwm_uvw_conversion_tbl[motor_index][pin_name]); #endif #if defined(HPMSOC_HAS_HPMSDK_PWMV2) pwmv2_disable_software_force(motor_pwm_tbl[motor_index], pwm_uvw_conversion_tbl[motor_index][pin_name]); #endif}void hpm_mcl_bldc_pwm_disable(uint8_t motor_index, uint8_t pin_name){ motor_index -= 1; #if defined(HPMSOC_HAS_HPMSDK_PWM) pwm_enable_pwm_sw_force_output(motor_pwm_tbl[motor_index], pwm_uvw_conversion_tbl[motor_index][pin_name]); #endif #if defined(HPMSOC_HAS_HPMSDK_PWMV2) pwmv2_enable_software_force(motor_pwm_tbl[motor_index], pwm_uvw_conversion_tbl[motor_index][pin_name]); #endif}
引脚映射表的实现:
const uint8_t pwm_uvw_conversion_tbl[4][6] = { { BOARD_BLDC_UH_PWM_OUTPIN, // U相上桥引脚 BOARD_BLDC_UL_PWM_OUTPIN, // U相下桥引脚 BOARD_BLDC_VH_PWM_OUTPIN, // V相上桥引脚 BOARD_BLDC_VL_PWM_OUTPIN, // V相下桥引脚 BOARD_BLDC_WH_PWM_OUTPIN, // W相上桥引脚 BOARD_BLDC_WL_PWM_OUTPIN // W相下桥引脚 }};
换相序列的数学模型:
每个换相步骤对应的磁场矢量可表示为:

方向控制的实现:
HPM MCL支持双向运行,通过改变换相序列实现:
// 正向运行:1→2→3→4→5→6→1...if (cfg->motor_dir == hpm_motor_dir_forward) { cfg->next_interval = (cfg->interval % 6) + 1;} // 反向运行:6→5→4→3→2→1→6...else { cfg->next_interval -= 1; if (cfg->next_interval == 0) { cfg->next_interval = hpm_mcl_interval_u_up; // 6 }}
换相时序的精确控制:
HPM MCL实现了精确的换相时序控制:

这种设计确保了换相的实时性和准确性,同时避免了换相过程中的竞态条件。
HPM MCL过零控制的完整执行流程:

性能特点总结:
void isr_adc(void){ uint32_t status = hpm_adc_get_status_flags(&hpm_adc_u); if ((status & BOARD_BLDC_ADC_PHASE_TRIG_FLAG) != 0) { hpm_adc_clear_status_flags(&hpm_adc_u, BOARD_BLDC_ADC_PHASE_TRIG_FLAG); // 获取三相ADC采样值 sensorless_cfg.adc_u = ((adc_buff[0][BOARD_BLDC_ADC_PHASE_TRG * 4] & 0xffff) >> 4) & 0xfff; sensorless_cfg.adc_v = ((adc_buff[0][BOARD_BLDC_ADC_PHASE_TRG * 4 + 1] & 0xffff) >> 4) & 0xfff; sensorless_cfg.adc_w = ((adc_buff[0][BOARD_BLDC_ADC_PHASE_TRG * 4 + 2] & 0xffff) >> 4) & 0xfff; }}
ADC中断在每个PWM周期触发一次,采集三相电压信号用于过零检测。
void isr_gptmr(void){ if (gptmr_check_status(BOARD_BLDC_TMR_1MS, GPTMR_CH_CMP_IRQ_MASK(BOARD_BLDC_TMR_CH, BOARD_BLDC_TMR_CMP))) { gptmr_clear_status(BOARD_BLDC_TMR_1MS, GPTMR_CH_CMP_IRQ_MASK(BOARD_BLDC_TMR_CH, BOARD_BLDC_TMR_CMP)); // 获取换相步骤 step_delay = hpm_mcl_over_zero_step_get(&sensorless_cfg); if (motor_run == true) { timer_times++; if (timer_times >= TIMER_TIMES_1MS) { timer_times = 0; // 速度计算和控制 speed_para.speed = hpm_mcl_over_zero_cal_speed(&sensorless_cfg); current_speed = hpm_mcl_over_zero_speed_filter(&speed_para); // PI控制 pi_para.target = user_setspeed; pi_para.cur = current_speed; hpm_mcl_over_zero_pi_contrl(&pi_para); // PWM输出 block_pwm_out = pival_to_pwmoutput(pi_para.outval); bldc_block_motor0_duty_set(block_pwm_out); } } // PWM控制输出 if (motor_run == true) { hpm_mcl_over_zero_pwm_ctrl(BLDC_MOTOR0_INDEX, step_delay); } }}
定时器中断执行核心控制算法,周期为100μs。
无传感器控制采用六步换相方式,每60°电角度换相一次:
void hpm_mcl_over_zero_pwm_ctrl(uint8_t motorindex, uint8_t step){ switch (step) { case 1: // AH+BL: A相上桥导通,B相下桥导通 hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_UH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_UL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_VH); hpm_mcl_bldc_pwm_enable(motorindex, BLDC_PWM_PIN_VL); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WH); hpm_mcl_bldc_pwm_disable(motorindex, BLDC_PWM_PIN_WL); break; case 2: // AH+CL: A相上桥导通,C相下桥导通 // ... 类似配置 break; // ... 其他步骤 }}
系统通过调整PWM占空比实现速度控制:
void bldc_block_motor0_duty_set(uint32_t duty){ #if defined(HPMSOC_HAS_HPMSDK_PWM) pwm_update_raw_cmp_central_aligned(MOTOR0_BLDCPWM, BOARD_BLDCPWM_CMP_INDEX_0, BOARD_BLDCPWM_CMP_INDEX_1, (PWM_RELOAD - duty) >> 1, (PWM_RELOAD + duty) >> 1); pwm_issue_shadow_register_lock_event(MOTOR0_BLDCPWM); #endif #if defined(HPMSOC_HAS_HPMSDK_PWMV2) pwmv2_shadow_register_unlock(MOTOR0_BLDCPWM); pwmv2_set_shadow_val(MOTOR0_BLDCPWM, (BOARD_BLDCPWM_CMP_INDEX_0 + 1), (PWM_RELOAD - duty) >> 1, 0, false); pwmv2_set_shadow_val(MOTOR0_BLDCPWM, (BOARD_BLDCPWM_CMP_INDEX_1 + 1), (PWM_RELOAD + duty) >> 1, 0, false); pwmv2_shadow_register_lock(MOTOR0_BLDCPWM); #endif}
当需要关闭特定相的输出时,使用强制输出模式:
void hpm_mcl_bldc_pwm_disable(uint8_t motor_index, uint8_t pin_name){ motor_index -= 1; #if defined(HPMSOC_HAS_HPMSDK_PWM) pwm_enable_pwm_sw_force_output(motor_pwm_tbl[motor_index], pwm_uvw_conversion_tbl[motor_index][pin_name]); #endif #if defined(HPMSOC_HAS_HPMSDK_PWMV2) pwmv2_enable_software_force(motor_pwm_tbl[motor_index], pwm_uvw_conversion_tbl[motor_index][pin_name]); #endif}
步骤1:参数配置
根据实际电机参数修改以下定义:
#define MOTOR0_POLE_PAIR (2) // 电机极对数#define PWM_FREQUENCY (20000) // PWM频率20kHz#define PI_P_VAL (124) // PI比例系数#define PI_I_VAL (0.15) // PI积分系数
步骤2:编译下载
使用支持的IDE编译工程并下载到目标板。
步骤3:运行测试
系统启动后会自动进行预定位,然后开始速度测试。
问题1:电机无法启动
问题2:速度不稳定
问题3:换相不平滑
PI参数调整:

滤波器参数:

提高启动成功率:
提高运行稳定性:
步骤1:板级定义修改
// ADC相关定义#define BOARD_BLDC_ADC_PHASE_U_BASE HPM_ADC0 // U相ADC#define BOARD_BLDC_ADC_PHASE_V_BASE HPM_ADC1 // V相ADC#define BOARD_BLDC_ADC_PHASE_W_BASE HPM_ADC2 // W相ADC#define BOARD_BLDC_ADC_PHASE_CH_U (5U) // U相通道#define BOARD_BLDC_ADC_PHASE_CH_V (6U) // V相通道#define BOARD_BLDC_ADC_PHASE_CH_W (7U) // W相通道// PWM相关定义#define MOTOR0_BLDCPWM HPM_PWM0 // PWM模块#define BOARD_BLDC_UH_PWM_OUTPIN (0U) // U相上桥臂#define BOARD_BLDC_UL_PWM_OUTPIN (1U) // U相下桥臂// ... 其他引脚定义
步骤2:引脚配置
void init_motor_over_zero_sensorless_adc_pins(void){ // 配置ADC输入引脚 // 设置引脚复用功能为ADC // 配置引脚特性(如输入阻抗等)}
基本参数修改:
void init_over_zero_para(hpm_mcl_over_zero_cfg_t *cfg){ cfg->pole_num = MOTOR0_POLE_PAIR; // 根据电机极对数修改 cfg->loop_time_in_sec = 0.0001; // 控制周期,根据定时器频率 // 速度滤波参数(根据电机特性调整) speed_para.filter_coef = 0.0304; // 滤波系数 speed_para.kp = 0.2814; // 速度环P参数 speed_para.ki = 0.0145; // 速度环I参数 // PI控制器参数(根据负载特性调整) pi_para.kp = PI_P_VAL; // 比例系数 pi_para.ki = PI_I_VAL; // 积分系数}
电压检测电路要求:
典型检测电路:

电气安全
启动安全
运行安全

适合无传感器控制的应用:
不适合的应用:
BLDC无传感器过零控制技术通过检测反电动势过零点实现转子位置估计,具有成本低、结构简单的优势。HPMicro SDK提供的bldc_over_zero示例展示了完整的实现方案,包括:
主要技术特点:
在实际应用中,开发者需要根据具体的电机参数和应用需求,对控制参数进行优化调整,以获得最佳的控制性能。通过本文提供的详细分析和指导,可以快速掌握无传感器过零控制技术,并成功应用到实际项目中。
全部0条评论
快来发表一下你的评论吧 !