生活随笔
收集整理的这篇文章主要介绍了
利用PWM原理实现调光灯
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
一、PWM原理
PWM(Pulse Width Modulation)即脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种技术。PWM是一种对模拟信号电平进行数字编码的方法。通过使用高分辨率计数器,对方波的占空比进行调制,从而对一个具体模拟信号的电平进行编码。
二、设计思想
本实验利用pynq-z2平台,要求对led灯实现4挡亮度,同时4个led灯要顺序流转起来。led灯只有高低电平2个挡位,如何实现led的4挡亮度呢?可以想到利用pwm技术,对信号周期的占空比进行控制,从而对电平编码,实现4挡亮度控制。
假设周期为1ms,则4挡亮度占空比分别为250us、500us、750us和1000us。定义一个2位计数器cnt1ms对4种状态进行编码。
此时已经实现led灯的4挡亮度。那么下面如何实现led灯的流转呢。定义一个每1s的计数器cnt,每过1秒led灯的状态变化一次,4s是一个周期。4个led灯的状态表如下所示。
根据状态表,对每个led灯的每个cnt时刻亮度挡位状态进行一一对应,即可实现led灯的流转。模块示意图如下所示。
三、代码实现
设计代码如下所示。
module pwm
(input sclk
,input s_rst
,output reg [
3:0] led
);localparam DELAY_250US
=
localparam DELAY_1MS
=
localparam DELAY_1S
= reg [
14:0] cnt_250us
;
reg [
1:0] cnt_1ms
;
reg [
9:0] cnt_1s
; //1s的计数器
reg [
1:0] cnt
; //每
1s的计数器,共
4salways @
(posedge sclk
or posedge s_rst
) begin //250us 计数器
if(s_rst
== 1cnt_250us
<= else if(cnt_250us
== DELAY_250US
)cnt_250us
<= elsecnt_250us
<= cnt_250us
+ 1
endalways @
(posedge sclk
or posedge s_rst
) begin //1ms 计数器
if(s_rst
== 1cnt_1ms
<= else if(cnt_1ms
== DELAY_1MS
&& cnt_250us
== DELAY_250US
)cnt_1ms
<= else if(cnt_250us
== DELAY_250US
)cnt_1ms
<= cnt_1ms
+ 1
endalways @
(posedge sclk
or posedge s_rst
) //1s 计数器
beginif(s_rst
== 1cnt_1s
<= 10else if(cnt_1s
== DELAY_1S
&& cnt_1ms
== DELAY_1MS
&& cnt_250us
== DELAY_250US
)cnt_1s
<= 10else if(cnt_1ms
== DELAY_1MS
&& cnt_250us
== DELAY_250US
)cnt_1s
<= cnt_1s
+ 1
end//计数器cnt
always @
(posedge sclk
or posedge s_rst
)
beginif(s_rst
== 1cnt
<= 2else if(cnt
== 2cnt
<= 2else if(cnt_1s
== DELAY_1S
&& cnt_1ms
== DELAY_1MS
&& cnt_250us
== DELAY_250US
)cnt
<= cnt
+ 1
end//led0
always @
(posedge sclk
or posedge s_rst
)
beginif(s_rst
== 1led[
0]
<= 1else if(cnt
== 0 ) //cnt
== 0 时,亮度
1挡
beginif (cnt_1ms
== 2led[
0]
<= 1elseled[
0]
<= 1endelse if(cnt
== 1) beginif (cnt_1ms
== 2led[
0]
<= 1elseled[
0]
<= 1endelse if(cnt
== 2) beginif (cnt_1ms
== 2led[
0]
<= 1elseled[
0]
<= 1endelse if(cnt
== 3) beginif (cnt_1ms
== 2led[
0]
<= 1elseled[
0]
<= 1endelse led[
0]
<= 1
end//led1
always @
(posedge sclk
or posedge s_rst
)
beginif(s_rst
== 1led[
1]
<= 1else if(cnt
== 0) beginif (cnt_1ms
== 2led[
1]
<= 1elseled[
1]
<= 1endelse if(cnt
== 1) beginif (cnt_1ms
== 2led[
1]
<= 1elseled[
1]
<= 1endelse if(cnt
== 2) beginif (cnt_1ms
== 2led[
1]
<= 1elseled[
1]
<= 1endelse if(cnt
== 3) beginif (cnt_1ms
== 2led[
1]
<= 1elseled[
1]
<= 1endelse led[
1]
<= 1
end//led2
always @
(posedge sclk
or posedge s_rst
)
beginif(s_rst
== 1led[
2]
<= 1else if(cnt
== 0) beginif (cnt_1ms
== 2led[
2]
<= 1elseled[
2]
<= 1endelse if(cnt
== 1) beginif (cnt_1ms
== 2led[
2]
<= 1elseled[
2]
<= 1endelse if(cnt
== 2) beginif (cnt_1ms
== 2led[
2]
<= 1elseled[
2]
<= 1end else if(cnt
== 3) beginif (cnt_1ms
== 2led[
2]
<= 1elseled[
2]
<= 1endelse led[
2]
<= 1end//led3
always @
(posedge sclk
or posedge s_rst
)
beginif(s_rst
== 1led[
3]
<= 1else if(cnt
== 0) beginif (cnt_1ms
== 2led[
3]
<= 1elseled[
3]
<= 1endelse if(cnt
== 1) beginif (cnt_1ms
== 2led[
3]
<= 1elseled[
3]
<= 1end else if(cnt
== 2) beginif (cnt_1ms
== 2led[
3]
<= 1elseled[
3]
<= 1endelse if(cnt
== 3) beginif (cnt_1ms
== 2led[
3]
<= 1elseled[
3]
<= 1end else led[
3]
<= 1
endendmodule
测试代码如下所示。
`timescale
1ns
/1ns
module tb_pwm
;reg sclk
;
reg s_rst
;
wire [
3:0] led
;initial
beginsclk
= 1;s_rst
<= 1 ;#
100s_rst
<= 0 ;
endalways #
4 sclk
= ~sclk
;pwm pwm_inst
(.sclk
(sclk
), .s_rst
(s_rst
), reset
, active low.led
(led
)
);endmodule
四、实验结果
利用testbench仿真的结果如下所示:
实验结果如下所示:
总结
以上是生活随笔为你收集整理的利用PWM原理实现调光灯的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。