A
A
Atilla2013-12-22 16:25:49
Microcontrollers
Atilla, 2013-12-22 16:25:49

How to implement an economical delay on a microcontroller?

microcontroller stm32f4.
Let's say that during the course of the program you need to interrupt the work of this section of the program for a while (for example, while another microcontroller with which you are exchanging data is restarting or processing data). Of course, you can spin in a cycle:
for ( ; i<time; i++ );
But this means that the processor is idling for a lot of time, but it could be reading something at that time. If you have to wait a little, then it's not scary. And if you need to wait a couple of milliseconds? How can I have you call some function:
delay ( 100 );
Which would stop the function at that point for 100 milliseconds, during which time the processor could work on other calculations?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
R
Rizvan Gereykhanov, 2013-12-22
@Gereykhanov

Only with the help of timers and the interrupt system, I see no other way

C
Catethysis, 2013-12-26
@Catethysis

Totally agree with @Gereykhanov , only on timers.
We take the TIM6 timer (the simplest timer with basic functions - to leave cooler timers free), configure it:

// Включаем тактирование таймера
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); 

// Настраиваем прескалер. При тактовой частоте 24МГц частота
// таймера будет равна 24МГц/24000 = 1кГц
TIM6->PSC = 24000;

// Настраиваем период таймера = 1000 циклов - полный цикл таймера
// будет равен 1/1кГц*1000 = 1 секунда.
TIM6->ARR = 1000;

// Разрешаем прерывание по окончанию счёта
TIM6->DIER |= TIM_DIER_UIE;  

// Включаем обработку всех прерываний от таймера TIM6
NVIC_EnableIRQ(TIM6_DAC_IRQn);

// Включаем таймер
TIM6->CR1 |= TIM_CR1_CEN;

after the timer expires, the interrupt handler will be called
void TIM6_DAC_IRQHandler(void)
{
  if (TIM6->SR & TIM_SR_UIF) {
    // Сбрасываем флаг прерывания
    TIM6->SR &= ~TIM_SR_UIF;

    /* ваш код после задержки*/
  }
}

This is not a delay(100) function, it is rather a demonstration of an asynchronous algorithm - but you need to understand that in complex programs, especially those related to transmitting and receiving data from outside, almost everything needs to be done on interrupts.
While the timer is running, the processor is completely free to do some math or service other interrupts.
Quite often, in my STM32 programs, void main looks just like while(1) {}, and all the logic of work is in interrupts. By the way, here it is already a stone's throw to finite automata.

A
Alexander, 2013-12-22
@komjaga

The easiest way is to organize your dispatcher like this
while(1)
{
Task1();
Task2();
Task3():
};
where Taks are your processes, each process executes quickly and waits for nothing
Taks1()
{
static step=0;
switch(step)
{
case 0: SendCommand(); step=1; break; //send command
case 1: if(port) { Led=1; step=0; break; //waiting for response
};
};
};

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question