Un tutorial mai vechi legat de debounce pe mai multe porturi.

Recently I faced a problem that gave me headaches. For an application I need to debounce 7 push buttons witch were connected on different ports. Searching the internet I found two ways to do this, namely: hardware method that involves an extra circuit and a software method that involves only code changes. Due to the fact that I’m not a hardware expert but also because I didn’t want to further complicate the circuit I have chosen the software method. Next I will discuss the method used by me to solve this problem detailing a bit principles used and finally I will present you a working example.

Development board – I still use my old card „ATMEGA8 DevBRD” with programming via serial port
AVR-GCC – one of the best C compilers for AVR
2 or more push buttons
Time: 30-45 min.

Take the example of a circuit consisting of a microcontroller which is connected to an LED and a push button.

What we want to happen is that when you press the button, the LED to be switched on and when you press again the button LED to be switched off.

A code example written in C would be the following:


The only problem is that the circuit works in a chaotic manner. And if you look very carefuly you can see that the LED will blink intermittently when pressing the button. This blinking effect is seen best on incandescent light bulbs.

If you wonder why this happens let’s look at the chart below and see what happens when you press the button.

Because the contacts inside the button are elastic, when contacts are touching each other there will be a variation of some milliseconds between position open/closed of the switch, which is observed on the chart above.

As I said above to eliminate the effect of „bouncing” there are 2 methods.

a.) Hardware method

May be of 2 types, namely:

a1.) RC


Image collected on a PmWiki
For more details on how debouncing hardware works please see the following link: http://www.elexp.com/t_bounc.htm

b.)Software method

b1.) Pooling method

Do you remember our test program? If so, lets create a procedure for debounce.

Have you seen the difference? Simple and to the point. The only thing I hate at this method is that when the button is hold, the LED will turn on / off making a light organ effect.

If you want to know more about the pooling method I suggest you read the following article: http://www.micahcarrick.com/05-15-2006/avr-tutorial-switch-debounce.html

b2.) Timers method

We will not modify our program using the timers method because we will discuss it later when we speak about virtual port. The best code for the timer method I discovered on Peter Fleury page. For more details please check the link below.

3.Problem and solution

The problem I faced recently was that I needed 7 inputs on the microcontroller but I had a free port with 6 pins and on another port I had 1 pin. To all these inputs I had connected push buttons. The circuit was controlling incandescent bulbs where the bounce effect is clearly visible, so all inputs had to be debounched. First I tried the pooling method but I disliked because it create an effect of light organ. After more searches on the Internet and many other headaches I seem to have found the perfect solution with the timers method and creating a virtual port.

I divided this part of the article in:

a.) How to create a virtual port

b.) Intrerupts procedure

c.) Access to buttons

d.) Functional example

The circuit on which we will discuss is the following:

a.) How to create a virtual port
In the following I will try to explain how to create a virtual port with the logical functions of C.
Circuit as shown above have switches connected to PC0-5 and on PB0, therefore virtual port will have the following form:


To define it in C we will need a variable „unsigned integer” and because our port has not more than 8 bits, will be a 8-bit variable. In conclusion the following command will be used:

OK, we defined our virtual port but now let’s see what means “((PINC & 0x3f) << 1) | (PINB & 0x01)”

PINC-represents the input bits of port c from the microcontroler and has the following form PC7;PC6;PC5;PC4;PC3;PC2;PC1;PC0
0X3F-represents 00111111
PINB– represents the input bits of port b from the microcontroler and has the following form PB7;PB6;PB5;PB4;PB3;PB2;PB1;PB0
0X01-represents 00000001
& – represents bitwise and
| – represents bitwise or
<< -represent left shift bit
By evaluating the expression ((PINC & 0x3f) << 1) | (PINB & 0x01) we see the folowing


1 (1)

2 (1)
(PINC & 0x3f) <<1

3 (1)
((PINC & 0x3f) << 1) | (PINB & 0x01)

Finaly our virtual port “PORTVIRT” looks like this:
that is exactly what we wanted.

b.) Intrerupts procedure
Intrerupts procedure looks something like this:

I think the comments attached to lines of code are enough to explain it. The only change made to this procedure was to add the line defining the virtual port within the procedure to have all the time the last status of the bits.

c.) Access to buttons

We are almost finish. The next step is to query the status of the buttons in our circuit. For this use the following line of code:


Where 0x01 will change depending on the pin that we want to interrogate.

0X01 – 00000001 -represent PB0
0X02 – 00000010 -represent PC0
0X40 – 01000000 -represent PC5

d.) Functional example
As I have promised you can download the functional example from the link below.
Download here:http://www.roroid.ro/progs/scripts/dvirtualport.c

4.Comments and future reading
Comments and suggestion are always welcomed. Also if you want you can help me improve the code for example to detect double clicks.
If you want to read more on the subject I sugest:

Virtual ports and debouncing

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Acest sit folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.