Аппаратное управление таймером состоянием вывода

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

Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

Добрый день, необходимо сформировать сигнал (как на приложенном рисунке) на пине мк от прерывания. Т.е. по событию EXTI каждый раз на пине формируется сигнал постоянной формы (50мксек высокий уровень, 50 - низкий, 500 - высокий и потом низкий до следующего EXTI).
Программно это сделать не проблема, завести таймер и в его прерываниях переключать пин. Но хотелось бы реализовать это аппаратно. Так и временные промежутки будут поточнее и время срабатывания.

Как это реализовать я пока не представляю. В самом сигнале самым важным является первый промежуток 50 мк сек и начало его срабатывания. Можно было бы включить один из таймеров в режиме One Pulse Mode, он бы отработал первые 50 мксек, а дальше вторым таймером в прерывании переключать оставшиеся промежутки, но при настройке пина в режим одиночного срабатывания PWM в дальнейшем у меня не получается менять его состояние, т.е. отработал он импульс, перешел в LOW и перевести его в HIGH вручную уже не получается.

Есть ли тут какие-либо варианты или же только переключать в прерываниях от таймера?
Вложения
Безымянный.png
(6.35 КБ) 135 скачиваний
Реклама
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Аппаратное управление таймером состоянием вывода

Сообщение Eddy_Em »

OPM режим с прерыванием по UEV: в прерывании EXTI запускаешь таймер, он дает тебе два первых импульса. Затем перенастраиваешь в прерывании UEV на 500мкс, опять запускаешь, уже отключив прерывание UEV.
Тольког 50мкс - маловато, из-за накладных расходов второй импульс будет больше (но можно экспериментально определить нужные настройки, а прерыванию UEV поставить наивысший приоритет).
Еще более разумный вариант — запусить передачу при помощи DMA, пусть он в CC1/ARR и пишет нужные значения. Тогда проблемы с длительностью будут минимальными.
Вот так, например. В конкретном случае нет нужды ни CC1, ни ARR дергать: можно прескалером поиграться.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Реклама
Аватара пользователя
azhel12
Встал на лапы
Сообщения: 145
Зарегистрирован: Пн апр 02, 2012 15:56:23

Re: Аппаратное управление таймером состоянием вывода

Сообщение azhel12 »

Интересная задачка, а что если такой вариант прикинуть (конечно, расход таймеров большой, но их вроде как много): объединить выход двух таймеров, первый настроить на двойной OPM (продвинутые так умеют) и период в 50мкс, второй сделать слейвом с делением на 2 и тоже OPM, тогда на второй переход первого таймера запустится второй, то есть вообще ничего изменять не надо?
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

Eddy_Em,
OPM режим с прерыванием по UEV: в прерывании EXTI запускаешь таймер, он дает тебе два первых импульса. Затем перенастраиваешь в прерывании UEV на 500мкс, опять запускаешь, уже отключив прерывание UEV.
Идея понятна, но смущает ручной запуск таймера в EXTI ..., ну ладно, как вариант.

Но вопрос, если пин настроен как OPM таймера, то менять состояние этого пина по ходу программы я не могу?
Еще более разумный вариант — запусить передачу при помощи DMA, пусть он в CC1/ARR и пишет нужные значения. Тогда проблемы с длительностью будут минимальными.
Мне кажется вызов DMA или в прерывании перезаписать CC1/ARR примерно то на то и выйдет?

Тут еще минус в том, что сейчас таймер срабатывает от EXTI автоматически, а если делать на перезапуске в прерываниях, то придется перенастраивать на программный запуск таймера, что скорее всего скажется на времени старта первого импульса

azhel12,
объединить выход двух таймеров
А разве так можно делать? Я чет даже не знаю...
Реклама
Эиком - электронные компоненты и радиодетали
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Аппаратное управление таймером состоянием вывода

Сообщение jcxz »

[uquote="DmitryR",url="/forum/viewtopic.php?p=4302191#p4302191"]Но хотелось бы реализовать это аппаратно.[/uquote]В чём проблема?
Берём XMC4500 или XMC4700 или XMC4800. Внешний сигнал заводим на вход любого таймера (CCU). На этот вход программируем функцию запуска таймера (по нужному событию: фронт/спад/фронт_или_спад). Пассивный уровень выхода таймера устанавливаем = LOW. Таймер настраиваем в режим PWM: период = 100мкс, длина импульса =50мкс. Также внутри этого периода настраиваем генерацию прерывания, в ISR которого будем производить запись новых периода/длины_импульса в теневые регистры. Во 2-м входе в ISR настроим новое прерывание на точку 500мкс от начала 2-го периода. В 3-м входе в ISR - выключим таймер.
Всё! Все интервалы будут выдержаны с точностью до такта CPU, так как ни один не зависит от задержек выполнения CPU/DMA.

PS: Если сильно нужно, то операции производимые в ISR, можно заменить на DMA (направив сигналы прерываний на линии DMA-запросов).
PPS: А если ещё немного подумать и немного доработать алгоритм, то даже целый CCU не нужен, можно обойтись его 1/4 частью.
Реклама
Аватара пользователя
Andrey_B
Сверлит текстолит когтями
Сообщения: 1101
Зарегистрирован: Пт апр 09, 2010 16:06:38
Откуда: Тула

Re: Аппаратное управление таймером состоянием вывода

Сообщение Andrey_B »

[uquote="DmitryR",url="/forum/viewtopic.php?p=4302191#p4302191"]Есть ли тут какие-либо варианты или же только переключать в прерываниях от таймера?[/uquote]

Попробуйте использовать не таймер, а модуль SPI. Ваш сигнал, это 12-битное слово 0b101111111111 на скорости 20kbps.
Реклама
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

jcxz, Ваша идея мне нравится, я даже не знал, что в режиме PWM можно генерировать прерывания.
Только пока с реализацией не получилось. Использую stm32f7 и из-за некоторых соображений настройку делаю на HAL

В main запускаю:

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

  HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_4);
  State = 1;
В прерывании меняю CCR и ARR:

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

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM3)
	{
		switch (State)
		{
			case 1:
				TIM3->CCR4 = 24999;
				TIM3->ARR = 49999;
				TIM3->EGR = TIM_EGR_UG;
				State++;

				break;

			case 2:
				TIM3->CCR4 = 4999;
				TIM3->ARR = 9999;
				TIM3->EGR = TIM_EGR_UG;

				HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_4);
				State = 1;

				break;

			default:
				__NOP();
		}
	}
}
Если я не ошибаюсь, то прерывание генерируется по достижению счета ARR, поэтому в case 1 меняю значения ARR и CCR на более длительные, т.е. на этот момент у меня уже 2 тайминга по 50 мксек должно отработать. Дальше отрабатывают новые ARR и CCR, генерируется прерывание и в case 2 я возвращаю прошлые значения и останавливаю PWM.

Но что-то работает не так

PWM настроен на запуск от EXTI
Вложения
2.png
(30.4 КБ) 103 скачивания
1.png
(30.28 КБ) 106 скачиваний
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Аппаратное управление таймером состоянием вывода

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

F7 разные бывают. Какая модель?
"Привет!" - соврал он.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

>TEHb<, 746
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Аппаратное управление таймером состоянием вывода

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

Вот собака, он без HRTIM! Тогда как вариант использовать
Eddy_Em писал(а):запусить передачу при помощи DMA, пусть он в CC1/ARR и пишет нужные значения.
Включить буферизацию регистров и сразу после запуска от внешнего события запихивать модулем ПДП в регистры настройки для второго импульса. Как толькотаймер отработает первый импульс, то значения обновятся и полетит второй импульс. Вероятно (не читал так подробно) можно устроить всё так, чтобы тот же ПДП во время второго импульса возвращал всё на круги своя. В этом случае ядро не будет отвлекаться вообще. Как всё это настраивать написано в документе RM0385 на странице 786.
"Привет!" - соврал он.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Аппаратное управление таймером состоянием вывода

Сообщение jcxz »

[uquote="DmitryR",url="/forum/viewtopic.php?p=4302961#p4302961"]jcxz, Ваша идея мне нравится, я даже не знал, что в режиме PWM можно генерировать прерывания.[/uquote]У таймеров XMC регистр сравнения (который определяет точку переключения выхода PWM) точно также может на этом же значении вызывать генерацию прерывания (если соответствующий бит разрешения установлен), либо можно отдельно разрешить прерывания в конце и/или в середине периода PWM (для этого регистр сравнения не используется). А если использовать таймер с двумя CR (регистрами сравнения), то можно одним CR задать точку переключения выхода PWM, а вторым CR - точку генерации прерывания в произвольном месте периода (никак не привязанном к моментам переключения выхода PWM).

Итого: один CCU8 (таймер с двумя регистрами сравнения) позволяет генерировать до 6-ти прерываний на период в разных точках периода: начале/конце, в середине, по 1-му CR при счёте вверх и при счёте вниз, и то же самое - по 2-му CR.
Для этих 6 источников прерываний можно назначить до двух разных сигналов прерывания к NVIC. Это не считая того, что для многих событий таймера (старт или стоп, захват, сигнал разрешения тактирования, изменения направления счёта, перезагрузка и др.) если они вызываются внешними сигналами, то по ним тоже таймер может дополнительно генерить прерывания по назначенным линиям NVIC.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

>TEHb<, jcxz, Ваши два совета в целом похожи и в целом они работают.
Настроить PWM на запуск от EXTI и в прерывании от таймера менять ARR и CCR, дальше останавливать таймер, возвращать ARR и CCR на место и разрешать повторное срабатывание по следующему EXTI.

Одна только проблема с этим: как только отрабатывают все 3 тайминга (50, 50 и 500 мксек), выставляем низкий уровень и при следующем EXTI у нас первые 50 мк сек опять должны быть HIGH, но они будут LOW, и из-за этого все уровни поменяются местами и так будет происходить циклично

Добавлено after 2 minutes 27 seconds:

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

if(htim->Instance == TIM2)
	{
		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);		// WorkTest

		switch (State)
		{
			case 1:
				State++;

				break;

			case 2:
				TIM2->CCR4 = 50000 - 1;
				TIM2->ARR = 50000 - 1;
				TIM2->EGR = TIM_EGR_UG;
				State++;

				break;

			case 3:
				HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_4);

				TIM2->CCR4 = 5000 - 1;
				TIM2->ARR = 5000 - 1;
				TIM2->EGR = TIM_EGR_UG;
				HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_4);
				State = 1;

				break;

			default:
				__NOP();
		}
	}
Ну и почему-то правильные тайминги выставляются при ARR = 5000 и CCR = 5000;

Я канал настроил как output compare CH, но с PWM по-моему то же самое
Вложения
3.png
(19.64 КБ) 77 скачиваний
2.png
(23.13 КБ) 85 скачиваний
1.png
(21.91 КБ) 77 скачиваний
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5742
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: Аппаратное управление таймером состоянием вывода

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

Значит у вас неверно настроен таймер. Настраивайте однозначно в какой точке устанавливать высокий уровень, а в какой низкий. Никаких переключений, только жёстко вверх или вниз.
Ну и я всё-таки предлагал с помощью DMA рассовывать данные в регистры, а не в прерывании.
"Привет!" - соврал он.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Аппаратное управление таймером состоянием вывода

Сообщение Eddy_Em »

DmitryR, предлагаю для начала от кала отказаться. Все равно ведь часть вещей делается напрямую регистрами!
Ну и еще раз напомню о DMA. А также, видимо, мимо пролетело: было же предложение SPI или I2C использовать, чтобы данную последовательность импульсов воспроизвести.
P.S. А код реально жуткий. Дрыгать ногодрыгом в прерывании от таймера, когда можно напрямую в ШИМ-режиме… Да еще и ты учти, что есть приличные накладные расходы на вход в прерывание и исполнение кода в нем. Таким образом честных 50мкс ты никак не получишь. Кстати, каловская HAL_GPIO_TogglePin - это тебе не макрос и даже не true_inline, а самая настоящая функция со всеми вытекающими!\
Если тебе так хочется кала, то напиши на С++ с шаблонами свою обертку, и будет тебе щассье. Так как минимум пара человек с форума делала.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

>TEHb<,
Настраивайте однозначно в какой точке устанавливать высокий уровень, а в какой низкий
Дело в том, что там нет таких настроек, могу только выбрать с какого уровня будет это все стартовать CH Polarity.
Хотя я тогда не понимаю, почему при повторном запуске он стартует не с указанного HIGH, а с предыдущего уровня

Eddy_Em,
Там стоит FreeRTOS, но вроде как не планируется ее взаимодействие с этим таймером, поэтому можно и без HAL...
Ну и еще раз напомню о DMA
Попробую на DMA, но мне кажется тут дело не в том, как менять ARR и CRR
А также, видимо, мимо пролетело: было же предложение SPI или I2C использовать
Как-то диковато звучит реализовать функции таймера посредством SPI, но можно попробовать)

Добавлено after 3 minutes 44 seconds:
Eddy_Em,
P.S. А код реально жуткий. Дрыгать ногодрыгом в прерывании от таймера, когда можно напрямую в ШИМ-режиме…
Если Вы про это

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

HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);      // WorkTest
То не, это не тот пин, который должен сигнал формировать, это я просто поставил, чтобы отследить на осциллографе когда срабатывает прерывание и не убрал.
А так в прерывании только ARR и CRR меняется, больше там ничего не делается, ну кроме State++
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: Аппаратное управление таймером состоянием вывода

Сообщение Eddy_Em »

Ну вот, чтобы не было проблем, нужно делать все более-менее аппаратно. И, кстати, предложение Andrey_B использовать SPI - очень даже дельная идея (если есть в системе 1 ненужный SPI и его нога MOSI свободная). И таймер на это тратить не придется, и канал DMA.
А ртось - это фу. Если приложение для МК невозможно без ртоси сделать, то дешевле купить одноплатник за две тысячи рублей и реализовать всю многозадачность на нормальном линуксе, а для RT выделить какой-нибудь недорогой камушек (зачастую даже F030 сгодится).
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

Eddy_Em,
А ртось - это фу
РТОС фу, HAL фу, LWIP фу, если так на все фукать на одних регистрах придется сидеть писать кучу времени)))
Да там FreeRTOS поставлена чисто из-за LWIP (уж что, а ethernet я точно на регистрах писать не готов).
На ОС я скидываю всякие медленные задачи не первой необходимости, а все RT делаю на приоритете выше чем у ОС и не взаимодействующими с ОС. Ну и стараюсь делать их аппаратно.
Камень 746 - таймеров, SPI, DMA, всего полно.

Тут знаете, дело-то даже и не в регистрах, это уже довольно заезженная тема, отношение к HAL давно понятно...
Тут скорее вопрос в принципе в функциональной возможности реализации тем или иным способом.
Вот, например, сейчас задача практически решена, за исключением подмеса ARR и CRR переключения пина происходит аппаратно, но он начинает свой новый цикл со значения предыдущего. Предполагаю, что так построена архитектура, что что он при первом запуске выставляет настроенный уровень, а дальше делает toggle и когда вмешиваешься в этот процесс, система себя так ведет. Может тогда помимо старт/стоп надо еще делать какую-нибудь переинициализацию состояния пина...
Добавить DMA можно, но на данном этапе это изменит лишь способ перезадания ARR и CRR
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Аппаратное управление таймером состоянием вывода

Сообщение VladislavS »

[uquote="DmitryR",url="/forum/viewtopic.php?p=4303715#p4303715"]но он начинает свой новый цикл со значения предыдущего.[/uquote]У таймера же куча вариантов поведения ноги по событию сравнения.
СпойлерИзображение
изображение_2022-10-12_150502672.png
(208.76 КБ) 172 скачивания
PS:А фукателя не слушайте. Он F4 то ещё не освоил, до F7 к пенсии не доберётся точно со своими фу.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Аппаратное управление таймером состоянием вывода

Сообщение DmitryR »

VladislavS, Видимо мне надо поглубже покапатьcя в Reference manual.
Опять же, как Вы и написали, это настройки на событие сравнения, а по событию сравнения надо менять ARR и ССR. Не знаю даже... Надо мне почитать сначала

PS: Для себя я сделал вывод, что все, что не критично на HAL или LL, критичные функции на CMSIS или, в некоторых случаях, LL. Типа золотая середина по-моему мнению
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Аппаратное управление таймером состоянием вывода

Сообщение VladislavS »

ARR может быть буферизирован и новое значение будет активироваться при достижении текущего.
Изображение
изображение_2022-10-12_155430452.png
(9.92 КБ) 452 скачивания
Ответить

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