按鈕解彈跳計數7段LED顯示器VHDL20240611_seg7_controller
按鈕解彈跳記數7段LED顯示器VHDL20240611_seg7_controller
https://youtube.com/shorts/PQcoAYN7H8I
- clk_4M訊號被控制時脈輸入,用於觸發時脈邊緣的過程。
- counting和訊號分別控制是否rst進行計數和重置計數。countingrst
- seg7_scan是用於掃描選擇七段顯示器的訊號,seg7_out用於輸出七段顯示器的選擇訊號,seg7_sec用於控制秒的訊號。
- v2和v3訊號分別用來儲存兩個四位的整數的值。
- button_1是一個狀態機,idle用於處理按鈕的狀態pressed。訊號為高電平,則切換回狀態。idlepressedpressedcnt2countingidle
- cnt4訊號在時脈的clk_2k上升沿選擇翻轉。cnt4seg7_reg
- 透過seg7_reg中儲存的值來選擇要顯示的七段數碼管的段,將其儲存在seg7_out中輸出。
- 最後,透過將v2和v3中的值分別賦給BCD訊號的低四位元和高四位,輸出到外部。
- 實現一個控制七段顯示器的狀態機,它按鈕控制計數開始/停止和重設功能,並根據計數結果選擇要顯示的數字。
題
背景:
在數位電路設計中,按鍵的彈跳問題是一個常見的挑戰。
要
設計一個按鍵去振動計數器和七段LED顯示器控制器。
功能描述:
- 按鍵按下時,計數開始並在七段 LED 顯示器上顯示計數值。
- 當按鍵釋放時,計數停止並保持顯示最後
- 可以透過另一個按鍵清除
- 使用七段LED顯示器顯示計數值,使用
提
- 使用狀態機來實現關鍵的穩定檢測和計數的控制。
- 考慮使用投票來針對按鈕
考
- VHDL設定
- 按鍵去搖晃
- 狀態
- 七段LED
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity VHDL20240611_seg7_controller is
port(
clk_4M:in std_logic;
counting:in std_logic;
rst:in std_logic;
seg7_scan:out std_logic_vector(3 downto 0);
seg7_out:out std_logic_vector(6 downto 0);
seg7_sec:out std_logic:='0';
BCD:out std_logic_vector(7 downto 0));
end VHDL20240611_seg7_controller;
architecture aa of VHDL20240611_seg7_controller is
signal cnt1:integer range 0 to 1999:=0;
signal clk_2k:std_logic:='0';
signal v3, v2:std_logic_vector(3 downto 0):="0000";
type button_state is (idle, pressed);
signal button_1:button_state:=idle;
signal cnt2:integer range 0 to 99:=0;
signal cnt4:std_logic:='0';
signal seg7_reg:std_logic_vector(3 downto 0);
begin
process(clk_4M)
begin
if rising_edge(clk_4M) then
if cnt1=1999 then
cnt1<=0;
clk_2k<=not clk_2k;
else
cnt1<=cnt1+1;
end if;
end if;
end process;
process(clk_2k,rst)
begin
if rising_edge(clk_2k) then
cnt4<=not cnt4;
if rst='0' then
v3<="0000";
v2<="0000";
else
case button_1 is
when idle =>
if counting='0' then
if v2="1001" then
v2<="0000";
if v3="1001" then
v3<="0000";
else
v3<=v3+1;
end if;
else
v2<=v2+1;
end if;
button_1<=pressed;
cnt2<=0;
end if;
when pressed=>
if cnt2=99 then
cnt2<=0;
if counting='1' then
button_1<=idle;
end if;
else
cnt2<=cnt2+1;
end if;
end case;
end if;
end if;
end process;
process(cnt4)
begin
case cnt4 is
when '0'=>
seg7_scan<="1110";
seg7_reg<=v2;
when '1'=>
seg7_scan<="1101";
seg7_reg<=v3;
end case;
end process;
seg7_out<= "1000000" when seg7_reg="0000"else
"1111001" when seg7_reg="0001"else
"0100100" when seg7_reg="0010"else
"0110000" when seg7_reg="0011"else
"0011001" when seg7_reg="0100"else
"0010010" when seg7_reg="0101"else
"0000010" when seg7_reg="0110"else
"1111000" when seg7_reg="0111"else
"0000000" when seg7_reg="1000"else
"0011000" when seg7_reg="1001"else
"1111111";
seg7_sec<='1';
BCD(7 downto 4)<=v3(3 downto 0);
BCD(3 downto 0)<=v2(3 downto 0);
end aa;
留言
張貼留言