Du lässt also Timer1 frei durchlaufen und nutzt derzeit nur den
ICP-Interrupt. Das ist schonmal gut. (es sind alle Wege offen...)
Da du mit 8MHz und Vorteiler 1 arbeitest, läuft der Timer alle 8,192ms
über. Dies kannst du in einem weiteren Interrupt nutzen (ein
Timer1OVF-Interrupt), in dem du eine weitere Variable (Byte) erhöhst,
und bei 122 (entspricht 1 Sekunde) auf 0 setzt und einen Sekundenzähler
(Byte) erhöhst. Das ist im Int schon alles. Denn die ISR soll ja so kurz
wie möglich sein, damit der Capture-Int nicht blockiert wird.
In Main wird dann der Sekundenzähler mit den "Weckzeiten" (für jeden
abzuschalteten Kanal getrennt) verglichen und bei Gleichstand der
betreffende Ausgang abgeschaltet.
Wird ein Ausgang eingeschaltet, dann setzt du "seine Weckzeit" auf
den momentanen Stand des Sekundenzählers + 10. Somit wird 10 Sekunden
später Gleichstand erreicht und der Port abgeschaltet.
Mir ist aufgefallen, dass du in der ISR "oncapture" den Timer1
einliest (Zaehler=Timer1). Wird damit der aktuelle Timerstand
eingelesen, oder der Stand des ICP-Registers von Timer1? Falls möglich,
dann solltest du das ICP-Register einlesen (ich weiß aber nicht, wie das
in BASCOM heißt, in ASM heißt es ICR1H/ICR1L), da dann die Messung
bedeutend genauer wird. Schau dir mal die Architektur des Timers im
AVR-Datenblatt an, dann weißt du was ich meine.
Andere Variante:
Da du in der Mainloop "in jeder Runde" 2ms wartest, kannst du die
Verzögerung auch aus der Mainloop generieren (also ohne OVF-Int). Zähle
einfach eine 16-Bit-Variable (unsigned-int) hoch, das dauert etwa 131s
bis zum Überlauf. Eine Sekunde entspricht etwa 500, für 10 Sekunden
müsstest du also 5000 zum aktuellen Stand addieren. Der Vergleich geht
wie oben beschrieben, nur dass es mehr RAM verbraucht und mehr
Maschinencode (Flash) erzeugt, da mit 16 Bit gearbeitet wird.
Viel Erfolg...
...HanneS...