1)實驗平臺:正點原子新起點V2開發板
2)平臺購買地址:https://detail.tmall.com/item.htm?id=609758951113
2)全套實驗原始碼+手冊+視頻下載地址:http://www.openedv.com/thread-300792-1-1.html
3)對正點原子FPGA感興趣的同學可以加群討論:994244016
4)關注正點原子公眾號,獲取最新資料更新

第九章按鍵控制LED燈實驗
按鍵是常用的一種控制器件,生活中我們可以見到各種形式的按鍵,由于其結構簡單,成本低廉等特點,在家電、數碼產品、玩具等方面有廣泛的應用,本章我們將介紹如何使用按鍵控制多個LED的亮滅,
本章包括以下幾個部分
99.1簡介
9.2實驗任務
9.3硬體設計
9.4程式設計
9.5下載驗證
9.1簡介
按鍵開關是一種電子開關,屬于電子元器件類,我們的開發板上有兩種按鍵開關:第一種是本實驗所使用的輕觸式按鍵開關(如圖 9.1.1),簡稱輕觸開關,使用時以向開關的操作方向施加壓力使內部電路閉合接通,當撤銷壓力時開關斷開,其內部結構是靠金屬彈片受力后發生形變來實作通斷的;第二種是自鎖按鍵(如圖 9.1.2),自鎖按鍵第一次按下后保持接通,即自鎖,第二次按下后,開關斷開,同時開關按鈕彈出來,開發板上的電源鍵就是這種開關,

圖 9.1.1 輕觸式按鍵

圖 9.1.2 自鎖式按鍵
9.2實驗任務
使用新起點開發板上的四個按鍵控制四個LED燈,不同按鍵按下時,四個LED燈顯示不同效果,
9.3硬體設計
如圖 9.3.1所示,本實驗使用四個按鍵開關控制四個LED燈,

圖 9.3.1 按鍵電路原理圖
如上圖所示,開發板上的5個按鍵未按下時,輸出高電平,按下后,輸出低電平,
本實驗中,系統時鐘、復位按鍵、按鍵和LED燈的管腳如下表所示,
表 9.3.1 觸摸按鍵控制LED管腳分配圖

對應的TCL約束檔案如下:
set_location_assignment PIN_M2 -to sys_clk
set_location_assignment PIN_M1 -to sys_rst_n
set_location_assignment PIN_E16 -to key[0]
set_location_assignment PIN_E15 -to key[1]
set_location_assignment PIN_M15 -to key[2]
set_location_assignment PIN_M16 -to key[3]
set_location_assignment PIN_D11 -to led[0]
set_location_assignment PIN_C11 -to led[1]
set_location_assignment PIN_E10 -to led[2]
set_location_assignment PIN_F9 -to led[3]
9.4程式設計
我們程式設計最終實作的效果為:無按鍵按下時,LED燈全滅;按鍵1按下時,LED燈顯示自右向左的流水效果;按鍵2按下時,LED燈顯示自左向右的流水效果;按鍵3按下時,四個LED燈同時閃爍;按鍵4按下時,LED燈全亮,
LED在流水效果和閃爍效果在時間間隔均為0.2秒,因此需要在程式中定義一個0.2s的計數器,即每隔0.2s,狀態計數器加一,根據當前按鍵的狀態選擇不同的顯示模式,不同的顯示模式下四個led燈的亮滅隨狀態計數器的值改變,從而呈現出不同的顯示效果,

圖 9.4.1 系統框圖
按鍵控制led模塊的代碼如下所示:
1 module key_led(
2 input sys_clk , //50Mhz系統時鐘
3 input sys_rst_n, //系統復位,低有效
4 input [3:0] key, //按鍵輸入信號
5 output reg [3:0] led //LED輸出信號
6 );
7
8 //reg define
9 reg [23:0] cnt;
10 reg [1:0] led_control;
11
12 //用于計數0.2s的計數器
13 always @ (posedge sys_clk or negedge sys_rst_n) begin
14 if(!sys_rst_n)
15 cnt<=24'd9_999_999;
16 else if(cnt<24'd9_999_999)
17 cnt<=cnt+1;
18 else
19 cnt<=0;
20 end
21
22 //用于led燈狀態的選擇
23 always @(posedge sys_clk or negedge sys_rst_n) begin
24 if (!sys_rst_n)
25 led_control <= 2'b00;
26 else if(cnt == 24'd9_999_999)
27 led_control <= led_control + 1'b1;
28 else
29 led_control <= led_control;
30 end
31
32 //識別按鍵,切換顯示模式
33 always @(posedge sys_clk or negedge sys_rst_n) begin
34 if(!sys_rst_n) begin
35 led<=4'b 0000;
36 end
37 else if(key[0]== 0) //按鍵1按下時,從右向左的流水燈效果
38 case (led_control)
39 2'b00 : led<=4'b1000;
40 2'b01 : led<=4'b0100;
41 2'b10 : led<=4'b0010;
42 2'b11 : led<=4'b0001;
43 default : led<=4'b0000;
44 endcase
45 else if (key[1]==0) //按鍵2按下時,從左向右的流水燈效果
46 case (led_control)
47 2'b00 : led<=4'b0001;
48 2'b01 : led<=4'b0010;
49 2'b10 : led<=4'b0100;
50 2'b11 : led<=4'b1000;
51 default : led<=4'b0000;
52 endcase
53 else if (key[2]==0) //按鍵3按下時,LED閃爍
54 case (led_control)
55 2'b00 : led<=4'b1111;
56 2'b01 : led<=4'b0000;
57 2'b10 : led<=4'b1111;
58 2'b11 : led<=4'b0000;
59 default : led<=4'b0000;
60 endcase
61 else if (key[3]==0) //按鍵4按下時,LED全亮
62 led=4'b1111;
63 else
64 led<=4'b0000; //無按鍵按下時,LED熄滅
65 end
66
67 endmodule
代碼主要分為三個部分,第12至20行對系統時鐘計數,當計數時間達0.2s時,計數器清零,同時使led_control在四個狀態(00,01,10,11)內依次變化,第33至65行利用case陳述句實作對按鍵狀態的檢測,當不同的按鍵按下時,led隨著led_control的變化,被賦予不同的值,
大家可以發現,本次實驗和流水燈實驗計數時間都是0.2s,本次實驗的計數器最大可以計數到9_999_999,而流水燈實驗中計數器的值最大可以計數到10_000_000,事實上,這兩個實驗計數器都是從0開始計數的,本次實驗從0計數到9_999_999,需要10_000_000個時鐘周期,而系統時鐘為20ns,所以計數的時間為0.2s,而流水燈實驗從0計數到10_000_000需要10_000_001個時鐘周期,因此其計數時間實際上比0.2s要多出20ns,
為了驗證我們的程式,我們在modelsim內對代碼進行仿真,
Testbench模塊代碼如下:
1 `timescale 1 ns/ 1 ns
2 module tb_key_led();
3
4 parameter T = 20;
5
6 reg [3:0] key ;
7 reg sys_clk ;
8 reg sys_rst_n;
9
10 wire [3:0] led;
11
12 initial begin
13 key <=4'b1111;//按鍵初始狀態為全斷開
14 sys_clk <=1'b0; //初始時鐘為低電平
15 sys_rst_n <=1'b0; //復位信號初始為低電平
16 #T sys_rst_n <=1'b1; //一個時鐘周期后復位信號拉高
17
18 #600_000_020 key[0] <=0; //0.6s時按下按鍵1
19 #800_000_000 key[0] <=1;
20 key[1] <=0; //0.8s后松開按鍵1,按下按鍵2
21 #800_000_000 key[1] <=1;
22 key[2] <=0; //0.8s后松開按鍵2,按下按鍵3
23 #800_000_000 key[2] <=1;
24 key[3] <=0; //0.8s后松開按鍵3,按下按鍵4
25 #800_000_000 key[3] <=1; //0.8s后松開按鍵4
26
27 end
28
29 always # (T/2) sys_clk <= ~sys_clk;
30 key_led u_key_led(
31 .sys_clk(sys_clk),
32 .sys_rst_n(sys_rst_n),
33 .key(key),
34 .led(led)
35 );
36
37 endmodule

圖 9.4.2 仿真影像
觀察代碼,結合波形分析可知,14至16行代碼為對時鐘信號、復位信號、按鍵信號賦初始值,默認為按鍵全斷開,第0.6s時按下按鍵key0(kye[0]由高電平變為低電平),可觀察到led3至led0依次點亮,呈現自右向左的流水效果;按鍵key1斷開的同時按下按鍵key2,可觀察到led0至led3依次點亮,呈現自左向右的流水效果;按鍵key2斷開的同時按下按鍵key3s,可觀察到led0至led3呈現閃爍效果;按鍵key3斷開的同時按下按鍵key4,可觀察到led0至led3保持全亮,
9.5下載驗證
首先我們打開按鍵控制LED工程,在工程所在的路徑下打開key_led/par檔案夾,在里面找到“key_led.qpf”并雙擊打開,注意工程所在的路徑名只能由字母、數字以及下劃線組成,不能出現中文、空格以及特殊字符等,key_led工程打開后如圖 9.5.1所示,

圖 9.5.1 打開工程
工程打開后通過點擊工具列中的“Programmer”圖示(圖中紅框位置)打開下載界面,
下載界面如圖 9.5.2所示,查看圖中是否已經加載下載檔案(sof檔案),如果沒有,則需要通過點擊“Add File”按鈕添加流水燈工程中key_led/par/output_files目錄下的“key_led.sof”檔案,

圖 9.5.2 下載界面
如下圖 9.5.3所示,將下載器一端連接電腦,另一端與開發板上的JTAG下載口相連接,如下圖所示,然后連接電源線并打開電源開關,

圖 9.5.3 開發板按鍵
開發板電源打開后,在程式下載界面點擊“Hardware Setup”,在彈出的對話框中選擇當前的硬體連接為“USB-Blaster”,然后點擊“Start”將工程編譯完成后得到的sof檔案下載到開發板中,
下載完成后,就可以利用按鍵來控制LED了,如圖 9.5.3所示,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/333498.html
標籤:其他
上一篇:tools - 低代碼開發平臺
