色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于FPGA按鍵控制LED-ISE操作工具

電子發燒友論壇 ? 來源:FPGA技術江湖 ? 2023-08-16 09:28 ? 次閱讀

本系列將帶來FPGA的系統性學習,從最基本的數字電路基礎開始,最詳細操作步驟,最直白的言語描述,手把手的“傻瓜式”講解,讓電子信息、通信類專業學生、初入職場小白及打算進階提升的職業開發者都可以有系統性學習的機會。

系統性的掌握技術開發以及相關要求,對個人就業以及職業發展都有著潛在的幫助,希望對大家有所幫助。后續會陸續更新 Xilinx 的 Vivado、ISE 及相關操作軟件的開發的相關內容,學習FPGA設計方法及設計思想的同時,實操結合各類操作軟件,會讓你在技術學習道路上無比的順暢,告別技術學習小BUG卡破腦殼,告別目前忽悠性的培訓誘導,真正的去學習去實戰應用。話不多說,上貨。

按鍵控制LED-ISE操作工具

利用按鍵控制LED的要求為:按一下按鍵,改變一下LED的狀態。按鍵按一次,LED由熄滅變為點亮,按鍵再按一次,LED由點亮變為熄滅。

硬件介紹

開發板上面有四個按鍵,當按鍵按下時,將對應的網絡置成低電平;當按鍵釋放時,將對應的網絡置成高電平。

開發板上面有四個LED發光二極管,FPGA輸出高電平時,LED點亮;FPGA輸出低電平時,LED熄滅。

設計原理

通常的按鍵所用開關為機械彈性開關,當機械觸點斷開、閉合時,由于機械觸點的彈性作用,一個按鍵開關在閉合時不會馬上穩定地接通,在斷開時也不會一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動。

按鍵抖動會引起一次按鍵被誤讀多次。為確保CPU對鍵的一次閉合僅作一次處理,必須去除鍵抖動。在鍵閉合穩定時讀取鍵的狀態,并且必須判別到鍵釋放穩定后再作處理。

抖動時間的長短由按鍵的機械特性決定,一般為5ms~10ms。這是一個很重要的時間參數,在很多場合都要用到。按鍵穩定閉合時間的長短則是由操作人員的按鍵動作決定的,一般為零點幾秒至數秒。

我們可以在按鍵和主控設備之間加入消抖電路(消抖芯片電容等),此種方法會增大PCB面積和花費一定的物料費用。大多數的板子直接將按鍵和主控設備相連接,將帶有抖動的波形輸入到主控設備內部,由內部進行消抖處理。

單片機一般采用延遲重采樣的方式進行消抖。當檢測信號為低時,延遲一段時間(一般為20ms),再次檢測信號是否為低,如果為低,則證明按鍵按下,否則認為按鍵沒有按下,繼續下一次檢查。

在FPGA設計時,筆者推薦另外一種方式:持續采樣。當檢測到信號持續為低10ms,認為按鍵按下;當檢測到信號持續為高10ms,認為按鍵釋放。

在設計時,需要考慮到外部的按鍵信號為異步信號,需要進行同步處理。具體請參考附錄2 FPGA中的同步信號、異步信號和亞穩態。

每次按鍵按下的時間的長短不一,經過消抖后,低電平的持續長度長短也不一樣。此長度遠遠大于一個時鐘周期的長度。要求每次按下只能夠切換一次LED的狀態,所以不能夠直接用此電平當做輸出翻轉的使能。

經過消抖的波形,每次按下只有一個下降沿(按鍵按下時)、只有一個上升沿(按鍵釋放時)。所以通過檢測下降沿(上升沿)的變化,產生一個新的信號------脈沖(一個時鐘周期的脈沖),利用此脈沖作為翻轉的使能即可。利用檢測到下降沿的脈沖翻轉時,LED的狀態會在按下時就會改變;利用檢測到上升沿的脈沖翻轉時,LED的狀態會在釋放時發生改變。本設計中采用檢測到下降沿的脈沖進行翻轉。

設計架構和信號說明

本設計模塊命名為key_led。

a1f9a89a-3bc8-11ee-9e74-dac502259ad0.png

在設計中,共分為三個模塊。

key_filter(按鍵消抖模塊):將外部輸入的帶有抖動的波形進行消抖。

edge_check(邊沿檢測模塊):將消抖后的波形進行下降沿檢測,并產生對應的脈沖。

led_ctrl(led控制模塊):利用脈沖,翻轉led的輸出狀態。

a20f2512-3bc8-11ee-9e74-dac502259ad0.png

key_filter設計實現

本設計采用狀態機實現,狀態機的具體原理請參看相關文章。

對key_n信號為異步信號,需要進行同步兩拍,命名為key_n_r和key_n_rr。狀態機的判斷信號為key_n_rr信號。

本設計共分為四個狀態,KEY_OFF(按鍵釋放狀態),SHAKE_ON(按鍵按下時抖動判斷狀態),KEY_ON(按鍵按下狀態),SHAKE_OFF(按鍵釋放時抖動判斷狀態)。

按鍵沒有按下時,一直KEY_OFF狀態,當按鍵信號變為低電平時,就轉入SHAKE_ON狀態,檢測低電平的持續時間。如果持續時間沒有達到T_10ms就變為高電平,則清零計數器并返回KEY_OFF狀態;如果持續時間沒有達到T_10ms并且也一直為低電平,則繼續在SHAKE_ON狀態計數;如果持續時間達到T_10ms并且為低電平,則清零計數器并進入KEY_ON狀態。在KEY_ON狀態,外部輸入為低電平時,則繼續在KEY_ON狀態;如果外部輸出為高電平,則轉入SHAKE_OFF狀態。在SHAKE_OFF狀態,如果持續時間沒有到達T_10ms就變為低電平,則清零計數器并返回KEY_ON狀態;如果持續時間沒有達到T_10ms并且一直為高電平,則繼續在SHAKE_OFF狀態計數;如果持續時間達到T_10ms并且一直為高電平,則清零計數器并轉入KEY_OFF狀態。

在KEY_OFF和SHAKE_ON狀態,認為按鍵沒有按下;在KEY_ON和SHAKE_OFF狀態,認為按鍵為按下;

狀態轉移圖如下:

a2291e7c-3bc8-11ee-9e74-dac502259ad0.png

a24e2938-3bc8-11ee-9e74-dac502259ad0.png

設計代碼為:

module key_filter (
 
 input   wire   clk,
 input   wire   rst_n,
 
 input   wire   key_n,
 
 output  reg   okey_n
);


 parameter T_10ms  = 500_000;


 localparam  KEY_OFF = 4'b0001;
 localparam  SHAKE_ON = 4'b0010;
 localparam  KEY_ON = 4'b0100;
 localparam  SHAKE_OFF = 4'b1000;
 
 reg     [3:0]   c_state;
 reg     [3:0]   n_state;
 reg          key_n_r;
 reg          key_n_rr;
 reg     [18:0]  cnt;
 
 always @ (posedge clk) key_n_r <= key_n;
 ?always @ (posedge clk) key_n_rr <= key_n_r;
 ?
 ?always @ (posedge clk, negedge rst_n) begin
 ? ?if (rst_n == 1'b0)
 ? ? ?c_state <= KEY_OFF;
 ? ?else
 ? ? ?c_state <= n_state;
 ?end
 ?
 ?always @ * begin
 ? ?case (c_state)
 ? ? ?KEY_OFF ? ?: ? ?begin
 ? ? ? ?if (key_n_rr == 1'b1)
 ? ? ? ? ?n_state = KEY_OFF;
 ? ? ? ?else
 ? ? ? ? ?n_state = SHAKE_ON;
 ? ? ?end ?
 ? ?
 ? ? ?SHAKE_ON ? ?: ? ?begin
 ? ? ? ?if (key_n_rr == 1'b1)
 ? ? ? ? ?n_state = KEY_OFF;
 ? ? ? ?else
 ? ? ? ? ?if (cnt < T_10ms - 1'b1)
 ? ? ? ? ? ?n_state = SHAKE_ON;
 ? ? ? ? ?else
 ? ? ? ? ? ?n_state = KEY_ON;
 ? ? ?end
 ? ?
 ? ? ?KEY_ON ? ?: ? ?begin
 ? ? ? ?if (key_n_rr == 1'b0)
 ? ? ? ? ?n_state = KEY_ON;
 ? ? ? ?else
 ? ? ? ? ?n_state = SHAKE_OFF;
 ? ? ?end
 ? ? ?
 ? ? ?SHAKE_OFF ?: ? ?begin
 ? ? ? ?if (key_n_rr == 1'b0)
 ? ? ? ? ?n_state = KEY_ON;
 ? ? ? ?else
 ? ? ? ? ?if (cnt < T_10ms - 1'b1)
 ? ? ? ? ? ?n_state = SHAKE_OFF;
 ? ? ? ? ?else
 ? ? ? ? ? ?n_state = KEY_OFF;
 ? ? ?end
 ? ? ?
 ? ? ?default ?: ? ?n_state = KEY_OFF;
 ? ?endcase
 ?end
 ?
 ?always @ (posedge clk, negedge rst_n) begin
 ? ?if (rst_n == 1'b0)
 ? ? ?cnt <= 19'd0;
 ? ?else
 ? ? ?case (c_state)
 ? ? ? ?KEY_OFF ? ?: ? ?begin
 ? ? ? ? ?cnt <= 19'd0;
 ? ? ? ?end
 ? ? ?
 ? ? ? ?SHAKE_ON ?: ? ?begin
 ? ? ? ? ?if (key_n_rr == 1'b0 && cnt < T_10ms - 1'b1)
 ? ? ? ?cnt <= cnt + 1'b1;
 ? ? ?else
 ? ? ? ?cnt <= 19'd0;
 ? ? ? ?end
 ? ? ? ?
 ? ? ? ?KEY_ON ? ?: ? ?begin
 ? ? ? ? ?cnt <= 19'd0;
 ? ? ? ?end
 ? ? ? ?
 ? ? ? ?SHAKE_OFF ?: ? ?begin
 ? ? ? ? ?if (key_n_rr == 1'b1 && cnt < T_10ms - 1'b1)
 ? ? ? ?cnt <= cnt + 1'b1;
 ? ? ?else
 ? ? ? ?cnt <= 19'd0;
 ? ? ? ?end
 ? ? ? ?
 ? ? ? ?default ? ?: ? ?cnt <= 19'd0;
 ? ? ?endcase
 ?end ?
 ?
 ?always @ (posedge clk, negedge rst_n) begin
 ? ?if (rst_n == 1'b0)
 ? ? ?okey_n <= 1'b1;
 ? ?else
 ? ? ?if (c_state == KEY_ON || c_state == SHAKE_OFF)
 ? ? ? ?okey_n <= 1'b0;
 ? ? ?else
 ? ? ? ?okey_n <= 1'b1;
 ?end


endmodule

(左右移動查看全部內容)

localparam可以定義參數,與parameter的區別在于,parameter定義的參數可以在例化時進行參數修改,而localparam定義的參數在例化時則不能夠修改。定義狀態機狀態時,一般采用localparam的定義方式。在不希望別人修改參數時,也可以定義為localparam。

edge_check設計實現

在一個波形中,如果當前時刻為低電平,上一個時刻為高電平,則認為波形中有一個下降沿;如果當前時刻為高電平,上一個時刻為低電平,則認為波形中有一個上升沿。

在數字電路設計時,可以采用寄存器來存儲上一個時刻的值。

a269ca12-3bc8-11ee-9e74-dac502259ad0.png

在寄存器電路中,Q的值,永遠是上一個CLK的有效邊沿所采樣的D值。因此Q為上一時刻值,而D為當前時刻的值。

設計代碼為:

module edge_check (


 input   wire      clk,  // 50MHz 
 input   wire      wave, // wave in
 
 output  wire      flag_pos, // flag - posedge
 output  wire      flag_neg // flag - negedge
);


 reg            wave_r;
 
 always @ (posedge clk) wave_r <= wave;
 ?
// ?assign flag_pos = (wave == 1'b1 && wave_r == 1'b0) ? 1'b1 : 1'b0;
 ?assign flag_pos = wave & (~wave_r);
 ?
// ?assign flag_neg = (wave == 1'b0 && wave_r == 1'b1) ? 1'b1 : 1'b0;
 ?assign flag_neg = (~wave) & wave_r;


endmodule

(左右移動查看全部內容)

在設計中,注釋掉的兩行代碼和其下方的一行代碼的功能是相同的。例:對于上升沿脈沖來說,現在為1,過去為0即為上升沿。由于寄存器每個時鐘周期都刷新,滿足這個要求的只會存在一個時鐘周期,所以flag_pos為一個時鐘周期的脈沖。

led_ctrl設計實現

本模塊中,利用脈沖進行led狀態的翻轉即可。

設計代碼為:

module led_ctrl (


 input   wire     clk,
 input   wire     rst_n,
 
 input   wire     flag,
 
 output  reg      led
);


 always @ (posedge clk, negedge rst_n) begin
  if (rst_n == 1'b0)
   led <= 1'b0;
 ? ?else
 ? ? ?if (flag == 1'b1)
 ? ? ? ?led <= ~led;
 ? ? ?else ?
 ? ? ? ?led <= led;
 ?end


endmodule

(左右移動查看全部內容)

key_led設計實現

本模塊只是負責將上述的三個模塊按照架構圖的方式進行連接,形成最終的設計。

設計代碼為:

module key_led (


 input  wire      clk,
 input  wire      rst_n,
 input  wire      key_n,
 
 output wire      led
);


 wire          okey_n;
   wire                      flag;


key_filter key_filter_inst(
 
.clk  (clk),
.rst_n  (rst_n),
  
.key_n  (key_n),
  
.okey_n  (okey_n)
);
 
 edge_check edge_check_inst(


  .clk     (clk),  // 50MHz 
  .wave     (okey_n), // wave in
  
  .flag_pos   (), // flag - posedge
  .flag_neg   (flag) // flag - negedge
 );


 led_ctrl led_ctrl_inst(


  .clk     (clk),
  .rst_n    (rst_n),
  
  .flag     (flag),
  
  .led     (led)
 ); 
 
endmodule

(左右移動查看全部內容)

在設計中,采用了按鍵按下時的脈沖(檢測到下降沿的脈沖),按鍵按下時led的狀態即可進行翻轉。

a27dcc88-3bc8-11ee-9e74-dac502259ad0.png

功能仿真

在仿真時,將按鍵消抖中的T_10ms的參數修改為20,即持續時間不超過400ns都不認為是有效按下或者抬起。

仿真代碼如下:

將okey_n、flag信號添加出來。

`timescale 1ns/1ps


module key_led_tb;


 reg       clk;
 reg       rst_n;
 reg       key_n;
 
 wire      led;
 
 key_led key_led_inst(


   .clk    (clk),
   .rst_n   (rst_n),
   .key_n   (key_n),
   
   .led    (led)
  );


 initial clk = 1'b0;
 always # 10 clk = ~clk;
 
 initial begin
  rst_n = 1'b0;
  key_n = 1'b1;
  # 201
  rst_n = 1'b1;
  # 200
//-------------- on shake-------------  
  @ (posedge clk);
  # 2;
  key_n = 1'b0;
  # 320
  @ (posedge clk);
  # 2;
  key_n = 1'b1;
  # 159
  @ (posedge clk);
  # 2;
  key_n = 1'b0;
  # 320
  @ (posedge clk);
  # 2;
  key_n = 1'b1;
  # 159
//--------------------------------------
//---------key on ---------------------  
  @ (posedge clk);
  # 2;
  key_n = 1'b0;
  # 5000
//------------------------------------  
//---------off shake ----------------
  @ (posedge clk);
  # 2;
  key_n = 1'b0;
  # 320
  @ (posedge clk);
  # 2;
  key_n = 1'b1;
  # 159
  @ (posedge clk);
  # 2;
  key_n = 1'b0;
  # 320
//-------------------------------------
//-----------key off----------------  
  @ (posedge clk);
  # 2;
  key_n = 1'b1;
  # 10000
  $stop;
 end


endmodule

(左右移動查看全部內容)

a2997410-3bc8-11ee-9e74-dac502259ad0.png

通過RTL仿真圖,可以清晰的看到okey_n信號將key_n的抖動濾除掉;flag信號為okey_n信號的下降沿時所產生的脈沖;led在flag信號為高時,反正翻轉。

分配管腳、下板測試之前,應該將按鍵消抖里面的T_10ms參數重新改為500_000,否則下板后可能會達不到消抖的效果。

下板觀察現象:

a2adc186-3bc8-11ee-9e74-dac502259ad0.png

下板成功后,可以修改在設計中使用上升沿的脈沖,得到的現象應該是按鍵釋放時,LED的狀態發生反轉。

切記:每次修改代碼,一定要進行重新編譯,否則更改將不會生效。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1629

    文章

    21729

    瀏覽量

    602998
  • led
    led
    +關注

    關注

    242

    文章

    23252

    瀏覽量

    660574
  • Xilinx
    +關注

    關注

    71

    文章

    2167

    瀏覽量

    121304
  • 發光二極管
    +關注

    關注

    13

    文章

    1198

    瀏覽量

    66282
  • 開發板
    +關注

    關注

    25

    文章

    5032

    瀏覽量

    97373

原文標題:【教程分享】FPGA零基礎學習:按鍵控制LED-ISE操作工具

文章出處:【微信號:gh_9b9470648b3c,微信公眾號:電子發燒友論壇】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    STM32按鍵控制LED的亮滅

    使用一個按鍵控制LED的亮滅,按鍵按下時LED亮起,按鍵松開時LED熄滅。通過
    的頭像 發表于 12-11 14:19 ?3784次閱讀
    STM32<b class='flag-5'>按鍵控制</b><b class='flag-5'>LED</b>的亮滅

    FPGA導航按鍵控制LED的方法

    FPGA按鍵控制LED軟件芯片功能代碼代碼解釋軟件軟件使用的是ISE14.6(因為窮沒買7系列,勸大家買個7系列的板子,這個軟件裝著還挺費事,不如Vivado好用,且6和7軟件不通用)
    發表于 01-18 10:31

    LED流水燈設計-ISE操作工具

    燈設計-ISE操作工具在軟件設計時,第一個例程總是“hello world!”,那么學習硬件時,也會有硬件的“hello world”------流水燈。在FPGA開發板上有四個LED
    發表于 03-31 18:44

    按鍵控制LED-ISE操作工具

    LED-ISE操作工具利用按鍵控制LED的要求為:按一下按鍵,改變一下LED的狀態。
    發表于 04-03 19:36

    數碼管驅動設計-ISE操作工具

    設計-ISE操作工具Xilinx ISE 系列實操所使用的開發設備為叁芯智能科技研發的SANXIN B02 FPGA開發板,如果有想入手的大俠,可登陸叁芯智能科技官方淘寶店咨詢以及購買
    發表于 04-04 21:23

    音樂蜂鳴器設計-ISE操作工具

    設計-ISE操作工具Xilinx ISE 系列實操所使用的開發設備為叁芯智能科技研發的SANXIN B02 FPGA開發板,如果有想入手的大俠,可登陸叁芯智能科技官方淘寶店咨詢以及購買
    發表于 04-04 21:46

    IP CORE 之 PLL- ISE 操作工具

    不多說,上貨。IP CORE 之 PLL- ISE 操作工具本篇實現基于叁芯智能科技的SANXIN -B02 FPGA開發板,如有入手開發板,可以登錄官方淘寶店購買,還有配套的學習視頻。Xilinx
    發表于 04-06 16:04

    IP CORE 之 ROM 設計- ISE 操作工具

    不多說,上貨。IP CORE 之 ROM 設計- ISE 操作工具本篇實現基于叁芯智能科技的SANXIN -B02 FPGA開發板,如有入手開發板,可以登錄官方淘寶店購買,還有配套的學習視頻
    發表于 04-07 20:09

    IP CORE 之 RAM 設計- ISE 操作工具

    不多說,上貨。IP CORE 之 RAM 設計- ISE 操作工具本篇實現基于叁芯智能科技的SANXIN -B02 FPGA開發板,如有入手開發板,可以登錄官方淘寶店購買,還有配套的學習視頻
    發表于 04-10 16:43

    IP CORE 之 FIFO 設計- ISE 操作工具

    不多說,上貨。IP CORE 之 FIFO 設計- ISE 操作工具本篇實現基于叁芯智能科技的SANXIN -B02 FPGA開發板,如有入手開發板,可以登錄官方淘寶店購買,還有配套的學習視頻。FIFO
    發表于 04-11 20:50

    數控車床操作工職業標準

    數控車床操作工職業標準(試行)1.職業概況1.1職業名稱:數控車床操作工1.2職業定義:操作數控車床,進行工件車削加工的人員。1.3職業等級:本職業共設四個等級,
    發表于 02-24 15:50 ?14次下載

    利用FPGA DIY開發板實現按鍵控制LED的顯示

    asean的 FPGA DIY 按鍵控制LED顯示的視頻
    的頭像 發表于 06-20 14:06 ?7129次閱讀
    利用<b class='flag-5'>FPGA</b> DIY開發板實現<b class='flag-5'>按鍵控制</b><b class='flag-5'>LED</b>的顯示

    FPGA入門系列實驗教程之按鍵控制LED亮滅的詳細資料說明

    實現按鍵控制LED亮滅。通過這個實驗,掌握采用Verilog HDL語言編程實現按鍵控制LED亮滅方法。
    發表于 06-11 16:50 ?31次下載
    <b class='flag-5'>FPGA</b>入門系列實驗教程之<b class='flag-5'>按鍵控制</b><b class='flag-5'>LED</b>亮滅的詳細資料說明

    【嵌入式】按鍵控制 LED

    【嵌入式】按鍵控制 LED 實驗1. 操作內容2. 原理解釋2.1 實驗箱按鍵電路2.2 實驗箱LED電路2.3 寄存器說明3.
    發表于 10-20 14:21 ?3次下載
    【嵌入式】<b class='flag-5'>按鍵控制</b> <b class='flag-5'>LED</b>

    基于stm32的按鍵控制led亮滅

    基于stm32的按鍵控制led亮滅資料文件分享
    發表于 09-21 15:50 ?39次下載
    主站蜘蛛池模板: 两个奶头被吃得又翘又痛| 幺妹视频福利视频| DASD-700美谷朱里| 亚洲精品无码久久久久A片| 成人免费观看国产高清| 明星三级电影| 在线观看中文字幕国产| 花蝴蝶高清观看免费| 性XXXXX搡XXXXX搡景甜| 国产成人精品精品欧美| 人妻中文字幕无码久久AV爆 | 最新无码专区在线视频| 精品国产九九| 亚洲AV无码久久流水呻蜜桃久色| 国产东北男同志videos网站| 日韩亚洲视频一区二区三区| 不良网站进入窗口软件下载免费| 欧美黑人巨大videos免费| 99久久蜜臀AV免费看蛮| 免费看国产精品麻豆| 99re6久久热在线视频| 蜜臀久久99精品久久久久久做爰 | 爱情岛aqdlttv| 免费黄色网址在线观看| 96精品视频| 妺妺窝人体色777777野大粗| 91国在线产| 暖暖视频大全免费观看| av在线观看网站免费| 強姧伦久久久久久久久| 草莓视频app深夜福利| 日日操日日射| 国产成人免费高清在线观看| 爽娇妻快高h| 国产人妻人伦精品A区| 亚洲精品无码不卡在线播放he| 国产在线精品亚洲二品区| 亚洲乱码在线卡一卡二卡新区 | 亚洲AV永久无码精品老司机蜜桃| 国产午夜精品理论片免费观看| 亚洲国产精品99久久久久久|