それを保証する方法はないと思いますが、この解決策は許容できる代替手段を提供する可能性があります。
フラグを設定するのではなく、値を変更することをお勧めしますか?
これがどのように機能するかです。
1/ 値をゼロから開始します。
2/ 10 ミリ秒の割り込みごとに、ISR (割り込みサービス ルーチン) でこの値を 10 ずつ増やします。
3/ メイン ループで、値が >= 500 の場合、値から 500 を引き、500 ミリ秒のアクティビティを実行します。
値を変更する際には、タイマーとメイン プログラムの間の競合状態に注意する必要があります。
これには、待ち時間や期間に関係なく、関数が 500 ミリ秒の境界にできるだけ近く実行されるという利点があります。
何らかの理由で関数が 1 回の反復で 20 ミリ秒遅れて開始した場合、値は既に 520 であるため、関数はそれを 20 に設定します。つまり、次の反復まで 480 ミリ秒しか待機しません。
それがあなたが望むものを達成するための最良の方法であるように私には思えます。
私は何年もの間8051に触れていませんでした(それがC51がターゲットとしていると仮定すると、あなたの説明を考えると安全な賭けと思われます)が、割り込みができずに50を引く命令があるかもしれません。ただし、アーキテクチャが非常に単純だったことを覚えているようです。そのため、ロード/変更/ストア操作を実行している間、割り込みを無効にするか遅延させる必要があるかもしれません。
volatile int xtime = 0;
void isr_10ms(void) {
xtime += 10;
}
void loop(void) {
while (1) {
/* Do all your regular main stuff here. */
if (xtime >= 500) {
xtime -= 500;
/* Do your 500ms activity here */
}
}
}