Страница 1 из 1

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

Добавлено: Пт янв 15, 2021 23:07:38
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);
	  }

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

Добавлено: Пт янв 15, 2021 23:24:57
Reflector
Volatile для blinkMS добавь.

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

Добавлено: Сб янв 16, 2021 15:35:10
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 нужно копировать в локальную переменную в начале цикла один раз. И потом работать только с её копией.