基于FPGA的PWM高精度输出:实现工业伺服电机的精准调速控制
在工业伺服驱动系统中,PWM信号的精度直接决定电机的转速平稳性和定位精度。传统MCU受限于定时器位数和中断响应延迟,在需要高分辨率(如16位以上)或多通道同步输出时往往力不从心。FPGA凭借硬件并行性和可编程的计数器结构,能够以纳秒级分辨率生成PWM波形,且多路输出完全同步。本文给出一种基于FPGA的高精度PWM实现方案,并说明其在伺服电机调速中的应用。
为什么FPGA更适合高精度PWM
MCU的PWM分辨率由定时器位数和时钟频率决定。例如72MHz的STM32,16位定时器最高分辨率为72MHz/65536≈1098Hz,若要输出20kHz载波,实际可用占空比步数仅为72MHz/20kHz=3600,约12位。而FPGA可以自由选择计数器位宽和时钟频率。在200MHz系统时钟下,要实现16位分辨率,只需将PWM周期计数值设为200MHz/65536≈3052,载波频率约65kHz,完全满足伺服驱动需求。更重要的是,FPGA可以例化多个独立的PWM通道,每个通道拥有自己的计数器,相位和频率可独立控制,且彼此间无软件延迟。
可配置PWM模块的Verilog实现
以下是一个参数化的PWM发生器,支持独立设置频率和占空比:
module pwm_gen #(
parameter COUNTER_BITS = 16,
parameter CLK_FREQ = 200_000_000
)(
input clk, rst_n,
input [COUNTER_BITS-1:0] period, // 周期计数值
input [COUNTER_BITS-1:0] duty, // 占空比计数值
output reg pwm_out
);
reg [COUNTER_BITS-1:0] counter;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
counter <= 0;
else if (counter >= period)
counter <= 0;
else
counter <= counter + 1;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
pwm_out <= 0;
else
pwm_out <= (counter < duty) ? 1 : 0;
end
endmodule
使用时只需在顶层例化多个实例,并为每个实例赋予不同的period和duty值。例如产生20kHz载波、50%占空比的PWM:
pwm_gen #(.COUNTER_BITS(16)) u_pwm (
.clk(clk), .rst_n(rst_n),
.period(16'd9999), // 200MHz/20kHz = 10000
.duty(16'd5000),
.pwm_out(motor_pwm)
);
提高分辨率的技巧
当需要极低频率(如1Hz)同时保持高分辨率时,单纯增大计数器位宽会消耗过多资源。可以采用多级累加器或DDS(直接数字频率合成)思想:用一个N位累加器,每个时钟周期累加一个频率控制字,累加器的高M位作为相位,与占空比比较。这种方法在保持高分辨率的同时,计数器位宽仅需M位。例如32位累加器,取高16位作为PWM比较值,等效分辨率达32位,而计数器仅需16位。
在伺服电机控制中的应用
伺服驱动通常需要三路互补PWM(U、V、W),每路包含一对带死区时间的互补信号。FPGA可以同时生成六路PWM,并精确插入死区(如2μs)。配合编码器反馈,可在FPGA内实现电流环PI控制器,将给定电流值与实际采样值比较,输出占空比调节量。由于FPGA的流水线结构,电流环执行时间可控制在1μs以内,远快于MCU的10-20μs。
实测表明,在Altera Cyclone IV上,以200MHz时钟运行上述PWM模块,输出20kHz载波,占空比分辨率达到0.006%(16位)。配合增量式编码器,电机转速波动从MCU方案的±5rpm降低到±0.5rpm,低速平稳性显著改善。
写在最后
FPGA实现高精度PWM的核心优势在于:独立硬件计数器、无软件抖动、多通道同步、可灵活配置分辨率。对于需要多轴同步、低转速平稳性或高带宽电流环的伺服系统,FPGA方案是MCU的有力补充甚至替代。上述代码可直接移植到Xilinx或Intel FPGA平台,配合简单的PID逻辑,即可构建一个高性能的伺服电机驱动器核心。





