Using a timer to delay

I need to implement a delay function with a hardware timer. The timer value is incremented every millisecond.

The usual approach is to use the width of the timer register and use modulo the behavior corresponding to

volatile int TimerReg;

void Delay(int amount)
{
    int start = TimerReg;
    int elapsed;

    do
    {
        eleapsed = TimerReg - start;
    } while (elapsed < amount);
}

This works when TimerReg has an int width. The difference now - startin this case is steadily increasing.

But when the width of the TimerReg is less than the width of the int or (as in my case), the timer only counts from 0..1000, there is a problem when the timer wraps from 999 to 1000 by 0.

What is a good approach to using such a timer? I would like to avoid the operation with the module, because it costs a lot on the microcontroller.

Edit: The separation module is not yet included in the microcontroller code.

+3
source share
6

. , int. elapsed, .

volatile int TimerReg; /* value range: 0..999 */
const int TimerMaxValue = 999;

void Delay(int amount) 
{ 
    int start = TimerReg; 
    int elapsed; 

    do 
    { 
        eleapsed = TimerReg - start;
        if (elapsed < 0) eplapsed += (TimerMaxValue + 1);
    } while (elapsed < amount); 
} 
0

- :

volatile int TimerReg;

void Delay(int amount)
{
  int start = TimerReg;
  int elapsed;
  int rolled_over = 0;
  int last_time = start;

  do
  {
    int timer_reg = TimerReg;
    // Check for rollover
    if(last_time > timer_reg) {
      // ROLLOVER_INTERVAL is the magic number at which the timer rolls over to 0
      rolled_over += ROLLOVER_INTERVAL - start;
      start = 0;
    }
    last_time = timer_reg;
    if(rolled_over == 0) {
      elapsed = timer_reg - start;
    } else {
      elapsed = timer_reg + rolled_over;
    }
  } while (elapsed < amount);
}

, if- , .

+3

? , , 0xFFF, 0x000 999 000,

elapsed = (TimerReg - start)&0xFFF;

elapsed = (TimerReg - start)%1000; 

, .

, , - , ,

nowtime = TimerReg;
if(nowtime < start)
{
   elapsed = (1000 - start) + nowtime;
}
else
{
   elapsed = nowtime - start;
}

.

, , (0xFFFF 0xFFFFFFFF - ), , - , ( , ).

+1

, :

start_timer();
while ( (timer_flag_register & bitmask)==0 )
{
  do_stuff();
}

start_timer() [ ] + [ ]. ( ). MCU .

0

You can use interrupt when the timer reaches its value to increase the global counter (for example, for every 1000 ms).

0
source

Your 1 ms timer (Nyquist frequency) is much slower than your polling code. Therefore, you can simply use the uqual operator '=':

volatile int TimerReg;

void Delay(int amount)
{
    int future = TimerReg + amount;

    while (TimerReg != future);
}

This is an elegant solution, in my humble opinion, but it only works if "TimerReg" is free to work across the entire range, for example. '0xffff'.

-1
source

All Articles