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

STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Пн мар 27, 2023 14:28:32
The_Blind_WatchMaker
Эволюционирую проект из Bare Metal до RTOS использую CubIDE.
В проекте АЦП работает по прерыванию от таймера, в прерывании цикл с остановом по тикам таймера - дергает ножками АЦП для её запуска.
В RTOS сделать цикл с остановкой по таймеру не удаётся.
Спойлер

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

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim)
{
 if (htim->Instance == TIM1)
{
			HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);

			for (volatile __IO uint32_t i = 0, f = 0; f <255 ;[b][u] f =  htim->Instance->CNT[/u][/b])
			{
				 i = htim->Instance->CNT;
				if (i > 6)
					f = 255;
				if(htim->Instance->CNT != last)
				{
					HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
					last = htim->Instance->CNT;
				}
			}
}
}
Не запускается, а вот плохой костыль:
Спойлер

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

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim)
{
 if (htim->Instance == TIM1)
{
			HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);

			for (volatile __IO uint32_t i = 0, f = 0; f <255 ; [b][u]f ++[/u][/b])
			{
				 i = htim->Instance->CNT;
				if (i > 6)
					f = 255;
				if(htim->Instance->CNT != last)
				{
					HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
					last = htim->Instance->CNT;
				}
			}
}
}
Работает и показывает ожидаемую картинку в 3 импульса.
:oops: Помогите кто чем может. Отладчик в обоих случаях значения

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

htim->Instance->CNT
не показывает - всегда 0.
Хочу понять что я не так делаю и как мне реализовать требуемый функционал - цикл в котором буду дергать ножки АЦП контролируя временные интервалы.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Пн мар 27, 2023 16:39:57
tonyk
Какой вопрос такой ответ.

Начнём с простого. АЦП внешний? Какой именно?

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Пн мар 27, 2023 17:30:50
AVI-crak
Что это??? И под какими веществами написано???

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 06:24:01
The_Blind_WatchMaker
Вещества все забористые, иное уже не берет. Не могу никак запустить цикл по таймеру в прерываниях. Без подключения RTOS работает.
АЦП внешний. Какой именно не суть важно, формулировка была неудачная в первом сообщении - проблема с таймерами, а не с АЦП. Просто нужно ткнуть носом, что не так с таймерами.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 08:31:51
a797945
таймер - это не счётчик. Забудьте о существовании CNT
Не удивлюсь, если то что Вы хотите таймер может выполнять сам. А чтоб это настроить читайте как устроены таймеры у stm32 (или у Вас другая платформа?)

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 08:54:38
tonyk
The_Blind_WatchMaker писал(а):АЦП внешний. Какой именно не суть важно
Суть важно. Есть подозрение, что ТС не с того бока подходит к вопросу. Глядя на обработчик прерывания, у меня тоже возник вопрос о веществах, принятых ТС перед его написанием.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 09:00:51
The_Blind_WatchMaker
Счас буду нести бред:
Как позже выяснилось проблема не совсем с RTOS в новом проекте без ОС тоже повторяется.
У меня работает в другом проекте на этой же отладочной плате из этого же STM32CubeIDE: один таймер вызывает прерывание каждые 100 мкс, другой используется для контроля времени выхода из прерывания и контроля тайминга дергания ножками внешней АЦП.
В последующих проектах воспроизвести этот функционал не удаётся :oops: с одинаковыми настройками...
Причём самый бред в том, что:
Спойлер

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

for (uint32_t i = 0, f = 0;(  (__HAL_TIM_GET_COUNTER(htim) < 6) ); f ++ ) //(f < 255) &&   - не работает
for (uint32_t i = 0, f = 0;(  (f < 255) &&(__HAL_TIM_GET_COUNTER(htim) < 6) ); f ++ ) // работает как и хотелось до 6 тиков
В чём магия? Отладчик ни в одном случае CNT регистр таймеров мне не показывает...

Добавлено after 4 minutes 25 seconds:
[uquote="tonyk",url="/forum/viewtopic.php?p=4392433#p4392433"]
The_Blind_WatchMaker писал(а):АЦП внешний. Какой именно не суть важно
Суть важно. Есть подозрение, что ТС не с того бока подходит к вопросу. Глядя на обработчик прерывания, у меня тоже возник вопрос о веществах, принятых ТС перед его написанием.[/uquote]
В обработчике простой код для проверки - дергаю ножкой, которая поближе ко мне, чтобы в неё щупом тыкать поудобней было.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 09:41:03
VladislavS

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

while(__HAL_TIM_GET_COUNTER(htim)<6);

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 09:59:11
The_Blind_WatchMaker
[uquote="VladislavS",url="/forum/viewtopic.php?p=4392455#p4392455"]

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

while(__HAL_TIM_GET_COUNTER(htim)<6);
[/uquote]
Как раз с этого всё и началось код в файле подготовленном для управления АЦП содержал:

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

while ((__HAL_TIM_GET_COUNTER(htim) < Start_Limit) && !flag_2)
И теперь оно не работает... почему я ника не пойму :oops:

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

for (uint32_t i = 0, f = 0;( (f < 255) && (__HAL_TIM_GET_COUNTER(htim) < 6) ); f ++ ) //
Это уже кривые потуги разобраться в чём дело, я ж не такой профи, чтобы ассемблер вызывать и вообще.
Могу штатный дебаггер запустить, но он не помогает, CNT всегда пустой...
Есть мысль, что какой-то системный счётчик срабатывает пока в конструкции "while(__HAL_TIM_GET_COUNTER(htim)<6)" счетчик CNT не меняется, система считает, что получился "бесконечный цикл".
А если в условии добавляется "(f < 255) && (__HAL_TIM_GET_COUNTER(htim) < 6)" и в цикле " f ++ ", то такой ошибки не возникает.
Но из меня специалист так себе... ткните носом пжлст.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 10:55:12
VladislavS
Не надо мудрить. Если задача подождать пока счётчик станет равен 6, то так и надо писать "подождать пока счётчик меньше 6". Если не работает, то либо счётчик не тикает, либо читается не тот счётчик. Открываем отладчик, листинг и смотрим. Введение 100500 переменных-счётчиков цикла только усложняет отладку. Вот скажите, зачем в цикле переменная i ? Ну так, чисто поржать.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 12:06:06
The_Blind_WatchMaker
Грешно смеяться над больными людьми. Стыдно.
Лучше подскажите почему в цикле условие по таймеру не хочет работать без дополнительных 100500 переменных счётчиков цикла...

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 12:20:51
VladislavS
Если не работает, то либо счётчик не тикает, либо читается не тот счётчик.
Эти два варианта, я так понимаю, вы уже проверили?

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 13:59:08
The_Blind_WatchMaker
Проверил на 3-х платах: STM32CubeIDE (WIN) STM32F429ZI Disco, STM32F429ZI NUCLEO; STM32CubeIDE (Lin) STM32F429ZI Disco, STM32F429ZI NUCLEO, STM32F103C6T6.
//f103C6T6
Спойлер

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

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	int f = 0;
	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);
	while ((__HAL_TIM_GET_COUNTER(htim) < 16) && (f < 65534) ) //&& (f < 65534)
	{
		f++;

		if (__HAL_TIM_GET_COUNTER(htim) != last)
		{
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);
			last = __HAL_TIM_GET_COUNTER(htim);
		}
	}
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13, GPIO_PIN_RESET);
}
/* USER CODE END 4 */
//F429ZI (Nucleo & Discovery)
Спойлер

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

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	int f = 0;
	HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
	while ((__HAL_TIM_GET_COUNTER(htim) < 6) & (f < 200))
	{
		f++;

		if (__HAL_TIM_GET_COUNTER(htim) != last)
		{
			HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
			last = __HAL_TIM_GET_COUNTER(htim);
		}
	}
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_9, GPIO_PIN_RESET);
}
/* USER CODE END 4 */
Нигде не работает условие вида "while (__HAL_TIM_GET_COUNTER(htim) < 6)" только если условие "while ((__HAL_TIM_GET_COUNTER(htim) < 16) && (f < 65534) )" и в коде "f++".
СпойлерУ f103C6T6 медленно пины переключаются, на разницу "(__HAL_TIM_GET_COUNTER(htim) < 6)" и "(__HAL_TIM_GET_COUNTER(htim) < 16)" не стоит обращать внимания
Добавлено after 3 minutes 22 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=4392509#p4392509"]
Если не работает, то либо счётчик не тикает, либо читается не тот счётчик.
Эти два варианта, я так понимаю, вы уже проверили?[/uquote]
Проверил. Когда "работает" я вижу на осциллографе то количество фронтов которое и ожидал - 6 для F429 и 8 для F103 (код выше). У 103 медленно ноги дергает потому фронты 1 к 2 тикам таймера. Я так думаю.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 14:04:06
a797945
HAL_TIM_PeriodElapsedCallback

это не вызов при переполнении? и CNT=0?

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 14:10:36
The_Blind_WatchMaker
[uquote="a797945",url="/forum/viewtopic.php?p=4392556#p4392556"]HAL_TIM_PeriodElapsedCallback

это не вызов при переполнении? и CNT=0?[/uquote]

Таймер же в этот момент начинает с 0 считать, верно? В это же суть прерываний и организации "Real Time" кода? Я и собираюсь первые несколько тиков взять на подёргать ножками. В чём прикол я не понял. Вещества тяжелые с юмором туго.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 14:15:30
a797945
когда Вы включаете счетчик по f - зависаете в одном обработчике, и у таймера есть время по тикать;
нет этого счетчика - Вы каждый раз в новом прерывании и cnt опять еще только =0

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 14:20:50
The_Blind_WatchMaker
[uquote="a797945",url="/forum/viewtopic.php?p=4392562#p4392562"]когда Вы включаете счетчик по f - зависаете в одном обработчике,
нет этого счетчика - Вы каждый раз в новом прерывании и cnt опять еще только =0[/uquote]
А почему так-то? Я хотел, чтобы код вида:
Спойлер

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

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
   while ((__HAL_TIM_GET_COUNTER(htim) < 6) )
   {
      if (__HAL_TIM_GET_COUNTER(htim) != last)
      {
         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
         last = __HAL_TIM_GET_COUNTER(htim);
      }
   }
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_9, GPIO_PIN_RESET);
}
/* USER CODE END 4 */
дал мне 6 фронтов вот и всё, а почему без без "f" не получается я не понимаю, но вряд-ли дело в выходе из прерывания. Т.к. когда код имеет вид как в этом посте ничего не работает HardFault как я понимаю.
Я выше писал
Спойлер
Есть мысль, что какой-то системный счётчик срабатывает пока в конструкции "while(__HAL_TIM_GET_COUNTER(htim)<6)" счетчик CNT не меняется, система считает, что получился "бесконечный цикл".
А если в условии добавляется "(f < 255) && (__HAL_TIM_GET_COUNTER(htim) < 6)" и в цикле " f ++ ", то такой ошибки не возникает.
Но из меня специалист так себе...
Мысль в общем такая, но как это выявить я не знаю.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 14:29:29
a797945
я не знаю Хал, первая ссылка гугля про HAL_TIM_PeriodElapsedCallback сказала - это обработчик по переполнению - т.е. таймер оттикал период и снова =0.
с помощью Вашего f++ - Вы ЗАДЕРЖИВАЕТЕСЬ в обработчике и можете дождаться нужного тика таймера.

у таймера есть каналы и флаги, на необходимость пользоваться CNT я пока не натыкался.

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 14:34:54
The_Blind_WatchMaker
[uquote="a797945",url="/forum/viewtopic.php?p=4392572#p4392572"]я не знаю Хал, первая ссылка гугля про HAL_TIM_PeriodElapsedCallback сказала - это обработчик по переполнению - т.е. таймер оттикал период и снова =0.
с помощью Вашего f++ - Вы ЗАДЕРЖИВАЕТЕСЬ в обработчике и можете дождаться нужного тика таймера.[/uquote]
Я думал, что while ((__HAL_TIM_GET_COUNTER(htim) < 6) ) в функции HAL_TIM_PeriodElapsedCallback обеспечит мне задержку в прерывании на 6 тиков таймера, но такой код вызывает системную ошибку.
А как мне добиться выполнения кода вида
Спойлер

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

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
   while ((__HAL_TIM_GET_COUNTER(htim) < 6) )
   {
      if (__HAL_TIM_GET_COUNTER(htim) != last)
      {
         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
         last = __HAL_TIM_GET_COUNTER(htim);
      }
   }
   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_9, GPIO_PIN_RESET);
}
/* USER CODE END 4 */
без костылей в виде "f++"?

Re: STM32+RTOS проблема с работой таймеров в прерываниях

Добавлено: Вт мар 28, 2023 16:25:47
a797945
это я уже не внимательно читаю.

вопрос сводится к тому, что есть проблемы с поллингом регистра CNT ?
попробуйте пост проверку do{}while()
или посмотреть во что компилится