Bouncing button is a well known problem in embedded circuit design. It is due to the fact that the mechanical switch when pressed, producess - other then level transision - a series of spikes of High and Low signals that can be interpreted by CPU as more than one interrupt. As a result a single button press results to a multiple CPU interrupts - which in any case is undesirable.
There are a few well known solutions to the problem which are well documented and easily found online and i will not repeat them but rather describe a simple software solution in the context of acorn kernel.
Let us assume that we have a button connected to INT0 regrdless of the AVR CPU as long as it runs on acorn kernel and have a single task to wait on and process button press.
Our objective is getting rid of the consecutive interrupts generated after the first level transition due to the series of spikes. So all we need to do is accept the first interrupt and filter out all consecutive ones that fall within certain time interval.
Here is the proposed solution in tinyAcorn task.
And the interrupt handler itself.
We will be using a Deffered Procedure Call to serve the external INT0 interrupt. The semantic of DPC states that:
- Deffered Procedure is executed at DEVICE level.
- If the DPC task is in sleep, it will be awaiken to process the DPC.
Task lines (13,19) mark DPC boundery executed at DEVICE level. It simply toggles a LED. Lines (20,22) put the task to sleep at USER level. We need to make sure that code (13,22) executes without the pressence of another interrupt.
In inttrupt handler int0INT code (6,9) disables external interrupt if it is the first spike and queues DPC for processing it. All consecutive spikes during the DPC task sleep are discarded (10,12) thus preventing the DPC task waik up. DPC task sleep time out is determined to fit the speed of the button presses.