В моем проекте есть небольшая функция задержки, которую я написал сам, используя периферийное устройство таймера моего MCU:
статическая недействительная задержка100Us (недействительная)
{
uint_64 ctr = TIMER_read(0); //10ns resolution
uint_64 ctr2 = ctr + 10000;
while(ctr <= ctr2) //wait 100 microseconds(10000)
{
ctr = TIMER_read(0);
}
}
Счетчик представляет собой автономный аппаратный счетчик с разрешением 10 нс, поэтому я написал эту функцию так, чтобы она давала задержку примерно в 100 мкс. Я думаю, что это должно работать в принципе, однако может возникнуть ситуация, когда таймер меньше 10000 из-за переполнения, и поэтому ctr2 будет присвоено значение, которое больше, чем может фактически достичь ctr, и поэтому я бы в конечном итоге застрял в бесконечном цикле .
Мне нужно сгенерировать задержку, используя этот таймер в моем проекте, поэтому мне нужно как-то убедиться, что я всегда получаю одну и ту же задержку (100 мкс), и в то же время защитить себя от застревания там.
Есть ли способ сделать это или это просто ограничение, которое я не могу обойти?
Благодарю вас!
Редактировать:
ctr_start = TimerRead(); //get initial value for the counter
interval = TimerRead() - ctr_start;
while(interval <= 10000)
{
interval = ( TimerRead() - ctr_start + countersize ) % countersize;
}
Where countersize = 0xFFFFFFFFFFFFFFFF;
interval = (timer - ctr + countersize) % countersize
Если это 64-битный счетчик, тоinterval = timer - ctr
. Выполните арифметические действия перед проверкой интервала (чтобы арифметические действия переносились). - person Weather Vane   schedule 28.01.20210xFFFFFFFFFFFFFFFF
. IMO, лучше всего использовать счетчик свободного хода с общим периодом, превышающим максимальный, который вам когда-либо понадобится. Если счетчик 64-битный, то все просто. Отметьте начальное значение, затем вычислите истекший интервал и сравните его. Используйте>=
, чтобы вам не нужно было улавливать точное значение. Если это 32-битный счетчик, используйте типыuint32_t
и т. д. - person Weather Vane   schedule 28.01.2021