• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Key tied to two GPIO pins not functioning correctly

mik3ca

Member
I'm posting this here because it may be more of an electronics issue.

Anyways, I have a program which calls the dkey function to try to get a value based on the key pressed. I have three keys. Two are tied to their own GPIO pins and the third key functions exactly the same as the other two pressed at the same time.

When I press any of the first two keys (tied to its own GPIO pin), this function works fine, but sometimes when I use the third key, it tries to function as if its the first key but I don't understand why.

I set the timer function to execute about every 4096 clock cycles (about 2ms). I put it in timer mode 1 with TH0 as #0E0h and TL0 as #0h.

With my code, I deliberately use a 2ms+ delay along with a shift register approach (for a 16ms+ delay) before a button can be recognized as valid.

The keys in question I'm using are omron B3F-4000.
The diodes I'm using to connect the third key to the first two are 1N914's.

Is my hardware or timing at fault or is it something else?

Code:
    ;Keys are hooked up as:
    ;Button 1 to P1.1
    ;Button 3 to P1.3
    ;Button 2 to P1.1 AND P1.3 (via diodes)


    ALLKEYS equ P1

    KEYCAP equ 2Ch  ;keys captured
    KEY1 bit KEYCAP.1
    KEY2 bit KEYCAP.3

    KEYS equ 2Eh ;Keys detected after scan

    KEY1DOWN bit KEYS.0
    KEY1HELD bit KEYS.1
    KEY1UP bit KEYS.2
    KEY2DOWN bit KEYS.4
    KEY2HELD bit KEYS.5
    KEY2UP bit KEYS.6

    ;Our key data so timer can process new key info while we work
    ;with the old
    IKEY1DOWN bit ACC.0
    IKEY1HELD bit ACC.1
    IKEY1UP bit ACC.2
    IKEY2DOWN bit ACC.4
    IKEY2HELD bit ACC.5
    IKEY2UP bit ACC.6

    ;Mask value to indicate both keys are held
    ;This equals IKEY1HELD and IKEY2HELD
    BOTHHELD equ 22h


    timer:
      mov KEYCAP,ALLKEYS ;capture a new set of keys so we know what key1 and key 2 equal
    reti

    ;here key info is obtained
    getkey:
      ;Load first key
      mov C,KEY1
      mov A,UKEY1
      ;and put it into an 8-bit shift register named UKEY1
      ;this register changes value almost everytime we ask for a key
      rlc A
      mov UKEY1,A
      ;If register value=0 then key is held down (held for at least 8 key info requests)
      ;since press connects port pin to ground
      jnz nokeyp1h
        setb KEY1HELD
      nokeyp1h:
      ;Set key down since key is held for at least 4 key info requests
      cjne A,#0F0h,nokeyp1
        setb KEY1DOWN
      nokeyp1:
      ;Set key up since key is let go for at least 4 key info requests
      cjne A,#00Fh,nokeyp1b
        clr KEY1HELD
        setb KEY1UP
      nokeyp1b:
      ;The following is a repeat but for the other port pin connected to the keys.
      mov C,KEY2
      mov A,UKEY2
      rlc A
      mov UKEY2,A
      jnz nokeyp2h
        setb KEY2HELD
      nokeyp2h:
      cjne A,#0F0h,nokeyp2
        setb KEY2DOWN
      nokeyp2:
      cjne A,#00Fh,nokeyp2b
        clr KEY2HELD
        setb KEY2UP
      nokeyp2b:
      ;Load keys to accumulator so we can deal with them then reset keys value
      mov A,KEYS
      mov KEYS,#0h
      clr C
    ret

    ;Function is called in main program to get a button press. Stall if nothing is pressed
    dkey:
      acall getkey ;get key info
      mov B,A ;save key value
      anl A,#BOTHHELD ;check to see if both keys are held down
      cjne A,#BOTHHELD,o3
        mov A,#08h ;it is so return 8
        ret
      o3:
      mov A,B ;restore key value
      jnb IKEY1HELD,o1
        clr A ;Key one held down
        ret
      o1:
      jnb IKEY2HELD,o2
        mov A,#04h ;Key 2 held down
        ret
      o2:
      ;At this point, nothing is held down so rerun the loop
    sjmp dkey
 

Pommie

Well-Known Member
Most Helpful Member
I can't follow your code but it sounds like a timing or bouncing problem. Try reading mulitple times and if active high OR the values together, if active low then AND them together.

Mike.
 

mik3ca

Member
I did try that. I used jnz instruction when comparing UKEYx to see if the key is held down because when it is, the values coming in will be logic lows since one key pin is tied to ground while the other is tied to the gpio pin.

For now, I think I'll try a larger buffer approach and instead of storing bits into one byte, I'll store them into multiple bytes. Basically I'll try code listing 3 from http://www.ganssle.com/debouncing-pt2.htm
 

Latest threads

EE World Online Articles

Loading

 
Top