无刷直流电机BLDC,无位置双闭环调速系统,Matlab/Simulink仿真全套!

张开发
2026/4/10 0:35:02 15 分钟阅读

分享文章

无刷直流电机BLDC,无位置双闭环调速系统,Matlab/Simulink仿真全套!
无刷直流电机BLDC无位置双闭环调速系统Matlab/Simulink仿真全套仿真模型包含直流源、三相逆变桥、无刷直流电机、PI控制器、反电动势测量等经典转速、电流双闭环控制。附带仿真模型和详细资料无刷直流电机BLDC的无位置传感器控制比有刷电机复杂得多核心在于如何通过算法估算转子位置。这里为你构建一套基于 Simulink 和 MATLAB S-Function 的完整仿真方案。这套代码将自动生成一个包含 转速/电流双闭环、三相逆变桥 以及基于 反电动势Back-EMF过零检测 的无位置传感器控制模型。️ BLDC无位置传感器双闭环仿真建模代码将以下代码保存为 build_bldc_sensorless.m 并运行。function build_bldc_sensorless()% 清除环境clc; clear; close all;model_name BLDC_Sensorless_DualLoop; % 如果模型存在则关闭 if bdIsLoaded(model_name) close_system(model_name, 0); end % 创建新模型 new_system(model_name); open_system(model_name); %% 1. 定义系统参数 (请在模型工作区定义) % 电机参数 Rs 2.5; % 定子电阻 (Ohm) Ls 8.5e-3; % 定子电感 (H) J 1.5e-4; % 转动惯量 (kg*m^2) B 1e-5; % 粘滞摩擦系数 P 4; % 极对数 Ke 0.05; % 反电动势常数 (V/(rad/s)) Kt 0.05; % 转矩常数 (Nm/A) % 仿真参数 Ts 1e-5; % 采样时间 Vdc 48; % 直流母线电压 % 将参数写入模型工作区 set_param(model_name, ModelWorkspace, on); params {Rs, Ls, J, B, P, Ke, Kt, Ts, Vdc}; values {Rs, Ls, J, B, P, Ke, Kt, Ts, Vdc}; for i 1:length(params) assignin(model, model_name, params{i}, values{i}); end %% 2. 搭建主电路 (Main Circuit) % --- 直流电源 --- add_block(sps/Elements/DC Voltage Source, [model_name /DC Source], ... Position, [50 300 80 330], Amplitude, Vdc); % --- 三相逆变桥 --- % 使用通用桥臂模块 add_block(sps/Power Electronics/Universal Bridge, [model_name /Inverter], ... Position, [120 250 170 380], Power electronics, MOSFET/Diode, ... Number of bridge arms, 3, Snubber resistance, 1e5, Snubber capacitance, inf); % 连接电源与逆变桥 add_line(model_name, DC Source/1, Inverter/DC); add_line(model_name, DC Source/2, Inverter/DC-); % --- BLDC 电机 --- % 注意Simulink没有直接的无位置传感器BLDC模块通常使用PMSM模块配合梯形波反电动势设置 % 或者使用自定义S-function。这里使用PMSM模块并假设其反电动势波形可配置或通过外部注入。 % 为了演示无位置控制原理我们使用 PMSM 模块并在控制算法中处理梯形波逻辑。 add_block(sps/Machines/Permanent Magnet Synchronous Machine, [model_name /BLDC Motor], ... Position, [220 250 270 380], Rotor type, Salient-pole, ... Parameterization, Standard, Rs, Rs, Ld, Ls, Lq, Ls, ... Flux linkage, Ke, J, J, B, B, P, P, Initial rotor angle, 0); % 连接逆变桥与电机 add_line(model_name, Inverter/AC~, BLDC Motor/abc); % --- 负载转矩 --- add_block(simulink/Sources/Step, [model_name /Load Torque], ... Position, [220 400 250 430], Time, 1.0, FinalValue, 0.5); add_line(model_name, Load Torque/1, BLDC Motor/Tm); %% 3. 搭建测量环节 (Measurements) % 电流测量 (从逆变器输出或电机输入端) add_block(sps/Measurements/Current Measurement, [model_name /Ia Meas], Position, [180 260 200 280]); add_block(sps/Measurements/Current Measurement, [model_name /Ib Meas], Position, [180 300 200 320]); % 不需要测Ic因为 IaIbIc0 % 电压测量 (用于无位置算法估算反电动势) add_block(sps/Measurements/Voltage Measurement, [model_name /Va Meas], Position, [180 340 200 360]); add_block(sps/Measurements/Voltage Measurement, [model_name /Vb Meas], Position, [180 380 200 400]); % 连接测量模块 add_line(model_name, Inverter/AC~, Ia Meas/1); add_line(model_name, Inverter/AC~, Ib Meas/1); add_line(model_name, Inverter/AC~, Va Meas/1); add_line(model_name, Inverter/AC~, Vb Meas/1); % 转速反馈 (理想传感器仅用于观测不参与控制) add_block(simulink/Signal Routing/Bus Selector, [model_name /Bus Selector], Position, [300 300 330 330]); add_line(model_name, BLDC Motor/m, Bus Selector/1); set_param([model_name /Bus Selector], BusObjects, [], SignalNames, wr, Te, Theta); %% 4. 搭建无位置传感器控制算法 (Sensorless Algorithm) % 创建子系统反电动势估算与换相逻辑 add_subsystem(model_name, Sensorless Observer, ... Position, [350 100 550 200]); % 在子系统内部添加 S-Function (代码见下方说明) % 注意这里用 S-Function 模拟复杂的反电动势观测器 add_block(simulink/User-Defined Functions/S-Function, [model_name /Sensorless Observer/BackEMF Observer], ... Position, [20 20 100 60], S-functionName, bldc_observer_sfun); % 输入Ia, Ib, Va, Vb, Vdc add_block(simulink/Signal Routing/Mux, [model_name /Sensorless Observer/Mux Inputs], Position, [-30 30 0 50]); add_line(model_name, Sensorless Observer/Mux Inputs/1, Sensorless Observer/BackEMF Observer/1); % 连接测量信号到观测器 add_line(model_name, Ia Meas/1, Sensorless Observer/Mux Inputs/1); add_line(model_name, Ib Meas/1, Sensorless Observer/Mux Inputs/1); add_line(model_name, Va Meas/1, Sensorless Observer/Mux Inputs/1); add_line(model_name, Vb Meas/1, Sensorless Observer/Mux Inputs/1); % 也可以输入Vdc用于计算占空比反推电压 % 输出估算角度 Theta_hat % 这里的输出将用于 Park/Clarke 变换的角度输入 %% 5. 搭建双闭环控制器 (Dual Loop Control) % --- 坐标变换 (Clarke Park) --- % 简化起见这里使用 S-Function 或自定义模块实现 Park 变换 % 假设输入为 Ia, Ib, Theta_hat - 输出 Id, Iq % --- 电流环 PI (Iq 控制转矩) --- add_block(simulink/Continuous/PI Controller, [model_name /PI Iq], ... Position, [400 250 450 290], P, 10, I, 50); % --- 转速环 PI --- add_block(simulink/Continuous/PI Controller, [model_name /PI Speed], ... Position, [250 250 300 290], P, 0.5, I, 5); % --- 给定转速 --- add_block(simulink/Sources/Step, [model_name /Speed Ref], ... Position, [100 250 150 280], Time, 0.1, FinalValue, 300(2pi/60)); % 3000 RPM % --- 连接控制回路 --- % 1. 转速误差 add_block(simulink/Math Operations/Sum, [model_name /Sum Speed], Position, [220 255 240 275], Inputs, -); add_line(model_name, Speed Ref/1, Sum Speed/1); add_line(model_name, Bus Selector/1, Sum Speed/2); % 实际转速反馈 add_line(model_name, Sum Speed/1, PI Speed/1); % 2. 转速PI输出作为电流给定 (Iq_ref) add_line(model_name, PI Speed/1, PI Iq/1); % 3. 电流环输出 - 电压给定 - SVPWM/SPWM % 这里简化为直接生成占空比信号驱动逆变桥 % 实际应包含 SVPWM 模块 add_block(simulink/Continuous/Transfer Fcn, [model_name /PWM Generator], ... Position, [500 250 550 290], Numerator, [1], Denominator, [1e-4 1]); add_line(model_name, PI Iq/1, PWM Generator/1); % 4. PWM 信号连接到逆变桥门极 % 注意Universal Bridge 需要 g1-g6 信号。 % 这里为了模型能跑通使用简化的占空比直接控制电压源模拟逆变器输出 % 或者使用 S-Function 生成 6 路 PWM。 % 为了代码简洁且能直接运行我们采用一种简化的“平均电压模型”连接方式 % 或者使用 Simulink 自带的 PWM Generator (2-Level)。 % 替换上面的 PWM Generator 为 Simulink 标准模块 delete_block([model_name /PWM Generator]); add_block(sps/Control Blocks/PWM Generator (2-Level), [model_name /PWM Gen], ... Position, [480 250 530 310], Generator mode, Space Vector PWM, ... Sample time, Ts, Frequency, 10000); add_line(model_name, PI Iq/1, PWM Gen/Modulating); add_line(model_name, PWM Gen/PL, Inverter/g); %% 6. 配置仿真求解器 set_param(model_name, StopTime, 2.0); set_param(model_name, Solver, ode23t (mod. stiff/Trapezoidal)); set_param(model_name, MaxStep, 1e-5); % 添加示波器 add_block(simulink/Sinks/Scope, [model_name /Scope], Position, [600 300 630 330]); add_line(model_name, Bus Selector/1, Scope/1); disp(BLDC 无位置传感器模型构建完成); disp(注意模型中包含一个名为 bldc_observer_sfun 的 S-Function 占位符。); disp(你需要编写该 S-Function 来实现具体的反电动势观测算法或者使用 Simulink 模块搭建观测器。);end 核心算法反电动势观测器 S-Function 代码上面的模型搭建代码中引用了一个名为 bldc_observer_sfun 的 S-Function。这是无位置控制的核心用于根据电压和电流估算转子角度。请创建一个名为 bldc_observer_sfun.m 的文件内容如下这是一个简化的观测器示例function [sys,x0,str,ts,simStateCompliance] bldc_observer_sfun(t,x,u,flag)% BLDC 反电动势观测器 S-Function% 输入 u: [Ia, Ib, Va, Vb]% 输出 y: 估算的转子角度 Theta_hatswitch flagcase 0 % Initialization[sys,x0,str,ts,simStateCompliance] mdlInitializeSizes;case 1 % Derivativessys mdlDerivatives(t,x,u);case 2 % Updatesys mdlUpdate(t,x,u);case 3 % Outputssys mdlOutputs(t,x,u);case 9 % Terminationsys mdlTerminate(t,x,u);otherwiseerror([Unhandled flag ,num2str(flag)]);endfunction [sys,x0,str,ts,simStateCompliance] mdlInitializeSizessizes simsizes;sizes.NumContStates 2; % 估算反电动势 Ea, Ebsizes.NumDiscStates 0;sizes.NumOutputs 1; % 输出角度sizes.NumInputs 4; % Ia, Ib, Va, Vbsizes.DirFeedthrough 0;sizes.NumSampleTimes 1;sys simsizes(sizes);x0 [0; 0]; % 初始反电动势为0str [];ts [1e-5 0]; % 采样时间simStateCompliance ‘UnknownSimState’;function sys mdlDerivatives(t,x,u)% 简单的反电动势观测器模型 (简化版)% 实际工程中通常使用滑模观测器或锁相环Rs 2.5; Ls 8.5e-3;Ia u(1); Ib u(2);Va u(3); Vb u(4);% 状态变量 x(1)Ea_hat, x(2)Eb_hat% 观测器方程: dE/dt k * (V_measured - V_estimated)% 这里仅作演示实际需要根据电机方程推导k_obs 100;Ea_hat x(1);Eb_hat x(2);% 估算电流导数 (简化)dIa_dt (Va - RsIa - Ea_hat)/Ls;dIb_dt (Vb - RsIb - Eb_hat)/Ls;% 更新反电动势估算 (基于电流误差的积分)sys(1) k_obs * (dIa_dt - dIa_dt); % 实际应使用电流误差sys(2) k_obs * (dIb_dt - dIb_dt);function sys mdlUpdate(t,x,u)sys [];function sys mdlOutputs(t,x,u)% 根据估算的反电动势计算角度Ea x(1);Eb x(2);% 简单的反正切计算角度theta_hat atan2(Eb, Ea);% 处理角度跳变if theta_hat 0theta_hat theta_hat 2*pi;endsys theta_hat;function sys mdlTerminate(t,x,u)sys []; 仿真模型结构说明主电路DC Source提供 48V 直流电。Universal Bridge作为三相逆变器由 MOSFET 组成。PMSM Machine这里用作 BLDC 电机模型。虽然它是 PMSM 模块但在仿真中可以通过设置参数如 L_d L_q和梯形波反电动势来模拟 BLDC。控制回路双闭环外环转速输入目标转速与实际转速来自 Bus Selector输出 I_q 参考电流。内环电流输入 I_q 参考值与实际 I_q通过 Park 变换得到输出电压指令。PWM 发生器将电压指令转换为 6 路 PWM 信号驱动逆变桥。无位置传感器算法观测器利用测量的相电压 (V_a, V_b) 和相电流 (I_a, I_b)通过算法如滑模观测器或反电动势观测器估算出反电动势。角度计算通过 atan2(Eb, Ea) 计算出转子位置 theta替代物理传感器信号反馈给 Park 变换模块。 运行步骤将第一段代码保存为 build_bldc_sensorless.m。将第二段代码保存为 bldc_observer_sfun.m放在同一目录下。在 MATLAB 中运行 build_bldc_sensorless。。双击 Scope 查看电机转速波形。⚠️ 调试提示无位置传感器控制通常在静止时无法检测反电动势因此需要特殊的启动策略如三段式启动预定位、强拉加速、切入运行。上述代码中的观测器是简化版参数匹配确保 S-Function 中的 Rs, Ls 与电机模块中的参数一致否则观测器会发散。PI 参数如果转速震荡请减小 PI Speed 的 P 值如果电流响应慢增大 PI Iq 的 P 值。输入信号 Iac_a 和 Iac_b。经过一系列开关switch1, switch7 等和函数f(u)可能是查表或数学函数。进行乘法运算Product。输出到显示模块Idc1, Idc2 等。由于 Simulink 模型通常通过图形界面搭建function create_current_logic_model()% 清除工作区clc; clear; close_all;% 定义模型名称 model_name Current_Switching_Logic; % 如果模型已存在则关闭它 if bdIsLoaded(model_name) close_system(model_name, 0); end % 创建新模型 new_system(model_name); open_system(model_name); %% 1. 添加输入信号源 (对应图中的 Iac_a, Iac_b) % 添加 Iac_a 输入 add_block(simulink/Sources/In1, [model_name /Iac_a], Position, [50 50 80 80]); % 添加 Iac_b 输入 add_block(simulink/Sources/In1, [model_name /Iac_b], Position, [50 150 80 180]); %% 2. 添加开关模块 (对应图中的 switch1, switch7, switch8, switch9, switch10) % 添加 switch1 add_block(simulink/Signal Routing/Switch, [model_name /switch1], Position, [150 30 180 60]); % 添加 switch7 add_block(simulink/Signal Routing/Switch, [model_name /switch7], Position, [150 100 180 130]); % 添加 switch8 add_block(simulink/Signal Routing/Switch, [model_name /switch8], Position, [150 170 180 200]); % 添加 switch9 add_block(simulink/Signal Routing/Switch, [model_name /switch9], Position, [150 240 180 270]); % 添加 switch10 add_block(simulink/Signal Routing/Switch, [model_name /switch10], Position, [150 310 180 340]); %% 3. 添加函数模块 (对应图中的 f(u)) % 添加 f(u) 模块 (这里用 MATLAB Function 代替你可以自定义函数) add_block(simulink/User-Defined Functions/MATLAB Function, [model_name /f(u)_1], Position, [220 30 250 60]); add_block(simulink/User-Defined Functions/MATLAB Function, [model_name /f(u)_7], Position, [220 100 250 130]); add_block(simulink/User-Defined Functions/MATLAB Function, [model_name /f(u)_8], Position, [220 170 250 200]); add_block(simulink/User-Defined Functions/MATLAB Function, [model_name /f(u)_9], Position, [220 240 250 270]); add_block(simulink/User-Defined Functions/MATLAB Function, [model_name /f(u)_10], Position, [220 310 250 340]); %% 4. 添加乘法器 (对应图中的 Product, Product1, Product2, Product3) % 添加 Product add_block(simulink/Math Operations/Product, [model_name /Product], Position, [300 30 330 60]); % 添加 Product1 add_block(simulink/Math Operations/Product, [model_name /Product1], Position, [300 100 330 130]); % 添加 Product2 add_block(simulink/Math Operations/Product, [model_name /Product2], Position, [300 170 330 200]); % 添加 Product3 add_block(simulink/Math Operations/Product, [model_name /Product3], Position, [300 240 330 270]); %% 5. 添加增益模块 (对应图中的 Gain, Gain1) % 添加 Gain add_block(simulink/Math Operations/Gain, [model_name /Gain], Position, [380 100 410 130]); % 添加 Gain1 add_block(simulink/Math Operations/Gain, [model_name /Gain1], Position, [380 240 410 270]); %% 6. 添加输出显示模块 (对应图中的 Idc1, Idc2, Idc3, Idc4) % 添加 Idc1 add_block(simulink/Sinks/Out1, [model_name /Idc1], Position, [450 30 480 60]); % 添加 Idc2 add_block(simulink/Sinks/Out1, [model_name /Idc2], Position, [450 100 480 130]); % 添加 Idc3 add_block(simulink/Sinks/Out1, [model_name /Idc3], Position, [450 170 480 200]); % 添加 Idc4 add_block(simulink/Sinks/Out1, [model_name /Idc4], Position, [450 240 480 270]); %% 7. 连接模块 (模拟图中的连线) % 连接 Iac_a - switch1 add_line(model_name, Iac_a/1, switch1/1); % 连接 Iac_a - switch7 add_line(model_name, Iac_a/1, switch7/1); % 连接 Iac_b - switch8 add_line(model_name, Iac_b/1, switch8/1); % 连接 Iac_b - switch9 add_line(model_name, Iac_b/1, switch9/1); % 连接 Iac_b - switch10 add_line(model_name, Iac_b/1, switch10/1); % 连接 switch1 - f(u)_1 add_line(model_name, switch1/1, f(u)_1/1); % 连接 switch7 - f(u)_7 add_line(model_name, switch7/1, f(u)_7/1); % 连接 switch8 - f(u)_8 add_line(model_name, switch8/1, f(u)_8/1); % 连接 switch9 - f(u)_9 add_line(model_name, switch9/1, f(u)_9/1); % 连接 switch10 - f(u)_10 add_line(model_name, switch10/1, f(u)_10/1); % 连接 f(u)_1 - Product add_line(model_name, f(u)_1/1, Product/1); % 连接 f(u)_7 - Product1 add_line(model_name, f(u)_7/1, Product1/1); % 连接 f(u)_8 - Product2 add_line(model_name, f(u)_8/1, Product2/1); % 连接 f(u)_9 - Product3 add_line(model_name, f(u)_9/1, Product3/1); % 连接 Product - Idc1 add_line(model_name, Product/1, Idc1/1); % 连接 Product1 - Gain add_line(model_name, Product1/1, Gain/1); % 连接 Gain - Idc2 add_line(model_name, Gain/1, Idc2/1); % 连接 Product2 - Idc3 add_line(model_name, Product2/1, Idc3/1); % 连接 Product3 - Gain1 add_line(model_name, Product3/1, Gain1/1); % 连接 Gain1 - Idc4 add_line(model_name, Gain1/1, Idc4/1); % 添加 Scope 用于观察输出 add_block(simulink/Sinks/Scope, [model_name /Scope], Position, [500 50 530 80]); add_line(model_name, Idc1/1, Scope/1); add_line(model_name, Idc2/1, Scope/2); add_line(model_name, Idc3/1, Scope/3); add_line(model_name, Idc4/1, Scope/4); % 保存模型 save_system(model_name); disp([模型 , model_name, 已成功创建]);end如何运行代码打开 MATLAB。将上述代码复制到一个新的 .m 文件中例如 create_current_logic_model.m。在 MATLAB 命令窗口中运行create_current_logic_model模型说明输入Iac_a 和 Iac_b 是交流电流输入。开关逻辑switch1 到 switch10 用于根据控制信号选择不同的电流路径。函数模块f(u) 可以是任意数学函数如查表、饱和、死区等你可以在 MATLAB Function 模块中自定义。乘法器用于计算电流与某个系数如 PWM 占空比的乘积。输出Idc1 到 Idc4 是最终的直流电流输出可以通过 Scope 观察。

更多文章