001:FPGA入門——呼吸燈

  在一家作嵌入式公司實習已經兩個月了,須要學習整理的東西不少。決定堅持寫一些總結,留下一些記憶更有意義。呼吸燈這個題目剛拿到沒有思路,網上的參考示例也沒有找到合適的,不過最後找到一個YHXT機構(不是廣告,很簡單的實現了這個功能,放到博客一塊兒學習。控制LED的亮度變化,就是要控制電壓,讓電壓高低變化,是一個電壓從低到高再到低的一個線性變換過程。這裏用PWM控制電壓最合適。產生PWM須要分別產生載波信號和調製信號,最後對二者的大小進行比較產生pwm學習

  載波用cnt1計數器生成一個鋸齒波就是載波。這裏計數器cnt1從0開始計數到N,計數到最大值再次從0開始計數,不斷的循環計數。cnt1的最大值是N-1。根據你的時鐘(系統時鐘,FPGA的工做時鐘,大多狀況是50mhz,我這裏用的是40mhz,25ns)來計數,每來一次時鐘上升沿計數器加一。那麼從0到N-1,所需的時間就是N*T。這個就是一個鋸齒波的週期。spa

  調製信號呼吸燈是一個亮度又低到高再到低的過程,這裏再用一個計數器cnt2生成一個三角波,這個三角波的週期就是呼吸燈工做一次的週期。三角波計數器從0到最大值N ,至關於對調製信號N等份,每個等份是一個載波週期。這裏有一個公式   N^2 * T = 呼吸燈週期/2 。知道呼吸燈週期和時鐘的狀況下容易獲得計數器最大值N。(這裏爲了方便,我設置整個led週期5s,T = 25ns,則N = 10000。)這裏至關於cnt1計數到最大值,cnt2加一。當cnt2從0計數到N-1的過程就是一個上升的斜線,由N-1遞減到0就是降低的斜線。在cnt2計數到最大值時設置一個標誌位信號flag,flag爲1,表明開始遞減。blog

  大小比較經過載波和調製信號的大小比較,就能夠生成一個pwm波。載波大於調製信號時,pwm = 0,載波小於調製信號時,pwm =1。input

 

 

verilog邏輯代碼:博客

module hxled(clk,led1,led2);it

input clk;//系統時鐘40mhzio

output led1;
output led2;//這裏兩個led交替呼吸table

reg [13:0]cnt1;
reg [13:0]cnt2;
reg flag;//標誌位
parameter N = 10000;// 計數值最大值,一次暗亮暗的時間是5s
//cnt1
always@(posedge clk) begin
if(cnt1 == N - 1)
cnt1 <= 1'b0;
else
cnt1 <= cnt1 + 1'b1;
endtest

//cnt2
always@(posedge clk)
begin
if(cnt1 == N - 1) //cnt1計滿一次 cnt2才遞增或遞減
begin
if(!flag)//標誌位爲0時 cnt2加狀態
begin
if(cnt2 == N - 1)
flag <= 1'b1;//cnt2計滿時 標誌位拉高
else
cnt2 <= cnt2 + 1'b1;
end
else
begin
if(cnt2 == 0)
flag <= 1'b0;
else
cnt2 <= cnt2 - 1'b1;
end
end
else
cnt2 <= cnt2;
endmodule

assign led1 = (cnt1 < cnt2)?1'b1:1'b0;//大小比較
assign led2 = ~led1;//兩個燈交替呼吸

endmodule

testbench文件:

`timescale 1ns/1ps
`define clock_period 25
module hxled_tb;

reg clk;
wire led1;
wire led2;

hxled u1(
.clk(clk),
.led1(led1),
.led2(led2)
);

initial clk = 1;
always# (`clock_period/2) clk = ~clk;

endmodule

  此次波形比較簡單就不分析仿真波形了,板級驗證經過,要注意quartus軟件的操做。不一樣的工做時鐘能夠更改一下計數器值,也能夠加入復位信號。若是實驗現象不明顯多是計數器值設置的問題。

  再次感謝YH學堂 此次學習 瞭解如何用計數器產生載波信號 調製信號 如何產生PWM 以及控制呼吸燈的原理。

相關文章
相關標籤/搜索