欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

利用PWM原理实现调光灯

发布时间:2024/3/7 编程问答 76 豆豆
生活随笔 收集整理的这篇文章主要介绍了 利用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 = 'd31249 ; localparam DELAY_1MS = 'd3 ; localparam DELAY_1S = 'd999;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 == 1'b1) cnt_250us <= 'd0;else if(cnt_250us == DELAY_250US)cnt_250us <= 'd0;elsecnt_250us <= cnt_250us + 1'b1; endalways @(posedge sclk or posedge s_rst) begin //1ms 计数器if(s_rst == 1'b1) cnt_1ms <= 'd0;else if(cnt_1ms == DELAY_1MS && cnt_250us == DELAY_250US)cnt_1ms <= 'd0;else if(cnt_250us == DELAY_250US)cnt_1ms <= cnt_1ms + 1'b1; endalways @(posedge sclk or posedge s_rst) //1s 计数器 beginif(s_rst == 1'b1)cnt_1s <= 10'd0 ;else if(cnt_1s == DELAY_1S && cnt_1ms == DELAY_1MS && cnt_250us == DELAY_250US)cnt_1s <= 10'd0 ;else if(cnt_1ms == DELAY_1MS && cnt_250us == DELAY_250US)cnt_1s <= cnt_1s + 1'b1 ; end//计数器cnt always @(posedge sclk or posedge s_rst) beginif(s_rst == 1'b1)cnt <= 2'd0 ;else if(cnt == 2'd3 && cnt_1s == DELAY_1S && cnt_1ms == DELAY_1MS && cnt_250us == DELAY_250US)cnt <= 2'd0 ;else if(cnt_1s == DELAY_1S && cnt_1ms == DELAY_1MS && cnt_250us == DELAY_250US)cnt <= cnt + 1'b1 ; end//led0 always @(posedge sclk or posedge s_rst) beginif(s_rst == 1'b1)led[0] <= 1'b0 ;else if(cnt == 0 ) //cnt == 0 时,亮度1beginif (cnt_1ms == 2'b00)led[0] <= 1'b1 ;elseled[0] <= 1'b0 ;endelse if(cnt == 1) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01)led[0] <= 1'b1 ;elseled[0] <= 1'b0 ;endelse if(cnt == 2) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10)led[0] <= 1'b1 ;elseled[0] <= 1'b0 ;endelse if(cnt == 3) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10 || cnt_1ms == 2'b11)led[0] <= 1'b1 ;elseled[0] <= 1'b0 ;endelse led[0] <= 1'b0 ; end//led1 always @(posedge sclk or posedge s_rst) beginif(s_rst == 1'b1)led[1] <= 1'b0 ;else if(cnt == 0) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01)led[1] <= 1'b1 ;elseled[1] <= 1'b0 ;endelse if(cnt == 1) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10)led[1] <= 1'b1 ;elseled[1] <= 1'b0 ;endelse if(cnt == 2) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10 || cnt_1ms == 2'b11)led[1] <= 1'b1 ;elseled[1] <= 1'b0 ;endelse if(cnt == 3) beginif (cnt_1ms == 2'b00)led[1] <= 1'b1 ;elseled[1] <= 1'b0 ;endelse led[1] <= 1'b0 ; end//led2 always @(posedge sclk or posedge s_rst) beginif(s_rst == 1'b1)led[2] <= 1'b0 ;else if(cnt == 0) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10)led[2] <= 1'b1 ;elseled[2] <= 1'b0 ;endelse if(cnt == 1) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10 || cnt_1ms == 2'b11)led[2] <= 1'b1 ;elseled[2] <= 1'b0 ;endelse if(cnt == 2) beginif (cnt_1ms == 2'b00)led[2] <= 1'b1 ;elseled[2] <= 1'b0 ;end else if(cnt == 3) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01)led[2] <= 1'b1 ;elseled[2] <= 1'b0 ;endelse led[2] <= 1'b0 ;end//led3 always @(posedge sclk or posedge s_rst) beginif(s_rst == 1'b1)led[3] <= 1'b0 ;else if(cnt == 0) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10 || cnt_1ms == 2'b11)led[3] <= 1'b1 ;elseled[3] <= 1'b0 ;endelse if(cnt == 1) beginif (cnt_1ms == 2'b00)led[3] <= 1'b1 ;elseled[3] <= 1'b0 ;end else if(cnt == 2) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01)led[3] <= 1'b1 ;elseled[3] <= 1'b0 ;endelse if(cnt == 3) beginif (cnt_1ms == 2'b00 || cnt_1ms == 2'b01 ||cnt_1ms == 2'b10)led[3] <= 1'b1 ;elseled[3] <= 1'b0 ;end else led[3] <= 1'b0 ; endendmodule

测试代码如下所示。

`timescale 1ns/1nsmodule 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原理实现调光灯的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。