I've been struggling with this for a while now, trying to use the PIC I/O pins set to schmitt for hardware debouncing - my original version uses an external schmitt trigger 40106 with the usual capacitor and two resistors on each of the required inputs, with the 40106 feeding the PIC inputs, and using IOC positive edge to generate an interrupt when the buttons (or input signal) are pressed. This works fine, and gives no problems.
But recent PIC's have schmitt inputs (selectable via a register), so I thought dump the 40106, use a newer PIC, and save an IC - I've been trying both the 16F18857 and 18F27K40. However, both chips give the same problem, intermittent multiple presses, which I presumed was down to switch bounce. Obviously without the inverting action of the 40106 I'm now using IOC negative edge, and so trying to find out why I added an extra line of code to toggle an I/O pin in the ISR, so I could try and spot the bouncing on the scope. I'd done this originally when I first started playing with hardware debouncing, and it allowed me to get nice 'clean' shots of the bounce.
However, there was no sign of contact bounce, but while I was repeatedly trying it (with the scope set to single sweep) I noticed a double count on the project display - on checking the scope I noticed the ISR had been triggered twice, once on the falling edge (as expected) but also on the rising edge (which it wasn't set to do).
Here's the scope display, the yellow display is the switch input pin, there's a 1uF to ground, and it's fed from two 22k in series, the blue trace is the output from the ISR toggle. Notice the nice schmitt trigger effect, with a suitable amount of hysteresis between the switching points. I also tried switching the inputs back to TTL, where the hysteresis all but disappears, so it's definately changing the input type as required.
So has anyone got any idea why the ISR should occasionally trigger on the rising edge?, when it's not set to do so - it probably only happens 10% of the time or so. There's three different inputs used, and it's the same on all of them.
For a 'work around' I've taken to checking if the I/O pin is LOW in the ISR, and exiting if it's not - but the older version with the 40106 works perfectly, using a 16F1847
Here's the code from the ISR for one of the buttons, it simply selects between two different modes using the Mode variable.
But recent PIC's have schmitt inputs (selectable via a register), so I thought dump the 40106, use a newer PIC, and save an IC - I've been trying both the 16F18857 and 18F27K40. However, both chips give the same problem, intermittent multiple presses, which I presumed was down to switch bounce. Obviously without the inverting action of the 40106 I'm now using IOC negative edge, and so trying to find out why I added an extra line of code to toggle an I/O pin in the ISR, so I could try and spot the bouncing on the scope. I'd done this originally when I first started playing with hardware debouncing, and it allowed me to get nice 'clean' shots of the bounce.
However, there was no sign of contact bounce, but while I was repeatedly trying it (with the scope set to single sweep) I noticed a double count on the project display - on checking the scope I noticed the ISR had been triggered twice, once on the falling edge (as expected) but also on the rising edge (which it wasn't set to do).
Here's the scope display, the yellow display is the switch input pin, there's a 1uF to ground, and it's fed from two 22k in series, the blue trace is the output from the ISR toggle. Notice the nice schmitt trigger effect, with a suitable amount of hysteresis between the switching points. I also tried switching the inputs back to TTL, where the hysteresis all but disappears, so it's definately changing the input type as required.
So has anyone got any idea why the ISR should occasionally trigger on the rising edge?, when it's not set to do so - it probably only happens 10% of the time or so. There's three different inputs used, and it's the same on all of them.
For a 'work around' I've taken to checking if the I/O pin is LOW in the ISR, and exiting if it's not - but the older version with the 40106 works perfectly, using a 16F1847
Here's the code from the ISR for one of the buttons, it simply selects between two different modes using the Mode variable.
C:
if (IOCBF4) // Mode button was just pressed
{
IOCBF4 = 0; // must clear the flag in software
TestPulse = ~TestPulse; // toggle test I/O pin
if (ModeKey == 0) // check button still pressed
{
mode++; // toggle through modes (0-2)
if (mode==2)
{
mode=0;
}
modechange = 1; // mode changed
display = 1; // update display
}
}