官方论坛
官方淘宝
官方博客
微信公众号
点击联系吴工 点击联系周老师

【案例】PWM流水灯设计

发布时间:2021-06-25   作者:admin 浏览量:

案例编号:000800000017

脉冲宽度调制(pulse width modelation)简称PWM,利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

在本章的应用中可以认为PWM就是一种方波。如图2-7所示。

2-7 PWM波形图

一个周期为10ms,高电平为6ms,低电平时间为4msPWM,其占空比(高电平时间占整个周期的比例)为60%

明德扬的FPGA开发板共有8LED灯。产生8个管脚的PWM图,如图2-8所示。每个管脚对应的占空比分别为:80%70%60%50%40%30%20%10%。系统工作时钟100MHz

2-8 各个LED等对应的PWM波形

FPGA通过8个管脚来分别控制8LED灯,管脚值为0,对应的LED灯亮,管脚值为1,对应的LED灯灭(低亮高灭)。如果管脚不停地变化,则LED灯会闪烁;如果这种高低变化非常快,由于人的视觉暂留现象,LED就会出现不同的亮度。

基于这个原则,我们也可以通过产生PWM波形,来控制LED灯的亮度。

1. 明确功能

首先确定模块信号列表,如表2.2

2.2信号列表

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟100MHz

rst_n

I

1

系统复位信号,低电平有效。

led

O

8

LED输出信号

产生8个脉冲,每个脉冲周期为10s对应的占空比分别为:80%70%60%50%40%30%20%10%

2. 功能波形

led所有信号的变化都是相似的,这里以led[0]为例。见图2-9

2-9 led[0]信号变化图

3. 计数结构

因为每个脉冲的高低电平持续时间都是以1s为单位的,所以引入两个计数器,计数器cnt_1s计数1s,计数器cnt_10s计数每个脉冲高低电平分别持续的时间。具体计数情况如2-10所示:


2-10 计数结构图

4. 加一结束条件

cnt_1s的加1条件:计数器一直在计数,即:assign add_cnt_1s=1

cnt_1s的结束条件:加一条件下计数到100_000_000-1

cnt_10s的加1条件:cnt_1s的结束时刻;

cnt_10s的结束条件:加一条件下计数到10-1

5. 定义特殊点

2-11有几个特殊点,需要我们记住

2-11 特殊定义点图

cnt1s的结束条件:cnt_1s==100_000_000-1,定为end_cnt_1s

cnt10s的结束条件:cnt_10s==10-1,定为end_cnt_10s

led所有位的新号变化都是相似的,所以我们以led[0]为例定义特殊点,

led[0]变高的条件:cnt_10s==1-1,定为led0_off

led[0]变低的条件:cnt_10s==10-1,定为led_on


6. 完整性检查


(1)计数器cnt_1s
cnt_1s的初值:0;
cnt_1s的加1条件:assign add_cnt_1s=1;
cnt_1s的结束条件:
assign end_cnt_1s=add_cnt1s&&cnt_1s ==100_000_000 - 1
(6)led[3]
led[3]由0变1:led3_off
led[3]由1变0:led_on
(2)计数器cnt_10s
cnt_10s初值:0;
cnt_10s的加1条件: assign add_cnt_10s=end_cnt1s;
cnt_10s的结束条件:
assign end_cnt_10s=add_cnt10s && cnt_10s==10 - 1
(7)led[4]
led[4]由0变1:led4_off
led[4]由1变0:led_on
(3)led[0]
led[0]由0变1:led0_off
led[0]由1变0:led_on
(8)led[5]
led[5]由0变1:led5_off
led[5]由1变0:led_on
(4)led[1]
led[1]由0变1:led1_off
led[1]由1变0:led_on
(9)led[6]
led[6]由0变1:led6_off
led[6]由1变0:led_on
(5)led[2]
led[2]由0变1:led2_off
led[2]由1变0:led_on
(10)led[7]
led[7]由0变1:led7_off
led[7]由1变0:led_on

7. 计数器代码

 1 parameter  TIME_1S  = 100_000_000   ;
 2
 3 always  @(posedgeclk or negedgerst_n)begin
 4     if(rst_n==1'b0)begin
 5         cnt_1s <= 0;
 6     end
 7     else if(add_cnt_1s)begin
 8         if(end_cnt_1s)
 9             cnt_1s <= 0;
10         else
11             cnt_1s <= cnt_1s + 1;
12     end
13 end
14 assign add_cnt_1s = 1'b1;
15 assign end_cnt_1s = add_cnt_1s && cnt_1s==TIME_1S-1;
16
17 always  @(posedgeclk or negedgerst_n)begin
18     if(rst_n==1'b0)begin
19         cnt_10s <= 0;
20     end
21     else if(add_cnt_10s)begin
22         if(end_cnt_10s)
23             cnt_10s <= 0;
24         else
25             cnt_10s <= cnt_10s + 1;
26     end
27 end
28 assign add_cnt_10s = end_cnt_1s;
29 assign end_cnt_10s = add_cnt_10s && cnt_10s==10-1;
30


8.完整代码

  1 //按照第六步第3点,写出len[0]的代码
  2 always  @(posedgeclk or negedgerst_n)begin
  3     if(rst_n==1'b0)begin
  4         led[0] <= 0;
  5     end
  6     else if(led_on)begin
  7         led[0] <= 0;
  8     end
  9     else if(led0_off)begin
 10         led[0] <= 1;
 11     end
 12 end
 13 assign led0_off = add_cnt_10s && cnt_10s==1-1;
 14 assign led_on  = add_cnt_10s && cnt_10s==10-1;
 15
 16 //按照第六步第4点,写出len[1]的代码
 17 always  @(posedgeclk or negedgerst_n)begin
 18     if(rst_n==1'b0)begin
 19         led[1] <= 0;
 20     end
 21     else if(led_on)begin
 22         led[1] <= 0;
 23     end
 24     else if(led1_off)begin
 25         led[1] <= 1;
 26     end
 27 end
 28 assign led1_off = add_cnt_10s && cnt_10s==2-1;
 29
 30 //按照第六步第5点,写出len[2]的代码
 31 always  @(posedgeclk or negedgerst_n)begin
 32     if(rst_n==1'b0)begin
 33         led[2] <= 0;
 34     end
 35     else if(led_on)begin
 36         led[2] <= 0;
 37     end
 38     else if(led2_off)begin
 39         led[2] <= 1;
 40     end
 41 end
 42 assign led2_off = add_cnt_10s && cnt_10s==3-1;
 43
 44 //按照第六步第6点,写出len[3]的代码
 45 always  @(posedgeclk or negedgerst_n)begin
 46     if(rst_n==1'b0)begin
 47         led[3] <= 0;
 48     end
 49     else if(led_on)begin
 50         led[3] <= 0;
 51     end
 52     else if(led3_off)begin
 53         led[3] <= 1;
 54     end
 55 end
 56 assign led3_off = add_cnt_10s && cnt_10s==4-1;
 57
 58 //按照第六步第7点,写出len[4]的代码
 59 always  @(posedgeclk or negedgerst_n)begin
 60     if(rst_n==1'b0)begin
 61         led[4] <= 0;
 62     end
 63     else if(led_on)begin
 64         led[4] <= 0;
 65     end
 66     else if(led4_off)begin
 67         led[4] <= 1;
 68     end
 69 end
 70 assign led4_off = add_cnt_10s && cnt_10s==5-1;
 71
 72 //按照第六步第8点,写出len[5]的代码
 73 always  @(posedgeclk or negedgerst_n)begin
 74     if(rst_n==1'b0)begin
 75         led[5] <= 0;
 76     end
 77     else if(led_on)begin
 78         led[5] <= 0;
 79     end
 80     else if(led5_off)begin
 81         led[5] <= 1;
 82     end
 83 end
 84 assign led5_off = add_cnt_10s && cnt_10s==6-1;
 85
 86 //按照第六步第9点,写出len[6]的代码
 87 always  @(posedgeclk or negedgerst_n)begin
 88     if(rst_n==1'b0)begin
 89         led[6] <= 0;
 90     end
 91     else if(led_on)begin
 92         led[6] <= 0;
 93     end
 94     else if(led6_off)begin
 95         led[6] <= 1;
 96     end
 97 end
 98 assign led6_off = add_cnt_10s && cnt_10s==7-1;
 99
100 //按照第六步第10点,写出len[7]的代码
101 always  @(posedgeclk or negedgerst_n)begin
102     if(rst_n==1'b0)begin
103         led[7] <= 0;
104     end
105     else if(led_on)begin
106         led[7] <= 0;
107     end
108     else if(led7_off)begin
109         led[7] <= 1;
110     end
111 end
112 assign led7_off = add_cnt_10s && cnt_10s==8-1;
113


技术交流QQ群:764574006

更多FPGA技术资讯:明德扬科教






   拓展阅读