esp_sensorless_bldc_control 比较器反电势过零检测与六步换相源码解读 esp_sensorless_bldc_control 比较器反电势过零检测与六步换相源码解读【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution这篇文章以 esp-iot-solution 仓库中的esp_sensorless_bldc_control组件为对象讲清基于硬件比较器检测反电动势BEMF过零点的无感方波电机控制方案先给出过零信号的物理来源与虚拟中性点技巧再走读三路比较器硬件电路然后按采样、滤波、测速、状态映射四个机制逐段读源码最后覆盖接线、bldc_user_cfg.h配置与闭环启动的完整流程并附上典型故障现象的排查对照。跟着走读完成后你可以基于仓库自带测试用例独立完成比较器三路接线、参数调整与无感闭环启动。一、快速总览条目内容核心概念比较器输出过零电平判断转子位置硬件门槛三路比较器、等阻网络、三个输入 GPIO适用场景低成本无感方波驱动、无霍尔电机关键文件comparer.c 与 six_step.c该方案是组件内与ALIGNMENT_ADCADC 采样并列的另一种无感模式通过配置项ALIGNMENT_COMPARER启用。两者共用同一套六步换相框架区别只在过零信号的产生与确认方式。二、原理走读过零信号从哪来反电势幅值与转速成正比方波驱动的 BLDC 电机任意时刻只有两相导通一相接正、一相接负第三相浮空。浮空相绕组没有电流其端电压主要就是反电动势因此浮空相是检测转子位置的最佳窗口。反电势的物理来源是绕组切割转子磁场按楞次定律其极性总是阻碍电流变化BEMF NlrBω符号含义N绕组匝数l转子导条有效长度r转子内半径B转子磁场强度ω转子角速度电机下线后 N、l、r、B 都是定值所以反电势幅值只与角速度 ω 成正比。这直接决定了两个工程事实转速越快过零检测越可靠转速过低时反电势弱到淹没在噪声里必须先靠对齐ALIGNMENT和强拖DRAG把转速拉起来过零信号才稳定可用。图中每个 60° 电角度发生一次换相换相后新浮空相的反电势在半周期内穿越中点这个穿越点就是比较器要捕捉的过零点。关键技巧等阻电阻重构虚拟中性点判断过零需要比较端电压与中性点电压谁大但星形接法的电机通常不引出中性点无法直接测量。比较器方案的做法是用相同阻值的电阻把三相拉到公共点该公共点电压近似等于真实中性点称为虚拟中性点。每相端电压与虚拟中性点各接一路比较器的输入比较器输出高低电平即代表该相端电压在不在中性点上方电平翻转时刻就是过零点。过零间隔与转速的数学关系浮空相反电势每半个电气周期180° 电角度穿越一次中点。设计时基准频率为 ft、电机极对数为 n、两次过零之间累计的计数值为 c则speed_rpm ft / (2 × n × c) × 60ft 是周期中断频率2×n 对应一个机械转内含有的半电气周期数。按组件默认配置MCPWM_CLK_SRC20MHz、MCPWM_PERIOD2000计时周期ALARM_COUNT_US100µsPOLE_PAIR5代入后系数为 60000即speed_rpm 60000 / speed_count。三、硬件/接口走读下左图是组件文档给出的功率侧参考三相全桥UH/VH/WH 上管、UL/VL/WL 下管驱动星形绕组母线 Udc 加在桥臂之间。下右图是信号侧每相端电压经 1K 分压电阻R25/R28、R29/R31、R32/R34接入比较器反相端等阻 20K 电阻R25 上方标注 20K 的网络合成虚拟中性点接比较器同相端输出经 100R 100nF 滤波后分别得到 BEMF_1/2/3 三路过零信号另有一路比较器U8:2用于输出端分压参考。硬件要点三路比较器支路每相一路负责把该相端电压与虚拟中性点的比较结果变成数字电平是过零信号的直接来源排查时先用示波器确认三路输出在电机转动时确有规律翻转。等阻虚拟中性点网络R28/R29/R32 等电阻必须同阻值任一路偏差都会把中性点基准拉偏导致某一相过零点系统性偏移。输出 RC 滤波100R 串联加 100nF 对地抑制 PWM 开关噪声电容过大则电平翻转滞后与软件滤波叠加会加大换相延迟。GPIO 接口三路信号接普通 GPIO组件按输入模式初始化active_level字段用于适配比较器输出极性。硬件排查顺序建议先测三路比较器输出是否随转速稳定翻转再核对等阻电阻的实测偏差建议 1% 以内最后检查输出端滤波电容取值与比较器供电、地线是否干净。四、源码机制走读同步采样MCPWM on_full 时刻的 64 位移入队列做什么MCPWM 定时器每次计数到峰值on_full 事件时把三路比较器 GPIO 电平各取一次逐位移入每相 64 位环形队列。为什么换相刚发生的窗口内端电压受续流二极管和开关噪声影响严重连续读 GPIO 会采到大量脏数据。绑定 PWM 峰值时刻采样保证每个 PWM 周期只取一个干净的样本点同时把采样节拍与 PWM 严格同步。在哪做bldc_control.c 中注册回调bldc_zero_cross_comparer.c 中实现采样// bldc_control.c: ALIGNMENT_COMPARER 分支 control-zero_cross bldc_zero_cross_comparer_operation; control-cbs-on_full read_comparer_on_full; /* 关键PWM 峰值时刻触发采样 */ config-six_step_config.upper_switch_config.bldc_mcpwm.timer_cb_user_data (void *)control-zero_cross_handle;// bldc_zero_cross_comparer.c: 每相 64 位队列左移 1 位并入当前电平 static void IRAM_ATTR alignment_comparer_get_value(bldc_zero_cross_comparer_t *zero_cross) { for (int i 0; i PHASE_MAX; i) { zero_cross-alignment_queue_value[i] zero_cross-alignment_queue_value[i] 1; zero_cross-alignment_queue_value[i] | gpio_ll_get_level(GPIO, zero_cross-alignment_pin[i]); } }怎么调采样时刻固定在 on_full无独立参数可调采样密度由MCPWM_CLK_SRC与MCPWM_PERIOD决定默认 10kHz PWM改 PWM 频率时注意队列窗口覆盖的时间随之变化。连续滤波与过零确认0xFFFF 相同样本判有效做什么把队列低 16 位与ZERO_CROSS_DETECTION_ACCURACY做按位与全 1 判该相为高、全 0 判为低、否则判滤波失败并跳过本周期处理。为什么硬件滤波后仍可能有窄脉冲噪声连续多次同电平的判决能拒绝孤立毛刺避免把噪声当过零事件触发误换相。滤波失败时filter_failed_count累加超过 15000 次会被主状态机判为堵转BLOCKED这一计数同时是信号质量的在线监测指标。在哪做bldc_zero_cross_comparer.cfor (int i 0; i PHASE_MAX; i) { if ((zero_cross-alignment_queue_value[i] ZERO_CROSS_DETECTION_ACCURACY) ZERO_CROSS_DETECTION_ACCURACY) { zero_cross-queue_filter_state[i] 1; /* 连续 16 次高电平 */ } else if ((zero_cross-alignment_queue_value[i] ZERO_CROSS_DETECTION_ACCURACY) 0) { zero_cross-queue_filter_state[i] 0; /* 连续 16 次低电平 */ } else { zero_cross-control_param-filter_failed_count; return 0; /* 滤波失败本周期不处理 */ } }怎么调ZERO_CROSS_DETECTION_ACCURACY默认0xFFFF连续 16 次相同最大0xFFFFFFFF32 次。改大会提高抗噪能力但电平确认延迟增大、换相整体后移需与ZERO_CROSS_ADVANCE联动补偿。测速与提前角补偿speed_count 折算 RPM做什么以 U 相滤波状态为基准做边沿检测检测到 1→0 下降沿时把本半周期累计的speed_count折算成转速经一阶低通后写回speed_rpm同时算出提前换向延迟filter_delay。为什么无传感器方案需要转速反馈给 PID而比较器检测到的过零点理论上是换向前 30° 电角度到来加上软件滤波滞后若立即换相角度会偏晚需要按当前转速折算出延迟量做补偿。在哪做bldc_zero_cross_comparer.c系数定义在 bldc_config.h#define COMPARER_RPM_CALCULATION_COEFFICIENT (((1000000 / ALARM_COUNT_US) / (2.0 * POLE_PAIR)) * 60) // bldc_zero_cross_comparer.c: U 相状态 1-0 下降沿处 if (filterEdge 0) { if (zero_cross-zero_stable_flag ZERO_STABLE_FLAG_CNT) { speed_rpm (uint32_t)(COMPARER_RPM_CALCULATION_COEFFICIENT / zero_cross-control_param-speed_count); BLDC_LPF(zero_cross-control_param-speed_rpm, speed_rpm, 0.2); /* 系数 0.2 低通平滑 */ } zero_cross-control_param-filter_delay zero_cross-control_param-speed_count / ZERO_CROSS_ADVANCE; }怎么调POLE_PAIR默认 5必须按电机实际极对数设置否则转速读数整体成倍偏差。ZERO_CROSS_ADVANCE默认 8提前角 180°/该值默认 22.5°略小于理论 30° 以抵消滤波滞后注释要求不小于 6改小则换相更提前过快会过冲建议用示波器对比实际与理论换相角。六种过零状态到换相动作的映射做什么滤波后的三相状态各 0/1共六种有效组合zero_cross_comparer_get_phase()输入三相状态与方向dir返回 1~6 的相位号相位号变化时bldc_six_step_turn()按方向选择对应的六步数组执行换相。为什么三相比较器电平的组合恰好唯一编码了当前转子所在的 60° 扇区查表即可把电平组合翻译成下一步该导通哪两相无需任何位置积分。在哪做相位判定在 bldc_zero_cross_comparer.c换相序列与执行在 bldc_six_step.c// bldc_zero_cross_comparer.c: 连续稳定后取相位 uint8_t phase zero_cross_comparer_get_phase(zero_cross-queue_filter_state, zero_cross-control_param-dir); if (phase 0 || phase 6) { zero_cross-control_param-error_hall_count; /* 非法组合信号质量异常 */ return 0; }// bldc_six_step.c: 正转六步序列函数指针数组 static void (*six_step_comparer_cw_array[6])(...) { bldc_six_step_UphaseH_VphaseL, /* U 上管 PWMV 下管导通 */ bldc_six_step_WphaseH_VphaseL, bldc_six_step_WphaseH_UphaseL, bldc_six_step_VphaseH_UphaseL, bldc_six_step_VphaseH_WphaseL, bldc_six_step_UphaseH_WphaseL, };方向数组的选择在 bldc_six_step.calignment_mode ALIGNMENT_COMPARER时绑定比较器专用数组否则绑定 ADC 数组。官方文档中的映射表1/0 表示该相比较器输出高于/低于虚拟中性点上开下关 / 上关下开 / 上关下关 表示该相桥臂状态正转CW序号ZERO UZERO VZERO WU 相状态V 相状态W 相状态1001上开下关上关下开上关下关2011上开下关上关下关上关下开3010上关下关上开下关上关下开4110上关下开上开下关上关下关5100上关下开上关下关上开下关6101上关下关上关下开上开下关反转CCW序号ZERO UZERO VZERO WU 相状态V 相状态W 相状态1010上关下开上开下关上关下关2110上关下开上关下关上开下关3100上关下关上关下开上开下关4101上开下关上关下开上关下关5001上开下关上关下关上关下开6011上关下关上开下关上关下开说明仓库文档 bldc_snls_comparer.rst 中两张映射表的表头三列均写作 ZERO U结合源码queue_filter_state[PHASE_MAX]为 U/V/W 三相状态数组的事实判断三列实际依次为 ZERO U、ZERO V、ZERO W上表按此呈现。怎么调方向由bldc_control_set_dir(handle, CW/CCW)设置方向设置必须与电机实际绕线一致否则会反向或无法启动调试时观察error_hall_count持续递增说明三相状态长期落在六种合法组合之外优先查硬件。五、实践三步第 1 步添加组件依赖与用户配置文件在项目根目录执行idf.py add-dependency espressif/esp_sensorless_bldc_control*把 user_cfg/bldc_user_cfg.h 复制到项目的main/目录保持文件名bldc_user_cfg.h并在main/CMakeLists.txt中追加与 test_apps/bldc_comparer/main/CMakeLists.txt 相同idf_component_get_property(bldc_lib espressif__esp_sensorless_bldc_control COMPONENT_LIB) cmake_policy(SET CMP0079 NEW) target_link_libraries(${bldc_lib} PUBLIC ${COMPONENT_LIB})验证点idf.py build通过且不再报bldc_user_cfg.h not found, must provide by user该报错由 bldc_config.h 的__has_include检查触发。第 2 步填写硬件配置结构体参考 test_comparer.cLEDC 驱动上管、GPIO 驱动下管的最小配置bldc_zero_cross_comparer_config_t zero_cross_comparer_config { .comparer_gpio[0] { .gpio_num 3, .gpio_mode GPIO_MODE_INPUT, .active_level 0 }, /* U 相过零 */ .comparer_gpio[1] { .gpio_num 46, .gpio_mode GPIO_MODE_INPUT, .active_level 0 }, /* V 相过零 */ .comparer_gpio[2] { .gpio_num 9, .gpio_mode GPIO_MODE_INPUT, .active_level 0 }, /* W 相过零 */ }; bldc_control_config_t config { .speed_mode SPEED_CLOSED_LOOP, .control_mode BLDC_SIX_STEP, .alignment_mode ALIGNMENT_COMPARER, /* 关键选择比较器过零检测 */ .six_step_config { .lower_switch_active_level 0, /* 关键下管有效电平须与驱动板一致 */ .upper_switch_config upper_switch_config, .lower_switch_config lower_switch_config, .mos_en_config.has_enable false, }, .zero_cross_comparer_config zero_cross_comparer_config, };验证点comparer_gpio[i].gpio_num与硬件上 BEMF_1/2/3 的接线一一对应active_level与比较器输出极性匹配反接时软件滤波会一直判失败。第 3 步初始化、设方向并启动bldc_control_handle_t bldc_control_handle NULL; bldc_control_init(bldc_control_handle, config); /* 初始化硬件驱动 */ bldc_control_set_dir(bldc_control_handle, CCW); /* 设置旋转方向 */ bldc_control_start(bldc_control_handle, 300); /* 以 300 RPM 启动 */验证点串口日志依次出现BLDC_CONTROL_ALIGNMENT、BLDC_CONTROL_DRAG稳定运行后打印CLOSED_LOOP事件事件名表见 bldc_control.c只停在 DRAG 不进入闭环即说明过零信号未达标。六、排障速查现象可能原因对策比较器 GPIO 长期无规律翻转进不了 DRAG 后的闭环采样支路断线、等阻电阻偏差大、比较器未供电示波器逐一确认 BEMF_1/2/3 输出核对 20K 等阻网络阻值一致性建议 1% 精度强拖正常但始终进不了 CLOSED_LOOP滤波判决长期失败filter_failed_count高先把ZERO_CROSS_DETECTION_ACCURACY调大验证仍无效则查硬件滤波电容与active_level配置闭环后运行抖动、偶尔丢步滤波深度不足窄脉冲噪声触发误换相ZERO_CROSS_DETECTION_ACCURACY从0xFFFF提到0xFFFFFFFF并同步减小ZERO_CROSS_ADVANCE补偿延迟电机反转或启动时抖一下再反着转dir与绕线方向不符或某两相线序接反对调 U/V 两相接线或bldc_control_set_dir改方向二者改其一闭环后进入 BLOCKED日志打印 BLOCKEDfilter_failed_count超 15000 被判堵转信号持续无效观察error_hall_count是否同步递增递增则为信号质量差按前两项排查硬件转速读数明显偏离实际值POLE_PAIR设置错误测速系数成倍偏差按电机铭牌极对数重设POLE_PAIR读数偏差与设置比应成反比七、关键参数速查以下宏定义在 user_cfg/bldc_user_cfg.h宏默认值作用调整方向ZERO_STABLE_FLAG_CNT4连续稳定检测到多少个过零后进入无感闭环偏大→进闭环更晚但更可靠偏小→启动段误判风险高ZERO_CROSS_DETECTION_ACCURACY0xFFFF连续多少次相同采样判为有效电平16 次偏大→抗噪强但换相延迟大需配合减小ZERO_CROSS_ADVANCE偏小→噪点易通过filter_failed_count上升ZERO_CROSS_ADVANCE8提前换向分母提前角 180°/该值要求 ≥ 6偏大→提前角变小、换相偏晚偏小→换相过提前角度过冲POLE_PAIR5电机极对数决定测速系数偏大→转速读数偏低偏小→读数偏高须按实际极对设置RAMP_DUTY_STA/RAMP_DUTY_END20% / 40%强拖起始/结束占空比DUTY_MAX为 1000偏大→启动扭矩强但易过流偏小→带载时拉不起来RAMP_TIM_STA/RAMP_TIM_END600 / 90强拖换相间隔的起/止值单位gptimer 节拍偏大→启动平滑但时间长偏小→快但带载易丢步MCPWM_CLK_SRC/MCPWM_PERIOD20MHz / 2000PWM 时钟与周期10kHz决定ALARM_COUNT_US100µs改变会同步改变测速系数与滤波窗口需整体复核SPEED_KP/SPEED_KI0.004 / 0.00015速度闭环 PID 增益偏大→跟踪快但易振荡偏小→响应迟钝、带载掉速八、延伸阅读bldc_overview.rstBLDC 结构、逆变桥与有感/无感控制方式的总览对比。bldc_snls_comparer.rst官方对比较器方案的完整说明含本文两张映射表的原始出处。esp_sensorless_bldc_control.rstINJECT/ALIGNMENT/DRAG/CLOSED_LOOP 各启动阶段的参数详解与调参提示。bldc_control.c状态机主体、事件分发与回调注册位置。bldc_zero_cross_comparer.c 与 bldc_six_step.c过零确认与六步换相的两段核心实现。test_comparer.cLEDC GPIO 与 MCPWM 两种配置的完整运行示例可直接烧录验证。比较器方案的核心链条很短等阻网络重构虚拟中性点比较器把端电压比较结果变成三路电平64 位队列滤波确认过零再查表映射成六步换相。实际调参时最关键的一条经验是加深ZERO_CROSS_DETECTION_ACCURACY滤波后务必同步减小ZERO_CROSS_ADVANCE并用示波器核对实际换相角与理论换相角换相角度并不是越提前越好。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考