Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,894 Views

DE2 push buttons question

I have a simple counter in VHDL for DE2-115 (should work with any DE2). KEY0 starts counting, KEY1 stops, KEY2 resets. The output is displayed on 7-seg LEDs HEX0 - HEX3 in hexa digits (to be simple manner). 

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity led_counter_ent is port ( CLOCK_50: in std_logic; -- LEDR : out std_logic_vector(15 downto 0); HEX0 : out std_logic_vector(6 downto 0); HEX1 : out std_logic_vector(6 downto 0); HEX2 : out std_logic_vector(6 downto 0); HEX3 : out std_logic_vector(6 downto 0); HEX4 : out std_logic_vector(6 downto 0) := (others => '1'); HEX5 : out std_logic_vector(6 downto 0) := (others => '1'); HEX6 : out std_logic_vector(6 downto 0) := (others => '1'); HEX7 : out std_logic_vector(6 downto 0) := (others => '1'); KEY : in std_logic_vector(3 downto 0); LEDG : out std_logic_vector(1 downto 0)); end led_counter_ent; architecture behavior of led_counter_ent is signal count : std_logic_vector(24 downto 0) := (others => '0'); signal beat_count: std_logic_vector(15 downto 0) := (others => '0'); signal run : std_logic := '0'; signal reset : std_logic := '0'; procedure segment_proced (signal data : in std_logic_vector(3 downto 0); signal digit : out std_logic_vector(6 downto 0)) is begin case data is when "0000" => digit <= "1000000"; -- 0 when "0001" => digit <= "1111001"; -- 1 when "0010" => digit <= "0100100"; -- 2 when "0011" => digit <= "0110000"; -- 3 when "0100" => digit <= "0011001"; -- 4 when "0101" => digit <= "0010010"; -- 5 when "0110" => digit <= "0000010"; -- 6 when "0111" => digit <= "1111000"; -- 7 when "1000" => digit <= "0000000"; -- 8 when "1001" => digit <= "0010000"; -- 9 when "1010" => digit <= "0001000"; -- A when "1011" => digit <= "0000011"; -- b when "1100" => digit <= "1000110"; -- C when "1101" => digit <= "0100001"; -- d when "1110" => digit <= "0000110"; -- E when "1111" => digit <= "0001110"; -- F when others => digit <= "1111111"; -- switch off end case; end segment_proced; begin buttons_process:process (key(0), key(1), key(2), key(3)) begin -- signals run and reset are set due the first expression in the process - why ?? if (key(1) = '0') then run <= '0'; hex5 <= "1000000"; -- 0 else hex5 <= "1111001"; -- 1 end if; if (key(0) = '1') then hex4 <= "1111001"; -- 1 else hex4 <= "1000000"; -- 0 reset <= '0'; run <= '1'; --run <= not run; -- switch ON/OFF does't work properly - why ?? end if; if (key(3) = '0') then hex7 <= "1000000"; -- 0 run <= not run; -- switch ON/OFF does't work properly - why ?? else hex7 <= "1111001"; -- 1 end if; if (key(2) = '0') then hex6 <= "1000000"; -- 0 reset <= '1'; else hex6 <= "1111001"; -- 1 end if; end process; counter_process:process (clock_50) begin if clock_50 = '1' and clock_50'event then count <= count + 1; --if count = "1111111111001011010000000" then -- 33.527.424 --if count = "111111111001011010000000" then -- 16.750.208 --if count = "110110001001011010000000" then -- 14.194.304 --if count = "100110001001011010000000" then -- 10.000.000 - 200ms if count = "10011000100101101000000" then -- 5.000.000 - 100ms --if count = "111101000010010000000" then -- 2.000.000 - 40ms --if count = "1111010000100100000" then -- 500.000 - 10ms --if count = "1111010000100011111" then -- 499.999 - 10ms proper count <= (others => '0'); -- tik <= not tik; if (run = '1') then beat_count <= beat_count + 1; end if; if (reset = '1') then beat_count <= (others => '0'); end if; end if; end if; end process; segment_proced(beat_count(3 downto 0), hex0); segment_proced(beat_count(7 downto 4), hex1); segment_proced(beat_count(11 downto 8), hex2); segment_proced(beat_count(15 downto 12), hex3); -- ledr <= beat_count; ledg(0) <= run; ledg(1) <= reset; end behavior;I want to have only one button to start/stop the counter (not KEY0 for starting and KEY1 for stopping). But if I use the solution as it is used with KEY3, start/stop is not working properly ('run' is signal to indicate whether to count). run <= not run; Counting will not start/stop reliably with every button push which is not clear to me. 

 

I appreciate any advise, thank you.
0 Kudos
7 Replies
Altera_Forum
Honored Contributor I
35 Views

Right now, KEY is level sensitive. You can make KEY edge-triggered input to counter. For example, a press on KEY will toggle state from STOP to START. Another press on KEY will toggle state from START to STOP. And back and forth.

Altera_Forum
Honored Contributor I
35 Views

I have changed the process like this: 

buttons_process:process (key) begin if ((key(0) = '0' and key(0)'event)) then run <= not run; -- switch ON/OFF does't work properly - why ?? reset <= '0'; end if; if (key(1) = '0') then hex6 <= "1000000"; -- 0 reset <= '1'; else hex6 <= "1111001"; -- 1 end if; end process;but the key is still not toggling properly. If I change key(0) detection to rising edge (key(0) = '1' and key(0)'event) the key shouldn't be working from my opinion. But it is the same inproper toggling. What am I missing ? 

 

Thanks for reply.
Altera_Forum
Honored Contributor I
35 Views

P1: process (key(0)) 

begin 

if (rising_edge(key(0)) then 

run <= not run; 

reset <= '0'; 

end if; 

end process; 

 

P2: process (key(1)) 

begin 

if (rising_edge(key(1)) then 

if (run = '0') then 

hex6 <= hex6 - 1; 

else 

hex6 <= hex6 + 1; 

end if; 

end if; 

 

end process;
Altera_Forum
Honored Contributor I
35 Views

I made more experiments and I feel that there is problem with buttons edge detection on the DE2 board. I tried T flip flop:library ieee; use ieee.std_logic_1164.all; entity t_ff_async is port ( t : in std_logic; r : in std_logic; q : out std_logic; n_q : out std_logic ); end t_ff_async; architecture struct of t_ff_async is begin process (r, t) variable ff : std_logic; begin -- reset if r = '1' then ff := '0'; elsif t'event and t = '1' then ff := not ff; end if; q <= ff; n_q <= not ff; end process; end struct;Toggle is 't' in here - in which I have tested step by step all 4 keys (buttons) on the DE2. Code defines rising edge which is every release of the key (button). I assigned LEDs to Q and n_Q, so LED light should switch with every release of the key (button) which was not 100% event; it sometimes switched also when the button was pressed and then when released. I have also assigned another LEDs to indicate immediate value of the key ledr <= key which is working 100% correct. 

 

So I have reached a view that those type of buttons isn't good to use in applications where edge detection (due electrical characteristic) is needed. Do you think that this could be correct explanation ? 

 

Thanks for reply.
Altera_Forum
Honored Contributor I
35 Views

There are two type of switches KEY and SW. KEY is debounced, SW is NOT debounced. I am using KEY in my NIOS projects. It can register falling edge properly. Try use the falling edge instead to see there is any improvement.

Altera_Forum
Honored Contributor I
35 Views

... I was investigating where should be the the problem but I am still confused :confused:. 

 

I have tried detection of KEY's falling edge (KEY is pressed) and I think it was ~70% successful; else there was detected KEY's release instead of press or it was detected press and release (during one push). Shouldn't be there a problem with voltage setting (there is 2.5V in pin planner) or some voltage bouncing during the falling/rising edge ? I have any other explanation ... 

 

I have also upgraded Quartus from 9.1sp2 to 10.1 but there is no difference.
Altera_Forum
Honored Contributor I
35 Views

I have also confirmed that although there is a debounce it is not good because it doesn't actually make use of a double throw switch. In other words the mechanical characteristic of this cheap switch allows contact-no contact to occur when it is being held depressed. This activity is similar to one methodically pressing and releasing the PB, giving multiple debounced responses. In other words, this kind of debounce can't solve the mechanical switch shortcoming.

Reply