Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

F042, таймер и странное поведение мигалок

Пт янв 15, 2021 23:07:38

Добрый вечер.

Пытаюсь написать таймер для конечных автоматов и вот какая странность.
Настроил таймер на 1мс.
Прерывание от таймера простейшее:
Код:
extern uint32_t blinkMS;
void TIM14_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim14);

  if( blinkMS > 0 )
     blinkMS--;
}


Первый вариант мигалки, он работает:
Родил такое от безысходности, в приступе вдохновения :oops:
Спойлер
Код:
  uint8_t on = 0;
  while (1)
  {
     if( blinkMS <= 20 && blinkMS > 10 && !on )
     {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
        on = 1;
     }

     if( blinkMS <= 10 && on)
     {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
        on = 0;
     }

     if( blinkMS == 0 )
        blinkMS = 20;

  }


А вот второй, по смыслу такой же, не пашет. TogglePin вызывается только один раз и все, больше туда не заходит.
Спойлер
Код:
  while (1)
  {
     if( blinkMS == 0 )
     {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
        blinkMS = 1000;
     }
  }


Зато, если его немного переиначить и сделать так:
Спойлер
Код:
  while (1)
  {
     if( blinkMS == 0 )
     {
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
     }

     if( blinkMS == 0 )
     {
        blinkMS = 1000;
     }
  }

То он начинает мигать, но очень хаотично, импульсы нестабильны и отличаются по длине в 1.5-2 раза.

Вопрос: что за фигня творится и как это победить?!

Фото первой и третьей мигалок прилагаю:
Изображение Изображение

P.S. Вариант с запретом/разрешением прерывания ничего не менят.
СпойлерХаотичные импульсы:
Код:
if( blinkMS == 0 )
     {
        NVIC_DisableIRQ(TIM14_IRQn);
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
     }

     if( blinkMS == 0 )
     {
        blinkMS = 10;
        NVIC_EnableIRQ(TIM14_IRQn);
     }


Так, не работает вообще. Как вариант №2.
Код:
if( blinkMS == 0 )
     {
        NVIC_DisableIRQ(TIM14_IRQn);
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
        blinkMS = 10;
        NVIC_EnableIRQ(TIM14_IRQn);
     }

Re: F042, таймер и странное поведение мигалок

Пт янв 15, 2021 23:24:57

Volatile для blinkMS добавь.

Re: F042, таймер и странное поведение мигалок

Сб янв 16, 2021 15:35:10

Спойлер
Код:
  uint8_t on = 0;
  while (1)
  {
     if( blinkMS <= 20 && blinkMS > 10 && !on )
     {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
        on = 1;
     }

     if( blinkMS <= 10 && on)
     {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
        on = 0;
     }

     if( blinkMS == 0 )
        blinkMS = 20;

  }
Если добавите volatile для blinkMS, то blinkMS нужно копировать в локальную переменную в начале цикла один раз. И потом работать только с её копией.
Ответить