Hallo zusammen.

Hier nur eine Haarspalterei am Rande, die auch nichts mit der grundsätzlichen Funktionalität zu tun hat. (oberallgeier bitte verzeih mir!)

In deiner Test-Funktion benutzt du folgenden Code:
Code:
    for (ilng = PWMmin; ilng <= PWMmax; ilng++)
     {                           //
       cli();                    // ###
       OCR1B       = ilng;       //
       sei();                    // ###
       waitms (  srvwt);         //
     }           // ### Ende for (ilng = ...
Hier beim Schreiben in das OCRnx-Register kannst du getrost auf das cli() und sei() verzichten. Diese Register sind gepuffert und vertragen eine Unterbrechung durch Interrupts. (Mit der Ausnahme, wenn du in einer beliebigen INT-FNC auf das Register schreibst! Was du in deinen Code-Ausschnitten aber nicht machst.)
Klar, es bleibt, dass beim Lesen leider doch mit INT-sei(n)-oder-nicht-sei(n) gewerkelt werden muss.

Im dicken PDF zu den AVRs (angefangen beim atmega8 bis zum atmega644) ist das so beschrieben:
When the High byte I/O location is written by the CPU, the TEMP Register will be updated by the value written. Then when the Low byte (OCR1xL) is written to the lower eight bits, the High byte will be copied into the upper 8-bits of either the OCR1x buffer or OCR1x Compare Register in the same system clock cycle.


Aber wie gesagt: Hat nichts mit der eigentlichen Funktion zu tun. (Soll nur Bytes sparen)

Gruß Sternthaler