Время срабатывания таймеров и их точность

Кто любит RISC в жизни, заходим, не стесняемся.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Время срабатывания таймеров и их точность

Сообщение DmitryR »

Добрый день, довольно простая и обыденная задача вызвала большие затруднения с ее решением. Надо от одного таймера запустить 3 других и получить результат, как на рисунке 1.

TIM4 просто циклично задает начало отсчета (зеленая линия) с постоянной частотой. Далее мне надо получить картину как на рисунке, где все параметры (T1, T2, T3, P1, P2, P3) динамически могу меняться путем задания их длительности с ПК.

Основная проблема в том, что я не могу добиться нужной мне точности срабатывания таймеров и установки логических уровней на пинах мк. Для этого попробовал разные подходы:

1. Изначально была идея сделать на прерываниях. Довольно банально, от TIM4 стартуем все таймеры и в их прерываниях выставляем логические уровни и делаем их перезапуск.

Запускаем все таймеры
Спойлер

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

void TIM4_Callback(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
	{
		// START
		GPIOC->BSRR = GPIO_BSRR_BS0;

		// START TIMER 7
		TIM7->ARR = SetTime7 - 1;
		TIM7->SR &= ~ TIM_SR_UIF;
		TIM7->CNT = 0;
		TIM7->DIER = TIM_DIER_UIE;
		LL_TIM_EnableCounter(TIM7);

		// START TIMER 3
		TIM3->ARR = SeеTime3 - 1;
		TIM3->EGR = TIM_EGR_UG;
		TIM3 ->SR &= ~ TIM_SR_UIF;
		TIM3->CNT = 0;
		TIM3->DIER = TIM_DIER_UIE;
		LL_TIM_EnableCounter(TIM3);

		// START TIMER 5
		TIM5->ARR = SetTime5 - 1;
		TIM5->EGR = TIM_EGR_UG;
		LL_TIM_ClearFlag_UPDATE(TIM5);
		TIM5->CNT = 0;
		TIM5->DIER = TIM_DIER_UIE;
		LL_TIM_EnableCounter(TIM5);
	}
	else
	{
		__NOP();
	}

	LL_TIM_ClearFlag_UPDATE(TIM4);
}
Коллбек всех 3х таймеров делаем по такому примеру:
Спойлер

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

void TIM7_Callback(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM7))
	{
		switch (StateTim7)
		{
			case 0:
				StateTim7 = 1;
				// SET PIN LEVEL HIGH
				GPIOC->BSRR = GPIO_BSRR_BS3;
				TIM7->ARR = SetPeriod7 - 1;
				break;

			case 1:
				StateTim7 = 0;
				// SET PIN LEVEL LOW
				GPIOC->BSRR = GPIO_BSRR_BR3;
				LL_TIM_DisableCounter(TIM7);
				break;
		}
	}
	else
	{
		__NOP();
	}

	LL_TIM_ClearFlag_UPDATE(TIM7);
}
В таком виде это работает, но с ошибками. Если выставить тайминги довольно большими, например T7 = 29 мк сек, то в целом картина более менее стабильна (на логическом анализаторе он будет 31.75), т.е. все тайминги по факту будут больше на порядка 1.5 - 2 мк сек, полагаю из за задержки на время запуска таймеров. Хотя такая задержка вызывает вопросы, не много ли?
Но когда я уменьшаю время срабатывания таймера допустим T7 до 0.1 мк сек от старта, то тут во-первых этот тайминг не выставится меньше 2.5 мк сек (Рисунок 2), во вторых почему-то начинает сильно ошибаться величина P7, может уменьшиться в 1.5 раза и тд, происходит какое-то влияние одной величины на другую.
Такая не предсказуемость меня не сильно устроила, поэтому попробовал второй вариант.

2. Решил я переделать все на one pulse mode. В целом идея та же в коллбеке TIM4 стартуем 3 таймера, но уже настроенные в этом режиме. Для эксперимента взял TIM11 и TIM12
Спойлер

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

void TIM4_Callback(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
	{

	    TIM11->ARR = 4000;
	    TIM11->CCR1 = 1000;
	    TIM11->EGR = TIM_EGR_UG;

		TIM11->CNT = 0;
		TIM11->SR &= ~ TIM_SR_UIF;
		TIM11->DIER = TIM_DIER_UIE;

		HAL_TIM_Base_Start(&htim11);
		HAL_TIM_PWM_Start(&htim11, TIM_CHANNEL_1);


	    TIM12->ARR = 4000;
	    TIM12->CCR2 = 1000;
	    TIM12->EGR = TIM_EGR_UG;

		TIM12->CNT = 0;
		TIM12->SR &= ~ TIM_SR_UIF;
		TIM12->DIER = TIM_DIER_UIE;

		HAL_TIM_Base_Start(&htim12);
		HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_2);
	}
	else
	{
		__NOP();
	}

	LL_TIM_ClearFlag_UPDATE(TIM4);
}
Запускаю я их вместе, времена у них заданы одинаковые, а срабатывают они в разное время. А именно таймер 12 опаздывает на 2.5 мк сек. Измерил я, ради интереса, этот участок кода:

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

	    TIM11->ARR = 4000;
	    TIM11->CCR1 = 1000;
	    TIM11->EGR = TIM_EGR_UG;

		TIM11->CNT = 0;
		TIM11->SR &= ~ TIM_SR_UIF;
		TIM11->DIER = TIM_DIER_UIE;

		HAL_TIM_Base_Start(&htim11);
		HAL_TIM_PWM_Start(&htim11, TIM_CHANNEL_1);
По длительности он как раз занимает порядка 2.2 мк сек. Отсюда следует, если таким образом запускать 3 таймера подряд, то 3й будет отставать от первого на 5 мк сек. Это трындец будет. Ну и вопрос, опять, почему так много уходит времени на запуск таймера?

3. Третьей моей идеей является взять один таймер с 4мя каналами, запустить его в коллбеке TIM4 и в прерывании от каждого канала запускать еще по одному таймеру, чтобы выдержать необходимые длительности импульсов (P1, P2, P3). Берем пока TIM12 на 2 канала.
Ставлю такие параметры:
Для канала 1 - TIM_OC_InitStruct.CompareValue = 1;
Для канала 2 - TIM_OC_InitStruct.CompareValue = 2500;
Т.е. при запуске в том же самом коллбеке TIM4

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

		TIM12->EGR = TIM_EGR_UG;
		LL_TIM_EnableIT_CC1(TIM12);
		LL_TIM_EnableIT_CC2(TIM12);
		LL_TIM_EnableCounter(TIM12);
Спойлер

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

void TIM12_Callback(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM12))
	{
		if(LL_TIM_IsActiveFlag_CC1(TIM12))
		{
			LL_TIM_ClearFlag_CC1(TIM12);
			HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_2);		// Test
			LL_TIM_DisableIT_CC1(TIM12);
		}
		else if(LL_TIM_IsActiveFlag_CC2(TIM12))
		{
			LL_TIM_ClearFlag_CC2(TIM12);
			HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_2);		// Test
			LL_TIM_DisableIT_CC2(TIM12);

			LL_TIM_DisableCounter(TIM12);
		}
		else
		{
			__NOP();
		}
	}
	else
	{
		__NOP();
	}
}
Я должен получить, что первый канал сработает сразу же, а второй как отсчитает 2500 тиков, что равно 25 мксек.
По факту первый стартует спустя 1.5 мк сек, а второй 25 + 1.5 мк сек. Т.е. опять задержка от времени старта единицы мк секунд.

Исходя из этого:
1) Почему такие большие задержки запуска таймеров?
2) Какой подход для решения данной задачи будет самым правильным?
3) Может просто я что-то делаю не так?

Буду благодарен за любые подсказки, ибо не понимаю причину такой работы мк.

Лирическое отступление: мк - stm32f746. Настройка в CubeMX (для таймеров LL), так как используется FreeRTOS, но приоритет таймеров выше чем у любой задачи ОС. Таймеры функции ОС не используют
Вложения
3.png
Рисунок 3
(74.25 КБ) 82 скачивания
2.png
Рисунок 2
(27.46 КБ) 85 скачиваний
1.png
Рисунок 1
(9.92 КБ) 98 скачиваний
Реклама
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение >TEHb< »

Контроллер-то какой?
"Привет!" - соврал он.
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение Martian »

stm32f746

нехилый, однако...
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Время срабатывания таймеров и их точность

Сообщение DmitryR »

[uquote=">TEHb<",url="/forum/viewtopic.php?p=4281584#p4281584"]Контроллер-то какой?[/uquote]
stm32f746 на плате nucleo

Добавлено after 1 minute 31 second:
Martian, да, на 200 MHz частота, а на запуск таймера уходит 1.5 - 2 мксек, и побороть пока не могу...
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение >TEHb< »

DmitryR писал(а):stm32f746
Действительно, проморгал.

Посмотрите, например, на странице 794 документа RM0385 табличку с внутренними сигналами промежтаймерными. Можно ведомые таймеры настроить так, чтобы они запускались от события ведущего без участия ядра. Ну и в том же документе конечно написано как это сделать. Может быть придётся использовать не именно те таймеры, что у вас сейчас, но главное, что принцип организации аппаратного взаимодействия таймеров будет понятен.
"Привет!" - соврал он.
Реклама
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Время срабатывания таймеров и их точность

Сообщение DmitryR »

>TEHb<, Благодарю, тоже подумал про настройку ведомых таймеров в режиме one pulse mode. В целом сделал, есть одна загвоздка.
Динамически задаю тайминги:

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

		    		    TIM3->ARR = 2000;
		    		    TIM3->CCR2 = Timer3;
		    		    TIM3->EGR = TIM_EGR_UG;

		    		    TIM5->ARR = 2000;
		    		    TIM5->CCR1 = Timer5;
		    		    TIM5->EGR = TIM_EGR_UG;
Так как в этом режиме задаются 2 точки, меняю пока только первую - время срабатывания таймера.
Если выставляю величину 250 тиков таймера (2500 нс) и более, то все нормально, тайминги хорошие, таймер, который запустили вторым, отстает от первого на 750 нс (Рис. 1).
Если же поставить CCR1 и CCR2 меньше, например 100 (1000 нс), то сигнал искажается, как на рис. 2 Такое поведение не понятно. Либо что-то не так с настройками, либо все-таки есть минимальный предел, меньше которого таймер не может нормально функционировать, но думаю, что это не так.

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

void TIM4_Callback(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
	{
	    TIM3->CNT = 0;
		HAL_TIM_Base_Start(&htim3);
		HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);

		TIM5->CNT = 0;
		HAL_TIM_Base_Start(&htim5);
		HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
	}
	else
	{
		__NOP();
	}

	LL_TIM_ClearFlag_UPDATE(TIM4);
}
Вложения
3.png
(66.78 КБ) 72 скачивания
2.png
(62.81 КБ) 72 скачивания
1.png
(63.7 КБ) 77 скачиваний
Реклама
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение >TEHb< »

Классическая проблема. Решается включением буферизацией регистров. Если ничего не путаю, то бит ARPE в регистре TIMx_CR1 как раз за это и отвечает.
"Привет!" - соврал он.
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Время срабатывания таймеров и их точность

Сообщение MLX90640 »

У таймеров есть slave-mode с одновременным запуском по мастер-таймеру, либо с запуском по событиям триггеров.
ARPE в CR1 буферизует только ARR регистр. Если надо буферизовать CCRx регистры, биты её разрешения находится в регистрах CCMRx. Буферизация - это загрузка записанных в регистры значений только после наступления события Update, то есть в начале нового цикла счета.

RTOS и HAL могут вносить значительные задержки в доступе непосредственно к регистрам таймера, просто по причине очень длинного кода. И даже если вы назначили высокий приоритет задаче работы с таймерами, она все равно будет на короткое время прерываться с интервалом каждого системного тика, но возвращаться назад, если более приоритетных нет. Системные события никуда не деваются ведь, планировщик не остановлен.
Последний раз редактировалось MLX90640 Чт сен 01, 2022 15:41:16, всего редактировалось 1 раз.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение Eddy_Em »

Если выкинуть калокуб, задержка будет меньше.
Но все-таки, правильней сделать, как советовали: использовать связанные таймеры. Таймер-господин по определенному событию будет пинать своих рабов.
P.S. DmitryR, а что за задача-то? Это случаем не генерирование трех синусоид со сдвигом в 120°?
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: Время срабатывания таймеров и их точность

Сообщение Мурик »

Eddy_Em писал(а):Если выкинуть калокуб, задержка будет меньше.
Eddy_Em, много ли у вас проектов на регистрах для STM32F7?
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение Eddy_Em »

Мурик, если надо будет - будут. Пока мне F7 не нужен. Я вообще не понимаю, честно говоря, для каких целей такую жиробасину можно использовать. Да и дорого ужасно. Дешевле же сделать связку из orange pi + STM32F072 или F103.
Но уж вляпываться в калокод — ну это совсем буээ.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Время срабатывания таймеров и их точность

Сообщение MLX90640 »

Кстати, F7 ничем особым не отличается от того же F4 или даже F0 в этом плане. Если писали "на регистрах" для F0, то для F7 точно напишите таймеры. Они не отличаются, за исключением двух дополнительных каналов.
Разве что частота до 216 МГц и расширенный набор инструкций позволяют быстрее "проглатывать" портянки HAL.
Нынче F746 очень дорог. Иной раз H743 может оказаться дешевле.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Время срабатывания таймеров и их точность

Сообщение DmitryR »

>TEHb<, MLX90640, никогда не пользовался буферизацией, надо будет попробовать, спасибо за совет, только я не совсем понял какой регистр за это отвечает.
OC1PE: Output Compare 1 preload enable
Бит для управления буферизацией регистра TIMx_CCR1.
0: буферизация регистра TIMx_CCR1 не используется; запись в регистр TIMx_CCR1 может быть произведена в любой момент и новое значение начнёт использоваться немедленно.
1: используется буферизация регистра TIMx_CCR1; операции чтения/записи выполняются с буферным регистром, новое значение из буфера передаётся в активный регистр (который и управляет работой таймера) при каждом событии обновления.
Вот, вроде, подходит, или все-таки CCMRx?
RTOS и HAL могут вносить значительные задержки в доступе непосредственно к регистрам таймера, просто по причине очень длинного кода. И даже если вы назначили высокий приоритет задаче работы с таймерами, она все равно будет на короткое время прерываться с интервалом каждого системного тика, но возвращаться назад, если более приоритетных нет. Системные события никуда не деваются ведь, планировщик не остановлен.
Там у FreeRTOS максимальный приоритет 5, у всех этих таймеров задан приоритет 3, функции ОС они не используют, по идее ОС не должна влиять, но точно утверждать не могу...

Eddy_Em,
Если выкинуть калокуб, задержка будет меньше.
Ну про куб и HAL... Там ОС и Ethernet (LwIP), писать это на регистрах точно нет, поэтому какой выход я тут пытаюсь найти: настройка периферии на HAL или LL, далее все, что не имеет критическое значение и может работать медленно и не очень эффективно на HAL или том же LL, все, что критически важно на CMSIS. Ну как-то так... Благо ресурсы контроллера позволяют.
а что за задача-то? Это случаем не генерирование трех синусоид со сдвигом в 120°?
Не, по сути управление драйверами для транзисторов, надо их в нужное время открывать и с довольно критичной точностью по времени.
Я вообще не понимаю, честно говоря, для каких целей такую жиробасину можно использовать. Да и дорого ужасно.
Ну я привожу же не весь проект, а только его конкретную часть, где возникли проблемы, но на самом деле там можно обойтись более простым контроллером, не 103 конечно, но каким-нибудь 407. Просто у меня отладочная плата nucleo c ethernet, мне удобно пользоваться такой, а там уже как проект готов, можно думать какой мк взять. А стоимость, стоимость такой платы месяца 3-4 назад около 3-4 тыс, с алиэкспресс приехали абсолютно нормальные платы один в один как в чип и дипе
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Время срабатывания таймеров и их точность

Сообщение MLX90640 »

CCMR1 и CCMR2, биты OC1PE, OC2PE, OC3PE, OC4PE (расшифровывается как Output compare 1(2,3,4) preload enable, capture/compare mode register)
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение Eddy_Em »

А стоимость, стоимость такой платы месяца 3-4 назад около 3-4 тыс, с алиэкспресс приехали абсолютно нормальные платы один в один как в чип и дипе
Ну вот. А в случае с orange pi + дешевый МК вышло бы 2.5-3.5тыр. И на нормальном линуксе писать, а не извращаться с говеным lwip в убогой RTOS! И можно спокойно будет по ssh работать с железом (чего нельзя в случае МК)...

P.S. Получается, нужно сгенерировать три импульса строго определенной длительности, идущие через строго определенные промежутки времени? А обязательно отсчитывать прямо от общего начала? Ведь можно отсчитывать от времени подачи первого импульса. Тогда нужно будет использовать один таймер в режиме господина и два таймера в режиме раба. У первого CC1 будет определять длительность импульса, а CC2 и CC3 - пинать подчиненные таймеры. У тех же CC1 будет определять длительность.
Иначе придется задействовать четыре таймера: один господин и три раба.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Время срабатывания таймеров и их точность

Сообщение >TEHb< »

DmitryR писал(а):Там у FreeRTOS максимальный приоритет 5, у всех этих таймеров задан приоритет 3
Это всё внутри операционки, а ей самой ещё нужно с железом и задачами цацкаться. Systick, например, какой-нибудь может кааак сработать и всё, времена уплыли. Если временные интервалы и формировать на ядре, то нужно чертовски точно до такта понимать что и как там работает. Во всех смыслах ловчее получается таки аппаратными средствами периферии, благо таковые средства имеются.
Конкретный бит конкретного регистра не подскажу, я больше по HRTIM, но направление задали куда надо. Читайте, пробуйте.
Eddy_Em писал(а):orange pi + дешевый МК
Можно ещё ноутбук старый прикупить за такие деньги и не караться с этим одноплатником. Тут и экран, и клавиатура и всё такое. Лично я бы для точных временных интервалов и вовсе 334 контроллер бы взял.
"Привет!" - соврал он.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Время срабатывания таймеров и их точность

Сообщение DmitryR »

Eddy_Em,
А в случае с orange pi + дешевый МК вышло бы 2.5-3.5тыр
Ну это довольно сомнительная выгода, чтобы так заморачиваться)
На счет LWIP согласен, с ним тяжко, особенно когда была задача разогнать максимальную скорость передачи данных, он явно не для этого (хотя на форуме st есть серия постов, где этот стек разогнали до 90-95 Мбит/сек).
К ОС особо претензий нет, но если бы LWIP (HTTP) не требовало бы ее, то и смысла в ней тоже нет для этой задачи.
И на нормальном линуксе писать
Все эти инструменты дело вкуса, навыков и времени на их осваивание. Raspberry pi еще есть)
Но если бы мк совсем не тянул задачу, лично я бы лучше взял связку мк + ПЛИС.
Как правило самые критичные функции они же и являются самыми простыми по функционалу, типа как здесь таймеры, а самое объемное и замороченное, типа как передача данных по Ethernet, не столь требовательны к скорости выполнения.
P.S. Получается, нужно сгенерировать три импульса строго определенной длительности, идущие через строго определенные промежутки времени? А обязательно отсчитывать прямо от общего начала? Ведь можно отсчитывать от времени подачи первого импульса.
Нуу, в идеале да, строго определенной длительности и в строго определенное время. Строгость тут относительная, например я готов понять, если я запущу таймер так, чтобы он сработал через 20 мксек, а он сработает через 20.25 это одно дело, а если он сработает через 23 мк сек, это дикость для таймера, который тактируется частотой 100 МГц.
Тут больше нюанс в том, что мне не нужны артефакты в работе кода, а именно ситуация как на приведенном выше скрине, когда я меняю время срабатывания таймера, а у меня появляются ложные срабатывания, либо была еще ситуация, когда мной изменялся только промежуток времени начала импульса, а его длительность сама изменилась в 1.5 раза, хотя этот параметр никто не трогал.
Такое поведение наблюдается, когда он старта до момента срабатывания таймера требуется меньше 1-5 мк секунд. В этом диапазоне наблюдается хаотичное поведение не соответствующее требуемому.

К тому, что у меня задержка от запуска таймера до его максимально быстрого срабатывания 500 ns я уже, своего рода, привык, главное чтобы этот параметр был постоянным, чтобы импульсы каждый раз запускались в один и тот же момент.

Но от первого таймера отталкиваться нельзя, так как все параметры (время старта и длительность импульса) могут быть и будут динамически меняться, не исключена ситуация, когда второй импульс, в какой-то момент, станет первым и тд.

Поэтому суть в том, чтобы все 3 таймера были привязаны к одному моменту старта, были довольно точны по своему срабатыванию (ну в пределах 100 нс) и таймеры могли иметь возможность сработать как можно раньше от своего запуска. Ну и, соответственно, не было ошибок в работе.
Если временные интервалы и формировать на ядре, то нужно чертовски точно до такта понимать что и как там работает. Во всех смыслах ловчее получается таки аппаратными средствами периферии, благо таковые средства имеются.
Ну вот получается сейчас так реализовано, с ведущим и ведомыми таймерами. Только один момент, сейчас я в прерывании от ведущего таймера запускаю ведомые в режиме one pulse mode:

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

void TIM4_Callback(void)
{
	if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
	{
	    TIM3->CNT = 0;
		HAL_TIM_Base_Start(&htim3);
		HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);

		TIM5->CNT = 0;
		HAL_TIM_Base_Start(&htim5);
		HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
	}
	else
	{
		__NOP();
	}

	LL_TIM_ClearFlag_UPDATE(TIM4);
}
А могу я как-то один раз запустить ведомые и ведущий таймер вместе, чтобы мне не надо было ведомые каждый раз в прерывании от ведущего запускать? Тогда это будет работать без участия процессора.

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

Systick, например, какой-нибудь может кааак сработать и всё
Если я не ошибаюсь, то и Systick имеет приоритет не выше 5го, т.е. эти таймеры с приоритетом 3 перебью все процессы ОС, именно поэтому я и не могу использовать в них функционал ОС

Добавлено after 8 minutes 10 seconds:
Я как-то даже не подумал попробовать запустить ведущие таймеры, а потом ведомый, интересно, как себя поведет мк

Добавлено after 11 minutes 1 second:
MLX90640,
где-нибудь перед запуском или в инициализации добавить
TIM3->CCMR1 |= TIM_CCMR1_OC1PE;
Правильно же понимаю?
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Время срабатывания таймеров и их точность

Сообщение MLX90640 »

Systick - это таймер системных тиков для RTOS, и он ну полюбасу будет вызываться вот как угодно, просто для того, чтобы сама операционка работала. Если его заблокировать, то операционка повиснет. Тут как бы не надо путать приоритеты задач внутри операционки и приоритеты прерываний микроконтроллера. Приоритеты задач - это очередность выполнения их и величина выделяемого на задачу времени.
Щас как бы нет особо времени вникнуть в суть проблемы вашей, я просто временно отвлекаюсь на форум.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Время срабатывания таймеров и их точность

Сообщение DmitryR »

MLX90640, Мои познания в работе FreeRTOS не так значительны, чтобы спорить на счет ее работы)
Я думал Systick нужен, чтобы в заданные промежутки времени пинать шедулер, который всех прерывает и передает управление, но может Вы и правы)
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Время срабатывания таймеров и их точность

Сообщение MLX90640 »

Ну в принципе то да, систик, работающий на прерывании микроконтроллера, вызывается через равные промежутки времени и вызывает функции планировщика (шедулера), который и определяет, какие задачи в какой очередности переключать. Да. И если есть активная задача с более высоким приоритетом чем остальные задачи, планировщик обратно передаст ей управление. Но выполение кода планировщика тоже занимает время. Как правило, приоритет прерывания систика довольно низкий в системе прерываний микроконтроллера. Другие прерывания с более высоким приоритетом не будут перебиты систиком и будут обработаны с минимальной задержкой. Однако, использование функций HAL дает ощутимую задержку из-за длинного кода этих функций, ориентированного на универсальность написания программистом, но не на скорость работы кода. Каждый лишний коллбек, каждое лишнее использование HAL будет добавлять задержку выполения. В сумме она может стать весьма значительной.
Ответить

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