Wenn Du noch einen Timer und eine Interrupt-Eingang frei hast, ginge es auch ganz ohne das Hauptprogramm aufzuhalten:

Du konfiguriertst den Interrupt als "Change", d.h. er wird bei jeder Flanke ausgelöst.
In der ISR checkst Du, ob der Taster gedrückt oder losgelassen wurde (über eine If-Then-Abfrage des INT-Eingangs)
Wurde er gedrückt, startest Du den Timer, der so konfiguriert (bzw. vorgeladen) ist, dass er nach 3 Sek. überläuft.
Wurde er losgelassen, stoppst Du den Timer und setzt ihn zurück.

In der Timer-ISR wird dann eine Bit-Variable auf 1 gesetzt, die in der Hauptschleife abgefragt wird und den dreisekündigen Tastendruck signalisiert (und nach Ausführen der entsprechenden Aktion wieder auf 0 gesetzt wird).