99在线精品免费视频九九视-99在线精品视频-99在线精品视频免费观里-99在线精品视频在线观看-99在线免费播放



官方論壇
官方淘寶
官方博客
微信公眾號
點擊聯系吳工 點擊聯系周老師

【案例】PWM流水燈設計

發布時間:2021-06-16   作者:admin 瀏覽量:
PWM流水燈設計

--作者:小黑同學
【上板現象】

PWM流水燈在MP801的上板現象(點擊跳轉明德揚論壇觀看)



PWM流水燈在點撥開發板的上板現象
(點擊跳轉明德揚論壇觀看)



PWM流水燈在實驗箱的上板現象(點擊跳轉明德揚論壇觀看)



【設計教程】

1.1 總體設計

1.1.1 概述

脈沖寬度調制技術(Pulse WidthModelationPWM)是利用微處理器/FPGA的數字輸出對模擬電路進行控制的一種有效技術,其廣泛應用于測量、通信、功率控制與變換等眾多領域。PWM數字信號從處理器到被控系統都采用數字形式,無需進行數模轉換。航模中的控制信號大多是PWM信號,比如FUTABAJR等舵機的控制都采用PWM方式,發射機給接收機輸送脈沖后接收機就會控制舵機進行旋轉。舉個例子,假定基礎脈寬是100ms,當發射機的脈寬增大(如增加到150ms)時接收機就控制舵機正向旋轉;反之發射機的脈寬減小(如減小到50ms)時,接收機就控制舵機逆向旋轉。

PWM是一種對模擬信號電平進行數字編碼的方法。通過使用高分辨率計數器,對方波的占空比進行調制,從而對一個具體模擬信號的電平進行編碼。由于在給定的任何時刻,滿幅值的直流供電只存在有(ON)和無(OFF)兩種狀態,因此PWM信號仍然是數字信號。電壓或電流源是以一種通(ON)或斷(OFF)的重復脈沖序列被加到模擬負載上去的。直流供電被加到負載上的時候為“通”,負載供電被斷開的時候為“斷”。只要有足夠的帶寬,任何模擬值都可以使用PWM進行編碼。

通俗來說,PWM是連續的、具有一定比例占空比的脈沖信號,可以通過控制占空比來對其進行改變。簡單來說,可以認為PWM就是一種方波,如圖所示是一個周期為10ms,高電平為6ms,低電平時間為4msPWM,其占空比(高電平時間占整個周期的比例)為60%

PWM波形圖


發光二極管簡稱為LED,是一種常用的發光器件,通過電子與空穴復合釋放能量發光,它在照明領域應用廣泛。發光二極管可高效的將電能轉化為光能,在現代社會具有廣泛的用途,如照明、平板顯示、醫療器件等。可通過高低電平的變化來控制LED燈的明滅狀態,當輸出信號為低電平時,LED燈亮,反之,當輸出信號為高電平時,LED燈滅。因此可通過改變PWM波形的占空比,來控制LED燈亮滅的時間,當有多個LED燈的時候,通過不同的PWM波形來控制不同的LED燈,就可以產生各種各樣不同的效果。



1.1.2 設計目標

本模塊產生8個不同的PWM脈沖,控制8LED燈點亮不同的時間,從而達到流水燈的效果。每個脈沖周期為10s,占空比從10%~80%。上電后,led0點亮1s,熄滅9s;再點亮1s,熄滅9s,……,依次不斷循環。led1~led7led0類似,分別點亮2s~8s,其他時候都是熄滅的。



1.1.3信號列表
  
信號名
  
接口方向
定義
clk
輸入
系統時鐘,50Mhz
rst_n
輸入
低電平復位信號
led
輸出
8位led燈輸出信號


1.1.4 設計思路

根據題目功能要求可知,產生的8個不同的PWM脈沖的周期都是10秒(s),由此我們可以提出兩個計數器的架構,如下圖所示。



該架構由兩個計數器組成:時鐘計數器cnt_1s和周期計數器cnt_10s

時鐘計數器cnt_1s:用于計算1秒的時鐘個數,加一條件為1,表示一直計數;結束條件為50000000,表示數到1秒就清零。

周期計數器cnt_10s:用于對1秒進行計數,加一條件為end_cnt_1s,表示數到1秒就加1;結束條件為10,表示數完10秒就清零。

至此,我們就將這個練習的計數器架構設計出來了。

下面是計數器的代碼。

  
always @(posedge clk or negedgerst_n)begin
  
     if(!rst_n)begin
  
         cnt_1s <= 0;
  
     end
  
     else if(add_cnt_1s)begin
  
         if(end_cnt_1s)
  
             cnt_1s <= 0;
  
         else
  
             cnt_1s <= cnt_1s + 1;
  
     end
  
end
  
  
assign add_cnt_1s = 1;
  
assign end_cnt_1s = add_cnt_1s &&  cnt_1s==50_000_000 -1 ;
  
  
  
  
  
always @(posedge clk or negedgerst_n)begin  
  
     if(!rst_n)begin
  
         cnt_10s <= 0;
  
     end
  
     else if(add_cnt_10s)begin
  
         if(end_cnt_10s)
  
             cnt_10s <= 0;
  
         else
  
             cnt_10s <= cnt_10s + 1;
  
     end
  
end
  
  
assign add_cnt_10s = end_cnt_1s;
  
assign end_cnt_10s = add_cnt_10s  && cnt_10s==10-1 ;
  


下面我們開始設計輸出信號led,在設計這些信號的時候,我們只需要關注他的變化點,也就是0110的點。



led0的變化為例,上電后,led[0]點亮1s,熄滅9s,再點亮1s,熄滅9s。也就是數到1秒時,即add_cnt_10s && cnt_10s==1-1時,led001。當數到10秒時,即end_cnt_10s時,led[0]10


Led[1]~led[7]也是同樣,即:

上電后,led[1]點亮2s,熄滅8s,再點亮2s,熄滅8s。也就是數到2秒時,即add_cnt_10s &&cnt_10s==2-1時,led[1]01。當數到10秒時,即end_cnt_10s時,led[1]10

上電后,led[2]點亮3s,熄滅7s,再點亮3s,熄滅7s。也就是數到3秒時,即add_cnt_10s &&cnt_10s==3-1時,led[2]01。當數到10秒時,即end_cnt_10s時,led[2]10

上電后,led[3]點亮4s,熄滅6s,再點亮4s,熄滅6s。也就是數到4秒時,即add_cnt_10s &&cnt_10s==4-1時,led[3]01。當數到10秒時,即end_cnt_10s時,led[3]10

上電后,led[4]點亮5s,熄滅5s,再點亮5s,熄滅5s。也就是數到5秒時,即add_cnt_10s &&cnt_10s==5-1時,led[4]01。當數到10秒時,即end_cnt_10s時,led[4]10

上電后,led[5]點亮6s,熄滅4s,再點亮6s,熄滅4s。也就是數到6秒時,即add_cnt_10s &&cnt_10s==6-1時,led[5]01。當數到10秒時,即end_cnt_10s時,led[5]10

上電后,led[6]點亮7s,熄滅3s,再點亮7s,熄滅3s。也就是數到7秒時,即add_cnt_10s &&cnt_10s==7-1時,led[6]01。當數到10秒時,即end_cnt_10s時,led[6]10

上電后,led[7]點亮8s,熄滅2s,再點亮8s,熄滅2s。也就是數到8秒時,即add_cnt_10s &&cnt_10s==8-1時,led[7]01。當數到10秒時,即end_cnt_10s時,led[7]10

由此便可以將所有的led信號設計出來。

下面是led的代碼。

  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[0] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[0] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==1-1)begin
  
led[0] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[1] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[1] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==2-1)begin
  
led[1] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[2] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[2] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==3-1)begin
  
led[2] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[3] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[3] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==4-1)begin
  
led[3] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[4] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[4] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==5-1)begin
  
led[4] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[5] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[5] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==6-1)begin
  
led[5] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[6] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[6] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==7-1)begin
  
led[6] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[7] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[7] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==8-1)begin
  
led[7] <= 1;
  
     end
  
end  
  


1.1.5參考設計代碼

  
module pwmled(
  
clk    ,
  
rst_n  ,
  
     led     
  
);
  
  
input             clk        ;
  
input             rst_n       ;
  
output   [ 7:0]    led        ;
  
reg       [25:0]   cnt_1s      ;
  
wire             add_cnt_1s ;
  
wire             end_cnt_1s ;
  
reg      [ 7:0]    cnt_10s     ;
  
wire             add_cnt_10s;
  
wire             end_cnt_10s;
  
reg      [ 7:0]    led          ;
  
  
  
  
  
always @(posedge clk or negedgerst_n)begin
  
     if(!rst_n)begin
  
         cnt_1s <= 0;
  
    end
  
     else if(add_cnt_1s)begin
  
         if(end_cnt_1s)
  
             cnt_1s <= 0;
  
         else
  
             cnt_1s <= cnt_1s + 1;
  
     end
  
end
  
  
assign add_cnt_1s = 1;
  
assign end_cnt_1s = add_cnt_1s &&  cnt_1s==50_000_000 -1 ;
  
  
  
  
  
always @(posedge clk or negedgerst_n)begin  
  
     if(!rst_n)begin
  
         cnt_10s <= 0;
  
     end
  
     else if(add_cnt_10s)begin
  
         if(end_cnt_10s)
  
             cnt_10s <= 0;
  
         else
  
             cnt_10s <= cnt_10s + 1;
  
     end
  
end
  
  
assign add_cnt_10s = end_cnt_1s;
  
assign end_cnt_10s = add_cnt_10s  && cnt_10s==10-1 ;
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[0] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[0] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==1-1)begin
  
led[0] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[1] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[1] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==2-1)begin
  
led[1] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[2] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[2] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==3-1)begin
  
led[2] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[3] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[3] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==4-1)begin
  
led[3] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[4] <= 0;
  
    end
  
     else if(end_cnt_10s)begin
  
led[4] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==5-1)begin
  
led[4] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[5] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[5] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==6-1)begin
  
led[5] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[6] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[6] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==7-1)begin
  
led[6] <= 1;
  
     end
  
end
  
  
  
  
  
always   @(posedge clk or negedgerst_n)begin
  
     if(rst_n==1'b0)begin
  
led[7] <= 0;
  
     end
  
     else if(end_cnt_10s)begin
  
led[7] <= 0;
  
     end
  
     else if(add_cnt_10s && cnt_10s==8-1)begin
  
led[7] <= 1;
  
     end
  
end  
  
endmodule
  



1.2 效果和總結

  • 時間經過1秒之后




  • 時間經過4秒的時候





  • 時間經過8秒的時候



看上面的現象,可以發現,跟設計目標要求的都是一樣的,成功完成設計目標。


我們的至簡設計法和計數器模板在以上的設計中發揮了至關重要的作用,使設計能夠快速準確完成。本設計中的led信號的代碼為了方便理解,把8led燈分開寫了,希望有興趣的同學可以將led的代碼進行簡化,合成一個always,想不到也沒關系,在講解視頻中也有講述如何實現。


感興趣的朋友也可以訪問明德揚論壇(http://www.fpgabbs.cn/)進行FPGA相關工程設計學習,也歡迎大家在評論與我進行討論!

【設計教程下載】

 PWM流水燈V2.0.pdf (696.4 KB, 下載次數: 0)


【設計視頻教程】


http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=1041&page=1&extra=#pid1805(點擊鏈接跳轉明德揚論壇觀看)



【工程源碼】    01_PWM_waterfall_light.rar (8.23 KB, 下載次數: 0)


   拓展閱讀
主站蜘蛛池模板: 日韩精品在线观看免费 | 黄色va| 久久国产高清一区二区三区 | 综合图色 | 欧美在线a级高清 | 我就色色综合网 | 在线亚洲免费 | 一级一黄在线观看视频免费 | 视频国产一区 | 可以免费观看的黄色网址 | 欧美日韩在线观看一区二区 | 久久精品国产99精品国产2021 | 福利一区视频 | 成人性色大片 | 成人做爰免费看网站 | 中文字幕1页 | 国产精品毛片 | 综合久青草视频 | 欧美日韩大尺码免费专区 | 免费三片在线观看网站 | 中文字幕欧美日韩久久 | 国产精品一区二区不卡的视频 | 国产高清久久 | 韩国黄色一级毛片 | 欧美日本一道高清二区三区 | 国产51| 日韩三级一区二区 | 亚洲毛片 | 亚洲 欧美 日韩中文字幕一区二区 | 国产福利91 | 欧美一级特黄特色大片 | 国产伦精品一区二区三区网站 | 日本aaaa特级毛片 | 黄色午夜影院 | 欧美天天射 | 男女自偷自拍视频免费观看篇 | 日韩在线视频线视频免费网站 | 亚洲成年网站在线观看 | 成人午夜大片免费7777 | 久久东京伊人一本到鬼色 | 国产一区二区三区亚洲综合 |