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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
aaleksander
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 07, 2015 21:00:35

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

Сообщение aaleksander »

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

Пытаюсь написать таймер для конечных автоматов и вот какая странность.
Настроил таймер на 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);
     }
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

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

Сообщение Reflector »

Volatile для blinkMS добавь.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

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

Сообщение jcxz »

[uquote="aaleksander",url="/forum/viewtopic.php?p=3960700#p3960700"]
Спойлер

Код: Выделить всё

  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;

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

Вернуться в «ARM»