Я не думаю, что есть способ гарантировать это, но это решение может обеспечить приемлемую альтернативу.
Могу ли я предложить не устанавливать флаг, а вместо этого изменять значение?
Вот как это может работать.
1 / Начать значение с нуля.
2 / Каждое 10 мс прерывание, увеличьте это значение на 10 в ISR (процедура обработки прерывания).
3 / Если в главном цикле значение> = 500, вычтите 500 из значения и выполните действия в течение 500 мс.
При изменении значения вам нужно будет внимательно следить за условиями гонки между таймером и основной программой.
Преимущество заключается в том, что функция работает как можно ближе к границам 500 мс независимо от времени ожидания или продолжительности.
Если по какой-то причине ваша функция запускается на 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 */
}
}
}