Ivan. 4 10 июня Опубликовано 10 июня · Жалоба Доброго времени суток! Помогите реализовать задачу: нужно выдавать пачки импульсов попеременно на один и на второй канал таймера. Т.е. выдать 640 импульсов на один выход, а потом перейти в состояние Idle и выдать 640 импульсов на втором выходе. и т.д. Подумал, что можно задействовать Burst mode, но как рассинхронизировать выходы? Не получается ни с двумя выходами одного Slave таймера, ни с двумя Slave таймерами. Может сделать это с помощью чего то другого? Думал переконфигурировать выходы по DMA, но как то неудобно получается. Естественно вся это задача должна выполняться аппаратно без прерываний и программного кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deni 6 10 июня Опубликовано 10 июня · Жалоба Взять таймер у которого есть RepetitionCounter, это позволит сократить количество обновлений таймера в 128 раз. Далее настроить DMA по событию update на запись в CMP1 и CMP2. В DMA буфере установить ширину импульса для первого канала и нулевую ширину для второго. Сделать в DMA буфере 5 таких записей (640/128). Потом ещё 5, когда активен второй канал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 10 июня Опубликовано 10 июня · Жалоба Спасибо! Ну я примерно так и думал, только это не совсем кашерно. Да и чередовать CMP1 и CMP2 не удобно. придется использовать Burst DMA, чтобы за 1 триггер копировать 2 регистра. Решил сделать следующим образом: Включаю Burst Mode без тактирующего источника, тогда он постоянно висит в активном режиме. А потом в единственном регистре HRTIM_OUTxR включаю и выключаю IDLEM The output is in idle state when requested by the burst mode controller. Так же использовать Repetition с расширением его до 640 периодов с помощью несколько повторов DMA. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 13 июня Опубликовано 13 июня · Жалоба Не правильное решение получилось. Нельзя менять IDLE MODE во время активного BURST MODE. Решил задачу через SWAP выходов одного таймера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 13 июня Опубликовано 13 июня · Жалоба Появилась другая проблема. При остановке программы в режим отладки порты таймера должны быть автоматически выключены. Для этого есть соответствующие настройки: Активируем остановку HRTIM1 флагом DBGMCU_APB2FZ_DBG_HRTIM1_STOP, и выбираем состояние выхода в режиме FAULT битами HRTIM_OUTR_FAULTy у соответствующего таймера. Все отлично, выходы деактивируются при остановке программы, но как узнать, что программа останавливалась? Для этого случая тоже есть соответствующие флаги статуса: в HRTIM есть регистры OENR и ODSR, которые должны отображать текущее состояние выходов. Если бит TxyOEN в регистре OENR активен - выход в состояние работы. Иначе в регистре ODSR отображается причина отключения выхода: состояние IDLE или FAULT. И вот в чем беда: при остановке программы состояние битов OENR не меняется, как будто выходы в режиме работы. Как еще можно определить. что программа останавливалась? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 14 июня Опубликовано 14 июня · Жалоба Остановилась как? Под отладкой? У CPU в недрах его регистров дебага есть бит HALT. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 14 июня Опубликовано 14 июня · Жалоба Как узнать, что контроллер был остановлен отладчиком, что связь с внешним миром была на время потеряна. Я останавливаю программу отладчиком, а потом запускаю и программа не знает, что все ее данные давно не актуальны. Синхронизация фазы ушла и нужно все восстанавливать прежде чем открывать силовые ключи. Я включил режим остановки таймеров и выключение выходов при остановке программа, но я не могу понять как об этом узнать. HRTIM переводит выходы в FAULT состояние но почему то не отображает это в статус регистре OENR. В документации написано, что DBG_HRTIM_STOP не влияет на биты статуса и я вижу это, но фактически выходы выключены. и чтобы их снова включить нужно записать 1 в соответствующий бит регистра OENR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 14 июня Опубликовано 14 июня · Жалоба 11 часов назад, Ivan. сказал: Как еще можно определить. что программа останавливалась? Не знаю можно ли сделать такое в STM32, но в XMC4xxx я бы просто запустил второй таймер, не останавливаемый отладчиком. Который бы сбрасывался периодическими событиями от вашего останавливаемого таймера, а когда таких событий нет - его счётчик добегал бы до некоего конечного значения переполнения (или COMPARE-события). Дальше просто проверяем флаг наличия переполнения - есть значит останов скорее всего был. Ну или запустите любой таймер (хоть внутренний WDT, который только генерит не сброс, а прерывание). И периодически его сбрасывайте по COMPARE-событию (часто сбрасывайте). Если добежал до переполнения, значит -> не было сброса -> был останов. 52 минуты назад, Arlleex сказал: Остановилась как? Под отладкой? У CPU в недрах его регистров дебага есть бит HALT. Это будет весьма сложно сделать с остановленным CPU. Ведь ТСу явно это нужно знать в программе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 14 июня Опубликовано 14 июня (изменено) · Жалоба У основных таймеров есть бит MainOutput. по его состоянию можно узнать, что программа останавливалась, но почему то у HRTIM этот бит не меняется, хота выходы фактически были выключены. 4 минуты назад, jcxz сказал: Не знаю можно ли сделать такое в STM32, но в XMC4xxx я бы просто запустил второй таймер, не останавливаемый отладчиком. Который бы сбрасывался периодическими событиями от вашего останавливаемого таймера, а когда таких событий нет - его счётчик добегал бы до некоего конечного значения переполнения (или COMPARE-события). Дальше просто проверяем флаг наличия переполнения - есть значит останов скорее всего был. Это плохой вариант. Даже установка брейкпоинта может приостановить программу на несколько микросекунд и этого достаточно, чтобы спалить схему. Изменено 14 июня пользователем Ivan. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 14 июня Опубликовано 14 июня · Жалоба 9 минут назад, Ivan. сказал: Это плохой вариант. Даже установка брейкпоинта может приостановить программу на несколько микросекунд и этого достаточно, чтобы спалить схему. А что мешает установить период сброса в несколько нсек? За несколько нсек тоже схема сгорит??? PS: Да и кстати - в нормальных контроллерах защиту принято делать ещё и аппаратную. Не надеясь полностью на программную. Для этого даже в таймерах МК есть вход TRAP (или FAULT). А если у вас система так сделана, что её палит установка бряка, то вообще в мусорку такую схему. Так как бряк может устанавливаться во флешь, и тогда никакими микросекундами там и близко не пахнет. Как минимум - несколько мсек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ivan. 4 14 июня Опубликовано 14 июня · Жалоба Во всех нормальных контролерам есть множество зашит: комплиментарные выходы, отключение при остановке и прочее. Я и здесь могу задействовать для определения внештатной остановки ПО дополнительный таймер, но это какой то грязный хак. Я не могу понять, почему такой крутой таймер как HRTIM ведёт себя так нелагично. Что я не так делаю? Может у этого таймера есть ещё какой то специально обученный флаг, но я его не вижу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться