| Author |
Message |
spamiam
Joined: 13 Nov 2005
|
|
Posted: 26 May 2006, 16:52 PM Post subject: Switch debounce chip: an interesting option |
|
|
In one of my projects I need to interface with a bunch of switches. Some of these switch actions need immediate response from the CPU, others only need to be polled.
With limited external interrupt resources, multiple switch interrupts becomes an issue.
In the past I have used an OR gate to trigger one interrupt for multiple sources, and so on. I then also needed to have an RS latch as well.
I have also been very happy with RC hardware for debouncing, especially for polled switches.
But I have had some circumstances where I needed to do better, but never pursued it.
Well, the Maxim MAX6816, MAX6817, and MAX6818 are some pretty nice devices. The 16 and 17 are pretty simple 1 and 2 input devices.
The 6818 is a little different. It is an 8 input device with an /Enable pin and a /Change
The /Change is latched and is to be used as an interrupt trigger. It indicates that one of the switches changed its state. The /Enable pin will reset the /Change pin.
The inputs have ESD and clamping to protect the device, and you avoid some risk to the CPU by direct connections to the external world.
I can see this used directly to one of the full 8-input port pins on the ZX (or AVR). The /CH goes to one of the inputs set to trigger on the falling edge. The /EN goes to another pin and is set to OutputLow until it is toggled High/Low to reset the /CH pin.
I think there is a multiplexer chip that will take at least 7 of the inputs and create binary output to 3 of the ZX pins. This technique will save 4 CPU pins (only would save 3 pins if you really need all 8 inputs to be read). I do not recall off hand which multiplexer chip does this function.
-Tony |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 26 May 2006, 18:57 PM Post subject: |
|
|
| Quote: | | I think there is a multiplexer chip that will take at least 7 of the inputs and create binary output to 3 of the ZX pins |
I think that the device you're referring to is known as an encoder (also, a priority encoder). The 74LS148 and 74LS348 are examples of such a device. |
|
| Back to top |
|
 |
spamiam
Joined: 13 Nov 2005
|
|
Posted: 26 May 2006, 21:55 PM Post subject: |
|
|
yeah, I saw those as I was doing a quick check of the hardware as I wrote the message. I don't like the "priority" aspect of the encoder. I bet that most users are interested in ALL the sources equally. These chips will only show you the highest priority active input. If other lower priority inputs are also active you will not see them.
I suppose the solution is to use something like the MC14512B 8 channel data selector.
If you use this, when you get the interrupt, you then count through all 8 channels: read the bit, shift the bit, and read the next.
In this manner you use 3 output pins and 1 input pin to substitute for 8 input pins, and the reading takes more than 8 times longer. OTOH, saving half the pins is not bad....
-Tony |
|
| Back to top |
|
 |
GTBecker
Joined: 18 Jan 2006
Location: Cape Coral
|
|
Posted: 26 May 2006, 22:04 PM Post subject: Switch debounce chip: an interesting option |
|
|
> ... I don't like the "priority" aspect of the encoder.
My mind's eye sees the 74148 called a Priority _Interrupt_ Encoder (but
my yellow TI TTL handbooks are long gone so I might be wrong) suggesting
the original purpose of the part.
Tom |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 26 May 2006, 22:14 PM Post subject: |
|
|
| Quote: | | I don't like the "priority" aspect of the encoder. |
You originally spoke of encoding 8 bits of information (the 8 switch states) with a 3-bit result. The only way to do that is to "throw away" some information. The priority encoder does that by ignoring all but one input, that being the one with the highest priority that is asserted.
If you want all eight binary inputs to have equal priority, you have to retain all eight bits of information. |
|
| Back to top |
|
 |
spamiam
Joined: 13 Nov 2005
|
|
Posted: 28 May 2006, 1:31 AM Post subject: |
|
|
| dkinzer wrote: | | Quote: | | I don't like the "priority" aspect of the encoder. |
You originally spoke of encoding 8 bits of information (the 8 switch states) with a 3-bit result. The only way to do that is to "throw away" some information. The priority encoder does that by ignoring all but one input, that being the one with the highest priority that is asserted.
If you want all eight binary inputs to have equal priority, you have to retain all eight bits of information. |
You are absolutely right. I was having a brain freeze when I wrote the initial message. You either use all 8 bits in a parallel mode, or use a priority encoder, or you use a selector. I think we covered all the possible alternatives at this point.
-Tony |
|
| Back to top |
|
 |
spamiam
Joined: 13 Nov 2005
|
|
Posted: 30 May 2006, 19:03 PM Post subject: |
|
|
I did a little thinking of the implementation of the MAX6818.
If it is set up to monitor up to 8 switches, you can XOR the old byte of 8 switch values with the new byte and get a byte where each bit will be "true" (i.e. a value of 1) if that correxponding switch has changed state.
Here is some pseudocode:
| Code: | TOP:Read port, assign to New_Val
Switch_State = Old_Val XOR New_Val
If (SwitchState AND 1) then execute switch-1 change state
If (SwitchState AND 2) then execute switch-2 change state
If (SwitchState AND 4) then execute switch-3 change state
If (SwitchState AND 8) then execute switch-4 change state
.
.
.
Old_Val = New_Val
LOOP to TOP |
In my case, i might only care if the switch has become "active" (i.e. has grounded its input pin of the MAX6818). In that case the corresponding pin on the ZX will be LOW. I need a Switch_State that will be TRUE if the corresponding pin has changed to LOW, but not if it is HIGH.
In this case I believe that I will get the correct values if I AND the switch state with the inverse of New_VAL as in this code:
| Code: | TOP:Read port, assign to New_Val
Switch_State = (Old_Val XOR New_Val) AND (NOT New_Val)
If (SwitchState AND 1) then execute switch-1 change low state
If (SwitchState AND 2) then execute switch-2 change low state
If (SwitchState AND 4) then execute switch-3 change low state
If (SwitchState AND 8) then execute switch-4 change low state
.
.
.
Old_Val = New_Val
LOOP to TOP |
What to do if you care if a pin is only changed to HIGH is just as simple. Just do not use the inverse of New_Val.
| Code: | | Switch_State = (Old_Val XOR New_Val) AND (New_Val) |
Does this sound reasonable. Is there a more efficient technique of generating the Switch_State?
-Tony |
|
| Back to top |
|
 |
|