library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity encoder is port ( A : in std_logic; -- input A B : in std_logic; -- input B res: in std_logic; -- reset input clk: in std_logic; -- clock input EN : out std_logic_vector(2 downto 0); -- enable for 7-segment display SSEG: out std_logic_vector(7 downto 0) -- 7-segment display ); end encoder; architecture arch of encoder is signal state: std_logic_vector(3 downto 0); constant S0 : std_logic_vector(3 downto 0):= "0000"; constant S1 : std_logic_vector(3 downto 0):= "0001"; constant S2 : std_logic_vector(3 downto 0):= "0010"; constant S3 : std_logic_vector(3 downto 0):= "0011"; constant S4 : std_logic_vector(3 downto 0):= "0100"; constant S5 : std_logic_vector(3 downto 0):= "0101"; constant S10 : std_logic_vector(3 downto 0):= "1001"; constant S20 : std_logic_vector(3 downto 0):= "1010"; constant S30 : std_logic_vector(3 downto 0):= "1011"; constant S40 : std_logic_vector(3 downto 0):= "1100"; constant S50 : std_logic_vector(3 downto 0):= "1101"; signal encoder_clk : std_logic; signal encoder_rol : std_logic; signal clk_1kHz : std_logic:='0'; signal bcd_counter : std_logic_vector(3 downto 0):="0000"; BEGIN process (clk_1kHz, res) begin if res = '0' then state <= "0000"; elsif clk_1kHz'event and clk_1kHz = '1' then case state is when S0 => encoder_clk <= '0'; encoder_rol <= '0'; if A = '1' and B = '0' then state <= S1; elsif A = '0' and B = '1' then state <= S10; else state <= S0; end if; -- path of the state machine for motion detection in the "increase" direction when S1 => if A = '1' and B = '1' then state <= S2; elsif A = '1' and B = '0' then state <= S1; else state <= S0; end if; when S2 => if A = '0' and B = '1' then state <= S3; elsif A = '1' and B = '1' then state <= S2; else state <= S0; end if; when S3 => if A = '0' and B = '0' then state <= S4; elsif A = '0' and B = '1' then state <= S3; else state <= S0; end if; when S4 => encoder_rol <= '1'; state <= S5; when S5 => encoder_clk <= '1'; state <= S0; -- path of the state machine for motion detection in the "decrease" direction when S10 => if A = '1' and B = '1' then state <= S20; elsif A = '0' and B = '1' then state <= S10; else state <= S0; end if; when S20 => if A = '1' and B = '0' then state <= S30; elsif A = '1' and B = '1' then state <= S20; else state <= S0; end if; when S30 => if A = '0' and B = '0' then state <= S40; elsif A = '1' and B = '0' then state <= S30; else state <= S0; end if; when S40 => encoder_rol <= '0'; state <= S50; when S50 => encoder_clk <= '1'; state <= S0; when others => state <= S0; end case; end if; end process; --clock 1kHz process(clk) variable clock_cnt : integer:=0; begin if rising_edge(clk) then if clock_cnt < 6000 then clock_cnt := clock_cnt+1; else clock_cnt := 0; clk_1kHz <= not(clk_1kHz); end if; end if; end process; --counter mod 10 with encoder_clk as input process(encoder_clk) begin if rising_edge(encoder_clk) then if(encoder_rol = '1') then if(bcd_counter < 10 ) then bcd_counter <= bcd_counter + 1; --encoder knob rotates right else bcd_counter <= "0000"; end if; else if(bcd_counter > 0 ) then bcd_counter <= bcd_counter - 1; --encoder knob rotates left else bcd_counter <= "1001"; end if; end if; end if; end process; --bcd to 7-segment display decoder process(bcd_counter) begin case bcd_counter is --------------------abcdefgp when "0000"=>SSEG<="00000011"; when "0001"=>SSEG<="10011111"; when "0010"=>SSEG<="00100101"; when "0011"=>SSEG<="00001101"; when "0100"=>SSEG<="10011001"; when "0101"=>SSEG<="01001001"; when "0110"=>SSEG<="01000001"; when "0111"=>SSEG<="00011111"; when "1000"=>SSEG<="00000001"; when "1001"=>SSEG<="00001001"; when others=>SSEG<="11111111"; end case; end process; EN <= "110"; end arch;