-- filename ﹕ sw_debounce.vhd
-- author ﹕ wuhouhang
-- description ﹕ 三个独立按键控制led灯亮灭
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity sw_debounce is
port(
clk: in std_logic; --50mhz输入时钟
rst_n: in std_logic; --低电平复位信号
key_in: in std_logic_vector (2 downto 0); --三个独立按键,低表示按下
led_out: buffer std_logic_vector (2 downto 0) --发光二极管,分别由按键控制
);
end entity sw_debounce;
--20ms按键消抖处理
--消抖后按键下降沿检测
--led的键值控制
architecture key_control_of_led of sw_debounce is
signal key_inr0: std_logic_vector (2 downto 0); --第一拍按键锁存寄存器
signal key_inr1: std_logic_vector (2 downto 0); --第二拍按键锁存寄存器
signal key_posedge: std_logic_vector (2 downto 0); --按键上升沿标志位,高电平有效一个时钟周期
signal key_negedge: std_logic_vector (2 downto 0); --按键下降沿标志位,高电平有效一个时钟周期
signal cnt20ms: std_logic_vector (19 downto 0); --20ms计数寄存器
signal key_value: std_logic_vector (2 downto 0); --消抖后的键值锁存寄存器
signal key_valuer0: std_logic_vector (2 downto 0); --消抖后第一拍按键锁存寄存器
signal key_valuer1: std_logic_vector (2 downto 0); --消抖后第二拍按键锁存寄存器
signal key_valueneg: std_logic_vector (2 downto 0); --消抖后按键下降沿标志位,高电平有效一个时钟周期
begin
--第一拍按键锁存
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
key_inr0 <= 111;
elsif (clk'event and clk = '1') then --时钟上升沿
key_inr0 <= key_in; --锁存上一拍键值
end if;
end process;
--第二拍按键锁存
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
key_inr1 <= 111;
elsif (clk'event and clk = '1') then --时钟上升沿
key_inr1 <= key_inr0; --锁存上一拍键值
end if;
end process;
--按键边沿检测
key_posedge <= (not key_inr1) and key_inr0; --按键上升沿标志位,高电平有效一个时钟周期
key_negedge <= key_inr1 and (not key_inr0); --按键下降沿标志位,高电平有效一个时钟周期
--20ms计数
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
cnt20ms <= x00000;
elsif (clk'event and clk = '1') then --时钟上升沿
if ((key_posedge /= 000) or (key_negedge /= 000)) then --键值边沿标志位复位计数器,此处理目的为消除抖动
cnt20ms <= x00000;
elsif (cnt20ms < 10#1000000#) then --20ms计数
cnt20ms <= cnt20ms+1;
else
cnt20ms <= x00000;
end if;
end if;
end process;
--消抖后键值锁存
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
key_value <= 111;
elsif (clk'event and clk = '1') then --时钟上升沿
if (cnt20ms = 10#1000000#) then --计数值到20ms
key_value <= key_inr1; --锁存键值
end if;
end if;
end process;
--消抖后第一拍按键锁存
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
key_valuer0 <= 111;
elsif (clk'event and clk = '1') then --时钟上升沿
key_valuer0 <= key_value; --锁存上一拍键值
end if;
end process;
--消抖后第二拍按键锁存
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
key_valuer1 <= 111;
elsif (clk'event and clk = '1') then --时钟上升沿
key_valuer1 <= key_valuer0; --锁存上一拍键值
end if;
end process;
--消抖后按键下降沿检测
key_valueneg <= key_valuer1 and (not key_valuer0); --消抖后按键下降沿标志位,高电平有效一个时钟周期
--led状态控制
process(clk,rst_n)
begin
if (rst_n = '0') then --异步复位
led_out <= 000;
elsif (clk'event and clk = '1') then --时钟上升沿
if (key_valueneg(0) = '1') then --按键0按下
led_out(0) <= not led_out(0); --led0亮灭状态更替
end if;
if (key_valueneg(1) = '1') then --按键1按下
led_out(1) <= not led_out(1); --led1亮灭状态更替
end if;
if (key_valueneg(2) = '1') then --按键2按下
led_out(2) <= not led_out(2); --led2亮灭状态更替
end if;
end if;
end process;
end architecture key_control_of_led;
车灯IC 36V 1A高调光比 LED 恒流驱动 AP5165B
微访谈:灵明光子联合创始人兼首席执行官贾捷阳
采用PWM功率放大器的新型中频电源设计方案
iPhone8回归致敬iPhone4 富士康不再独家供货
web前端程序员到底值多少钱
BJ-EPM CPLD开发板:VHDL入门例程2
智能电网的概念与网络技术架构
C语言putchar函数介绍
PCB电路设计过程中会有什么问题
南京农业大学:基于石墨烯皮肤电极传感器的三合一便携式电子传感系统
是否可以通过在伺服控制之外增加控制回路来提高性能呢?
中科院微电子所:研发电子皮肤传感器不仅能敏锐感受压力,还知道摩擦力大小
NVSRAM在通信设备中的性能和可靠性方面的考虑因素
rfid自动化在厂区生产线智能管理系统的应用
美国芝加哥居民正在要求电信公司停止安装5G天线
如何克服LoRa®终端节点设计中的挑战
加密市场需要怎样去管理
智能电表:解决传统用电弊端
专于智能家居产品与服务领域,智能家居解决方案提供商-古北电子
X-FAB宣布对180nm BCD-on-SOI技术平台进行扩展,推出用于下一代汽车应用的新型高压器件