脈沖寬度調(diào)制(pulse width modelation)簡稱PWM,利用微處理器的數(shù)字輸出來對模擬電路進(jìn)行控制的一種非常有效的技術(shù),廣泛應(yīng)用在從測量、通信到功率控制與變換的許多領(lǐng)域中脈沖寬度調(diào)制是利用微處理器的數(shù)字輸出來對模擬電路進(jìn)行控制的一種非常有效的技術(shù),廣泛應(yīng)用在從測量、通信到功率控制與變換的許多領(lǐng)域中。
在本章的應(yīng)用中可以認(rèn)為PWM就是一種方波。如圖2-7所示。
圖2-7 PWM波形圖
一個周期為10ms,高電平為6ms,低電平時間為4ms的PWM,其占空比(高電平時間占整個周期的比例)為60%。
明德?lián)P的FPGA開發(fā)板共有8個LED燈。產(chǎn)生8個管腳的PWM圖,如圖2-8所示。每個管腳對應(yīng)的占空比分別為:80%、70%、60%、50%、40%、30%、20%和10%。系統(tǒng)工作時鐘100MHz。
圖2-8 各個LED等對應(yīng)的PWM波形
FPGA通過8個管腳來分別控制8個LED燈,管腳值為0,對應(yīng)的LED燈亮,管腳值為1,對應(yīng)的LED燈滅(低亮高滅)。如果管腳不停地變化,則LED燈會閃爍;如果這種高低變化非常快,由于人的視覺暫留現(xiàn)象,LED就會出現(xiàn)不同的亮度。
基于這個原則,我們也可以通過產(chǎn)生PWM波形,來控制LED燈的亮度。
1. 明確功能
首先確定模塊信號列表,如表2.2。
表2.2信號列表
信號名 |
I/O |
位寬 |
說明 |
clk |
I |
1 |
系統(tǒng)工作時鐘100MHz。 |
rst_n |
I |
1 |
系統(tǒng)復(fù)位信號,低電平有效。 |
led |
O |
8 |
LED輸出信號 |
產(chǎn)生8個脈沖,每個脈沖周期為10s對應(yīng)的占空比分別為:80%、70%、60%、50%、40%、30%、20%和10%。
2. 功能波形
led所有信號的變化都是相似的,這里以led[0]為例。見圖2-9。
圖2-9 led[0]信號變化圖
3. 計數(shù)結(jié)構(gòu)
因為每個脈沖的高低電平持續(xù)時間都是以1s為單位的,所以引入兩個計數(shù)器,計數(shù)器cnt_1s計數(shù)1s,計數(shù)器cnt_10s計數(shù)每個脈沖高低電平分別持續(xù)的時間。具體計數(shù)情況如圖2-10所示:
圖2-10 計數(shù)結(jié)構(gòu)圖
4. 加一結(jié)束條件
cnt_1s的加1條件:計數(shù)器一直在計數(shù),即:assign add_cnt_1s=1;
cnt_1s的結(jié)束條件:加一條件下計數(shù)到100_000_000-1;
cnt_10s的加1條件:cnt_1s的結(jié)束時刻;
cnt_10s的結(jié)束條件:加一條件下計數(shù)到10-1;
5. 定義特殊點
圖2-11有幾個特殊點,需要我們記住。
圖2-11 特殊定義點圖
cnt1s的結(jié)束條件:cnt_1s==100_000_000-1,定為end_cnt_1s。
cnt10s的結(jié)束條件: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)計數(shù)器cnt_1s cnt_1s的初值:0; cnt_1s的加1條件:assign add_cnt_1s=1; cnt_1s的結(jié)束條件: 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)計數(shù)器cnt_10s cnt_10s初值:0; cnt_10s的加1條件: assign add_cnt_10s=end_cnt1s; cnt_10s的結(jié)束條件: 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. 計數(shù)器代碼
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.完整代碼
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
技術(shù)交流QQ群:544453837
更多FPGA技術(shù)資訊:明德?lián)P科教
了解>>至簡設(shè)計法