#来自学渣的问候~(老口头禅了)
PWM(Pulse Width Modulation)控制——脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。PWM控制技术在逆变电路中应用最广,应用的逆变电路绝大部分是PWM型,PWM控制技术正是有赖于在逆 变电路中的应用,才确定了它在电力电子技术中的重要地位。
说起PWM,这里还有一个故事,当年我刚上大一的时候,就认识了我们学校一个特别厉害的学长(保研电子科大),那个时候我第一个问他的问题就是PWM。当时我非常单纯的问了一个呼吸灯的问题,就是利用PWM来实现的,算是最简单的应用之一。
PWM的介绍
PWM从复杂的角度来理解,是一种对模拟信号电平进行数字编码的方法。
而它的理论基础是:窄脉冲加在具有惯性的环节上时,其效果基本相同。冲量指窄脉冲的面积。效果基本相同,是指环节的输出响应波形基本相同。低频段非常接近,仅在高频段略有差异。
再难一点,就涉及蛮复杂的问题了,在这里就不细说了。想了解的可以看这个大佬的博客:PWM波的介绍
用最俗的话来说, PWM波就是方波的一种,在一定频率内,高电平持续一段时间,低电平持续一段时间,但是两者的占空比不同或者持续在变化。(或者受状态改变而变化)
Robei EDA实现PWM的办法是啥呢?(加强版计数器)
Robei 实现PWM
PWM模块的实现
这里的duty应该是wire类型,Datasize是2。
模块代码如下:(用的C#的高亮)
parameter cnt_end =100;
parameter cnt_25 = cnt_end/4;
parameter cnt_50 = cnt_end/2;
parameter cnt_75 = cnt_end*3/4;
reg [24:0] cnt;
always@(posedge clk or negedge rst)
begin
if(rst == 1)
cnt <= 1;
else if(cnt == cnt_end)
cnt <=1;
else
cnt <= cnt +1;
end
wire pwm1,pwm2,pwm3;
assign pwm1 = (cnt <= cnt_25) ? 1'b1:1'b0;
assign pwm2 = (cnt <= cnt_50) ? 1'b1:1'b0;
assign pwm3 = (cnt <= cnt_75) ? 1'b1:1'b0;
assign pwm_out = (duty == 2'b01)? pwm1: //这是个很长的三位运算
(duty == 2'b11)? pwm2:
(duty == 2'b10)? pwm3:1'b0;
代码解释:
parameter
声明的是PWM的占空比,方便修改和计算。- pwm1,pwm2,pwm3的三个判断,就是用来切换高低电平的。
- pwm_out是一个叠加了三个三目运算符的判断。
这里应该是Robei工程事一个很巧妙的地方,这个代码如果要我自己写的话,我应该会把PWM的变化放在always块里面,代码也会更多更复杂。但是这里直接用一个assign就搞定了。
这里我其实是有疑惑的,但是我资历尚浅,对这个没有发言权,所以把问题提出来,希望有大佬能帮忙解答一下。
我在学芯动力的课程——硬件加速设计方法,这门课程里。那个老师有讲过,尽量少使用“?:”这个运算,一个是比较晦涩难读,另一个是在优化的时候不方便。因为Verilog并不是普通的编程语言,它甚至不能算作编程语言,他是硬件描述语言,写出的每一行代码都是在对设计的电路进行描述,越复杂的代码不代表电路的复杂,越精简的代码也不代表电路的高效。所以我不太确定这里的这个assign用的到底好不好
但是这里的这个“?:“真的感觉用的非常的妙。那种,妙蛙种子吃了妙脆角妙进了米奇妙妙屋的那种妙啊。
testbech的创建
initial begin
clk = 1;
rst = 0;
duty = 2'b00;
#5 rst = 1;
#10 rst = 0;
#15000 rst = 1;
#5 $finish;
end
always begin
#5 clk=~clk;
end
always begin
#1000 duty = duty + 1'b1;
end
仿真波形如下:
——————分割线————————
PWM在FPGA上的实现还是非常简单的,因为PWM本来就是一种数字的输出形式(我的理解),如果换成SOC的话,在配置寄存器的放面非常麻烦,而且在不同的单片机上,操作也大不相同。