library IEEE
use IEEE.std_logic_1164.all
use IEEE.std_logic_arith.all
use IEEE.std_logic_unsigned.all
entity debounce is
generic (
CLK_FREQ_MHz : integer := 20--in MHz
BUTTON_PRESS_STATUS : std_logic := '0'
)
port (
reset_n : in std_logic
clk : in std_logic
btnIn : in std_logic
btnPressed: out std_logic
)
end debounce
architecture debounce_arch of debounce is
constant MAX_MS_CNT : integer := CLK_FREQ_MHz * 1000 - 1
signal msCnt: integer range 0 to MAX_MS_CNT
signal msClk: std_logic --做一个毫秒脉冲,每1毫秒对按钮采样一次
signal btnIn_q: std_logic_vector(9 downto 0) --记住最后10次采样
signal btn : std_logic
signal btn_q: std_logic
begin
--产生毫秒脉冲
process(reset_n, clk)
begin
if reset_n = '0' then
msCnt <= 0
msClk <= '0'
elsif rising_edge(clk) then
if msCnt >= MAX_MS_CNT then
msCnt <= 0
msClk <= '1'
else
msCnt <= msCnt + 1
msClk <= '0'
end if
end if
end process
--记住最后10次采样
process(reset_n, clk)
begin
if reset_n = '0' then
btnIn_q <= (others =>not BUTTON_PRESS_STATUS)
elsif rising_edge(clk) then
if msClk = '1' then
btnIn_q <= btnIn_q(btnIn_q'left-1 downto 0) &btnIn
else
btnIn_q <= btnIn_q
end if
end if
end process
process(reset_n, clk)
variable all_samples_are_pressed : std_logic_vector(btnIn_q'left downto 0) := (others =>BUTTON_PRESS_STATUS)
begin
if reset_n = '0' then
btn <= '0'
btn_q <= '0'
elsif rising_edge(clk) then
if btnIn_q = all_samples_are_pressed then
btn <= '1' --最后10次采样都是按下状态,就确认按钮按下(10ms消抖)
elsif btnIn_q = not all_samples_are_pressed then
btn <橘唯派= '0' --最后10次采样都是抬起状态,就确认按钮抬起(10ms消抖)
else
btn <= btn --否则保持不变
end if
btn_q <山行= btn
end if
end process
btnPressed <= '1' when btn = '1' and btn_q = '0' else '0' --按钮按下上升沿检测
end debounce_arch
(2)做一个加法器,存到文件adder.vhd
library IEEE
use IEEE.std_logic_1164.all
use IEEE.std_logic_arith.all
use IEEE.std_logic_unsigned.all
entity adder is
port (
reset_n : in std_logic
clk : in std_logic
adderEn : in std_logic
data : out std_logic_vector(3 downto 0)
dataValid: out std_logic
)
end adder
architecture adder_arch of adder is
signal cnt : std_logic_vector(3 downto 0)
begin
process(reset_n, clk)
begin
if reset_n = '0' then
cnt <= x"0"
dataValid <= '0'
elsif rising_edge(clk) then
if adderEn = '1' then--将被替换成,按钮按下时,计数+1
if cnt >= x"9" then
cnt <= x"0"
else
cnt <= cnt + 1
end if
dataValid <= '1'
else
cnt <= cnt
dataValid <= '0'
end if
end if
end process
data <= cnt
end adder_arch
(3)做7段数码管显示,存到文件SevenSegment.vhd
library IEEE
use IEEE.std_logic_1164.all
use IEEE.std_logic_arith.all
use IEEE.std_logic_unsigned.all
entity SevenSegment is
generic (
LED_ON : std_logic := '0'
)
port (
reset_n : in std_logic
clk : in std_logic
data : in std_logic_vector(3 downto 0)
dataValid: in std_logic
ledOut : out std_logic_vector(6 downto 0)
)
end SevenSegment
architecture SevenSegment_arch of SevenSegment is
constant LED_OFF : std_logic := not LED_ON
signal led : std_logic_vector(6 downto 0)
begin
-- --a--
-- |f|b
-- --g--
-- |e|c
-- --d--
process(reset_n, clk)
begin
if reset_n = '0' then
led <= LED_ON &LED_ON &LED_ON &LED_ON &LED_ON &LED_ON &LED_OFF--display 0
elsif rising_edge(clk) then
if dataValid = '1' then
case data is --a b c d e f g
when x"0" =>
led <= LED_ON &LED_ON &LED_ON &LED_ON &LED_ON &LED_ON &LED_OFF--display 0
when x"1" =>
led <= LED_OFF &LED_ON &LED_ON &LED_OFF &LED_OFF &LED_OFF &LED_OFF--display 1
when x"2" =>
led <= LED_ON &LED_ON &LED_OFF &LED_ON &LED_ON &LED_OFF &LED_ON --display 2
when x"3" =>
led <= LED_ON &LED_ON &LED_ON &LED_ON &LED_OFF &LED_OFF &LED_ON --display 3
when x"4" =>
led <= LED_OFF &LED_ON &LED_ON &LED_OFF &LED_OFF &LED_ON &LED_ON --display 4
when x"5" =>
led <= LED_ON &LED_OFF &LED_ON &LED_ON &LED_OFF &LED_ON &LED_ON --display 5
when x"6" =>
led <= LED_ON &LED_OFF &LED_ON &LED_ON &LED_ON &LED_ON &LED_ON --display 6
when x"7" =>
led <= LED_ON &LED_ON &LED_ON &LED_OFF &LED_OFF &LED_OFF &LED_OFF--display 7
when x"8" =>
led <= LED_ON &LED_ON &LED_ON &LED_ON &LED_ON &LED_ON &LED_ON --display 8
when x"9" =>
led <= LED_ON &LED_ON &LED_ON &LED_ON &LED_OFF &LED_ON &LED_ON --display 9
when others =>
led <= (others =>LED_OFF)
end case
else
led <= led
end if
end if
end process
ledOut <= led
end SevenSegment_arch
(4)最后,综合到一起,存到文件top.vhd
library IEEE
use IEEE.std_logic_1164.all
use IEEE.std_logic_arith.all
use IEEE.std_logic_unsigned.all
entity top is
generic (
CLK_FREQ_MHz : integer := 20--可以修改成你的系统时钟频率,以MHz为单位
BUTTON_PRESS_STATUS : std_logic := '0' --指定按钮按下时,是逻辑0还是1
LED_ON : std_logic := '0'--指定数码管点亮需要输出0还是1
)
port (
reset_n : in std_logic
clk : in std_logic
btnIn : in std_logic
ledOut : out std_logic_vector(6 downto 0)
)
end top
architecture top_arch of top is
component debounce
generic (
CLK_FREQ_MHz : integer := 20--in MHz
BUTTON_PRESS_STATUS : std_logic := '0'
)
port (
reset_n : in std_logic
clk : in std_logic
btnIn : in std_logic
btnPressed: out std_logic
)
end component
component adder
port (
reset_n : in std_logic
clk : in std_logic
adderEn : in std_logic
data : out std_logic_vector(3 downto 0)
dataValid: out std_logic
)
end component
component SevenSegment
generic (
LED_ON : std_logic := '0'
)
port (
reset_n : in std_logic
clk : in std_logic
data : in std_logic_vector(3 downto 0)
dataValid: in std_logic
ledOut : out std_logic_vector(6 downto 0)
)
end component
signal btnPressed : std_logic
signal data : std_logic_vector(3 downto 0)
signal dataValid : std_logic
begin
debounce_inst : debounce
generic map (
CLK_FREQ_MHz =>CLK_FREQ_MHz, --in MHz
BUTTON_PRESS_STATUS =>BUTTON_PRESS_STATUS
)
port map(
reset_n =>reset_n,
clk =>clk,
btnIn =>btnIn,
btnPressed=>btnPressed
)
addr_inst : adder
port map (
reset_n =>reset_n,
clk =>clk,
adderEn =>btnPressed,
data =>data,
dataValid=>dataValid
)
SevenSegment_inst : SevenSegment
generic map (
LED_ON =>LED_ON
)
port map (
reset_n =>reset_n,
clk =>clk,
data =>data,
dataValid=>dataValid,
ledOut =>ledOut
)
end top_arch
(5)你只要修改top.vhd里generic的定义,设定时钟频率、按钮按下状态和数码管点亮状态即可
想加的话可以加的,我目前在用8.0都,用哪个都无所谓啊,相比还老旁是7.2更好用吧,个人认为的,quartus的仿弯碧真软件是自带的,建立一个仿真文件就可以了 点击开始 新建一个vector waveform file 文件 加载波形就好了 然后不要忘记生成网表文件 在编译就好了 书上的讲解都很详细的。闹钟模块很好写的,就是在计数的基础上,记到某个数值输出标志位,控制灯亮或者播放音乐都可以,如果是按键去抖的话 就是都到输入的1后,延迟一个时钟周期,就可以了,如果是按键的输入引脚为pin的话
if clk'event and clk = '1' then----这段是很常用的D触发器的写侍闹橡法 其实就是pin_yan<=pin
if pin = '1' then
pin_yan<='1'
else
pin_yan<='0'
end if
end if
主要是利用D出发器,当时钟上升沿捕捉到‘1’后,将该信号延迟了一个时钟周期,在下一个时钟周期变为‘0’。具体的是
if ret = '1' then ----复位
pin_yan <='0'
elsif clk'event and clk = '1' then
if pin_yan = '0' then
if pin = '1' then
pin_yan<='1' ---经过去抖后的按键信号
else
pin_yan<='0'
end if
end if
if pin_yan = '1' then -------使得该信号为一个周期的信号
pin_yan<='0'
end if
end if
这样就该能够更好的去抖吧
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)