生活随笔
收集整理的這篇文章主要介紹了
利用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原理实现调光灯的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。