Es gibt 2 Lösungsansätze:
1. Wenn Du Timeouts > 3,2s brauchst:
------------------------------------
Merk Dir beim Start des Timeouts einen Timestamp:
1 | uint16_t Systemzeit;
|
2 | uint16_t Timestamp;
|
3 | uint16_t Timeout;
|
4 | ...
|
5 | void set_timeout (uint16_t my_Timeout){
|
6 | sei();
|
7 | Timestamp = Systemzeit;
|
8 | cli();
|
9 | Timeout = my_Timeout;
|
10 | }
|
Zum Test, ob der Timeout abgelaufen ist, rechnest Du dann:
1 | sei();
|
2 | my_Systemzeit = Systemzeit);
|
3 | cli();
|
4 | if (Timeout <= (Systemzeit - Timestamp){
|
5 | // Timeout erreicht
|
6 | }
|
Angenommen, beim Start ist die Systemzeit 00FFh:
Dann ist 10 Ticks später die Systemzeit 109h.
Die Rechnung 109h - 000ffh ergibt im 16-Bit-Zahlenraum 0Ah (10dez).
Angenommen, beim Start ist die Systemzeit 0ffffh:
Dann ist 10 Ticks später die Systemzeit 09h.
Die Rechnung 09h - 0ffffh ergibt im 16-Bit-Zahlenraum 0Ah (10dez).
Bei der Berechnung wird ein Überlauf also durch die 16-Bit-Begrenzung
abgeschnitten, das Ergebnis ist automatisch immer, wie von Dir
gewünscht.
Nachteil an dieser Methode:
Du musst mit 2 16-Bit-Variablen arbeiten (und den Speicherplatz
vorhalten).
2. Wenn 3,2s Timeout ausreichen:
--------------------------------
1 | uint16_t Systemzeit;
|
2 | uint16_t Timeout;
|
3 | ...
|
4 | void set_timeout (uint16_t my_Timeout){
|
5 | sei();
|
6 | Timeout = Systemzeit + my_Timeout;
|
7 | cli();
|
8 | }
|
1 | sei();
|
2 | int16_t Timediff = Systemzeit - Timeout;
|
3 | cli();
|
4 | if ( Timediff >= 0){
|
5 | // Timeout erreicht
|
6 | }
|
Nicht vergessen:
Ich gehe mal davon aus, dass die Systemzeit im IR hochgezählt wird. Weil
Zugriffe auf die Systemzeit nicht atomar sind (2 8-Bit Zugriffe), muss
in main() per sei() / cli() der IR kurzfristig gesperrt werden.
Viele Grüße, Stefan