Например TDA7294

Форум РадиоКот :: Просмотр темы - Аппаратное управление таймером состоянием вывода
Форум РадиоКот
https://radiokot.ru/forum/

Аппаратное управление таймером состоянием вывода
https://radiokot.ru/forum/viewtopic.php?f=59&t=184894
Страница 1 из 2

Автор:  DmitryR [ Пн окт 10, 2022 07:48:30 ]
Заголовок сообщения:  Аппаратное управление таймером состоянием вывода

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

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

Есть ли тут какие-либо варианты или же только переключать в прерываниях от таймера?

Вложения:
Безымянный.png [6.35 KiB]
Скачиваний: 112

Автор:  Eddy_Em [ Пн окт 10, 2022 09:16:45 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

OPM режим с прерыванием по UEV: в прерывании EXTI запускаешь таймер, он дает тебе два первых импульса. Затем перенастраиваешь в прерывании UEV на 500мкс, опять запускаешь, уже отключив прерывание UEV.
Тольког 50мкс - маловато, из-за накладных расходов второй импульс будет больше (но можно экспериментально определить нужные настройки, а прерыванию UEV поставить наивысший приоритет).
Еще более разумный вариант — запусить передачу при помощи DMA, пусть он в CC1/ARR и пишет нужные значения. Тогда проблемы с длительностью будут минимальными.
Вот так, например. В конкретном случае нет нужды ни CC1, ни ARR дергать: можно прескалером поиграться.

Автор:  azhel12 [ Пн окт 10, 2022 10:04:43 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Интересная задачка, а что если такой вариант прикинуть (конечно, расход таймеров большой, но их вроде как много): объединить выход двух таймеров, первый настроить на двойной OPM (продвинутые так умеют) и период в 50мкс, второй сделать слейвом с делением на 2 и тоже OPM, тогда на второй переход первого таймера запустится второй, то есть вообще ничего изменять не надо?

Автор:  DmitryR [ Пн окт 10, 2022 14:43:55 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

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

Идея понятна, но смущает ручной запуск таймера в EXTI ..., ну ладно, как вариант.

Но вопрос, если пин настроен как OPM таймера, то менять состояние этого пина по ходу программы я не могу?

Цитата:
Еще более разумный вариант — запусить передачу при помощи DMA, пусть он в CC1/ARR и пишет нужные значения. Тогда проблемы с длительностью будут минимальными.

Мне кажется вызов DMA или в прерывании перезаписать CC1/ARR примерно то на то и выйдет?

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

azhel12,
Цитата:
объединить выход двух таймеров
А разве так можно делать? Я чет даже не знаю...

Автор:  jcxz [ Вт окт 11, 2022 01:07:55 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Но хотелось бы реализовать это аппаратно.
В чём проблема?
Берём 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 [ Вт окт 11, 2022 09:47:45 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Есть ли тут какие-либо варианты или же только переключать в прерываниях от таймера?


Попробуйте использовать не таймер, а модуль SPI. Ваш сигнал, это 12-битное слово 0b101111111111 на скорости 20kbps.

Автор:  DmitryR [ Вт окт 11, 2022 11:53:54 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

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 KiB]
Скачиваний: 80
1.png [30.28 KiB]
Скачиваний: 80

Автор:  >TEHb< [ Вт окт 11, 2022 13:01:20 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

F7 разные бывают. Какая модель?

Автор:  DmitryR [ Вт окт 11, 2022 13:03:01 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

&gt;TEHb&lt;, 746

Автор:  >TEHb< [ Вт окт 11, 2022 15:52:03 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Вот собака, он без HRTIM! Тогда как вариант использовать
Eddy_Em писал(а):
запусить передачу при помощи DMA, пусть он в CC1/ARR и пишет нужные значения.


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

Автор:  jcxz [ Вт окт 11, 2022 22:42:12 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

jcxz, Ваша идея мне нравится, я даже не знал, что в режиме PWM можно генерировать прерывания.
У таймеров XMC регистр сравнения (который определяет точку переключения выхода PWM) точно также может на этом же значении вызывать генерацию прерывания (если соответствующий бит разрешения установлен), либо можно отдельно разрешить прерывания в конце и/или в середине периода PWM (для этого регистр сравнения не используется). А если использовать таймер с двумя CR (регистрами сравнения), то можно одним CR задать точку переключения выхода PWM, а вторым CR - точку генерации прерывания в произвольном месте периода (никак не привязанном к моментам переключения выхода PWM).

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

Автор:  DmitryR [ Ср окт 12, 2022 13:47:42 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

&gt;TEHb&lt;, 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 KiB]
Скачиваний: 59
2.png [23.13 KiB]
Скачиваний: 60
1.png [21.91 KiB]
Скачиваний: 59

Автор:  >TEHb< [ Ср окт 12, 2022 13:50:21 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Значит у вас неверно настроен таймер. Настраивайте однозначно в какой точке устанавливать высокий уровень, а в какой низкий. Никаких переключений, только жёстко вверх или вниз.
Ну и я всё-таки предлагал с помощью DMA рассовывать данные в регистры, а не в прерывании.

Автор:  Eddy_Em [ Ср окт 12, 2022 14:08:47 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

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

Автор:  DmitryR [ Ср окт 12, 2022 14:22:49 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

&gt;TEHb&lt;,
Цитата:
Настраивайте однозначно в какой точке устанавливать высокий уровень, а в какой низкий

Дело в том, что там нет таких настроек, могу только выбрать с какого уровня будет это все стартовать 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 [ Ср окт 12, 2022 14:32:03 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Ну вот, чтобы не было проблем, нужно делать все более-менее аппаратно. И, кстати, предложение Andrey_B использовать SPI - очень даже дельная идея (если есть в системе 1 ненужный SPI и его нога MOSI свободная). И таймер на это тратить не придется, и канал DMA.
А ртось - это фу. Если приложение для МК невозможно без ртоси сделать, то дешевле купить одноплатник за две тысячи рублей и реализовать всю многозадачность на нормальном линуксе, а для RT выделить какой-нибудь недорогой камушек (зачастую даже F030 сгодится).

Автор:  DmitryR [ Ср окт 12, 2022 14:50:56 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

Eddy_Em,
Цитата:
А ртось - это фу

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

Тут знаете, дело-то даже и не в регистрах, это уже довольно заезженная тема, отношение к HAL давно понятно...
Тут скорее вопрос в принципе в функциональной возможности реализации тем или иным способом.
Вот, например, сейчас задача практически решена, за исключением подмеса ARR и CRR переключения пина происходит аппаратно, но он начинает свой новый цикл со значения предыдущего. Предполагаю, что так построена архитектура, что что он при первом запуске выставляет настроенный уровень, а дальше делает toggle и когда вмешиваешься в этот процесс, система себя так ведет. Может тогда помимо старт/стоп надо еще делать какую-нибудь переинициализацию состояния пина...
Добавить DMA можно, но на данном этапе это изменит лишь способ перезадания ARR и CRR

Автор:  VladislavS [ Ср окт 12, 2022 15:06:22 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

но он начинает свой новый цикл со значения предыдущего.
У таймера же куча вариантов поведения ноги по событию сравнения.

СпойлерИзображение
Вложение:
изображение_2022-10-12_150502672.png [208.76 KiB]
Скачиваний: 141


PS:А фукателя не слушайте. Он F4 то ещё не освоил, до F7 к пенсии не доберётся точно со своими фу.

Автор:  DmitryR [ Ср окт 12, 2022 15:22:24 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

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

PS: Для себя я сделал вывод, что все, что не критично на HAL или LL, критичные функции на CMSIS или, в некоторых случаях, LL. Типа золотая середина по-моему мнению

Автор:  VladislavS [ Ср окт 12, 2022 15:55:09 ]
Заголовок сообщения:  Re: Аппаратное управление таймером состоянием вывода

ARR может быть буферизирован и новое значение будет активироваться при достижении текущего.
Изображение
Вложение:
изображение_2022-10-12_155430452.png [9.92 KiB]
Скачиваний: 412

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/