BJ-EPM CPLD开发板:VHDL入门例程2

HDL语言及源代码

6人已加入

描述


  -- 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 <= x"00000";

  elsif (Clk'event AND Clk = '1') then --时钟上升沿

  if ((key_posedge /= "000") OR (key_negedge /= "000")) then --键值边沿标志位复位计数器,此处理目的为消除抖动

  cnt20ms <= x"00000";

  elsif (cnt20ms < 10#1000000#) then --20ms计数

  cnt20ms <= cnt20ms+1;

  else

  cnt20ms <= x"00000";

  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;

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分