Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Keypad Scanner help!

Hi,

I am new to VHDL. I am having issues implementing a 3 x 3 keypad scanner. The similar technique I have used in C code but it doesn't seem to work with VHDL. I scan each column by putting a logic zero on it , then reading each row and looking for a zero which would tell me on which column and row the key has been pressed. In this case however, by using my code below, it only detects keys pressed in the final column (3, 6 , 9) as it is the last test in the process. Could someone please tell me why this is wrong and suggest a proper way to do this. I appreciate your help. Thanks alot in advance.


------------------------------------------------------------------
ENTITY KeypadScanner IS
PORT ( clock_50 : IN STD_LOGIC ;
       LED : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
         Keypad_write : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
         Keypad_read : IN STD_LOGIC_VECTOR (3 DOWNTO 0)
         );
END KeypadScanner;
-------------------------------------------------------------------
ARCHITECTURE behaviour of KeypadScanner IS
SIGNAL delay : INTEGER:= 1000;
BEGIN
PROCESS (clock_50)
BEGIN
    
    Keypad_write <= "0111" after 10000 ns; --put logic zero on 1st column and scan the rows
    If (Keypad_read = "0111" ) THEN
        LED<= "00000001";
    ELSIf (Keypad_read = "1011") THEN
        LED<= "00000100";
    ELSIf (Keypad_read = "1101") THEN
        LED<= "00000111";
    END IF;
        
    Keypad_write <= "1011" after 10000 ns;--put logic zero on 2nd column and scan the rows
    If (Keypad_read = "0111") THEN
        LED<= "00000010";
    ELSIf (Keypad_read = "1011") THEN
        LED<= "00000101";
    ELSIf (Keypad_read = "1101") THEN
        LED<= "00001000";
    END IF;
    
    Keypad_write <= "1101" after 10000 ns;--put logic zero on 3rd column and scan the rows
    If (Keypad_read = "0111") THEN
        LED<= "00000011";
    ELSIf (Keypad_read = "1011") THEN
        LED<= "00000110";
    ELSIf (Keypad_read = "1101") THEN
        LED<= "00001001";
    END IF;
    
    
END PROCESS;
END behaviour;

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi, do you pulse_10us is really 20ns high (=period of clock_50) ? I have a doubt.

    Do you scope the row and col of your keypad ?

    row = key_write, col = key_read ?

    I have simulated your design,

    LED are dangling with 1,2,3 or 4,5,6 or 7,8,9, (each same row) You have to stop scanning when you encounter a key press.

    The final value of LED depends at which moment you depress the key. BUT your description on the post above let me think that you may have wrong connection between FPGA and Keypad.

    Regards
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for taking time to investigate this. My pulse is 10us high. When scanning the keypad, I write a zero on each column and read the rows. This works fine when I implement the same technique in software and run it on the NIOS. How do I stop scanning when I encounter a key press here in this case? Sorry, I am new to VHDL. I have done lots of software programming at college but I am determined to learn VHDL on my own.