Заголовок сообщения: Как отсчитать равный промежуток тактов на stm32f1
Добавлено: Пт окт 13, 2017 00:26:56
Встал на лапы
Зарегистрирован: Вс сен 23, 2012 05:51:35 Сообщений: 132
Рейтинг сообщения:0
Суть вопроса заключается в следующем. Мне нужно, чтобы, например, после прерывания А, прерывание Б происходило ровно, скажем, через 600 тактов. Вопрос решается, скажете вы, довольно просто, запусти таймер на 600 тактов, который вызывает прерывание. Ан нет, давно уже мучаюсь с этим, но ничего не выходит. Прерывание происходит не ровно через 600 тактов, а через 601-602 и т.д. в зависимости от фоновых действий.
То есть я запускаю таймер 1 с прерыванием. Он его генерит. В прерывании запускается таймер 2 на 600 тактов. Я что-то делаю в первом прерывании и выхожу из него. Срабатывает второе... но проходит не ровно 600 тактов! И как решить эту задачу я уже голову сломал. Да, счётчик таймера я сбрасываю.
Пробовал делать всё в одном прерывании, просто запомнить значение другого таймера в начале прерывания. Сделать какие-то дела в прерывании. И дождаться нужного значения в эти 600 тактов просто в вайле, но не тут то было! Арм и тут меня подловил и судя по всему иногда происходит, а иногда не происходит лишняя инструкция сравнения, но стабильности нет.
Пока единственный способ решения задачи, который я нашёл - просто ждать в for опрелённое количество цыклов в одном прерывании до события Б. Тогда выходит, что всегда отсчитывается нужное значение от начала прерывания А до события Б. Но! Это же такая бессмысленная трата ресурсов, которые мне очень нужны. Прошу помощи в решении этой нелёгкой задачи.
Единственное решение, которое я сейчас предполагаю - как-то отправить камень в сон и ждать прерывания от второго таймера после действий в событии А. Тогда, предположительно, он всегда будет одинаково выходить из сна и я буду получать свои фиксированные 600 тактов, но как это сделать я так и не понял. Ну или как-то ждать в самом прерывании значения таймера без вайла, какой-то скрытой командой, о которой я ничего не знаю.
Хочу сделать ремарку, что 600 тактов число навсидку. Мне просто нужно всегда чтобы событие Б происходило через фиксированное количество тактов от события А.
Единственное решение, которое я сейчас предполагаю - как-то отправить камень в сон и ждать прерывания от второго таймера после действий в событии А. Тогда, предположительно, он всегда будет одинаково выходить из сна
с режимами сна я особо не ковырялся, но емнип первое, что делает контроллер по пробуждении - дожидается стабилизации частоты тактового генератора. Это время не фиксировано.
Виновата флешпамять. Доступ к данным не мгновенный и зависит от латентности (FLASH->ACR). Вариант - выполнять программу из памяти.
Nope, попробовал через конфиг кейла закидывать функции в рам - не помогло.
Цитата:
с режимами сна я особо не ковырялся, но емнип первое, что делает контроллер по пробуждении - дожидается стабилизации частоты тактового генератора. Это время не фиксировано.
Ну я предполагал, что есть режим сна, в котором тактирование не отключается. Впрочем, он так глубоко уходит в сон по WFI, что до него даже программатор достучаться не может.
Цитата:
надежно - никак.
Печалька. Но, отвечая на ваш последний вопрос - вывод на vga. Я давно с ним воюю. Но в итоге победил, не знаю как, но мне удалось методом проб и ошибок добиться того, чтобы более менее фиксированный был промежуток между синхроимпульсом в первом прерывании и началом отрисовки во втором. Остаётся только дивиться, как люди умудряются на восьмибитках его (vga) поднимать.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
В прерывании запускается таймер 2 на 600 тактов. Я что-то делаю в первом прерывании и выхожу из него. Срабатывает второе... но проходит не ровно 600 тактов!
Black_lizard, у меня все работает, не важно из флеша выполнять или RAM. Пишу в CCR1 600, в прерывании сохраняю в массив текущее значение счетчика, CCR1 увеличиваю на 600, когда массив заполняется сверяю разницу между соседними значениями массива и она всегда равна 600.
Black_lizard, у меня все работает, не важно из флеша выполнять или RAM. Пишу в CCR1 600, в прерывании сохраняю в массив текущее значение счетчика, CCR1 увеличиваю на 600, когда массив заполняется сверяю разницу между соседними значениями массива и она всегда равна 600.
Хм. Возможно тогда это где-то всё-таки моя ошибка была. Спасибо.
Цитата:
Ошибка в использовании прерывания для запуска кода, особенно если нужен точный тайминг.
Ну если он успевает выполниться до следующего прерывания, то в чём проблема?
Ну если он успевает выполниться до следующего прерывания, то в чём проблема?
В чем проблема вы вроде сами выше написали. Надеюсь, вы в курсе, что пока код выполняется, вы сидите в прерывании?
Собственно, Reflector предложил одно из возможных ее решений.
Конечно, в курсе. И что прерывание не сработает до тех пор, пока мы сидим в прерывании с большим приоритетом. Тем не менее ранее я всех поблагодарил за помощь и написал, что решением проблемы нашлось. И, видимо, это была моя ошибка. Во всяком случае стабильности я добился.
oleg110592, с DMA я делал изначально и всё бы хорошо, но на его работу воздействует фоновая программа. То есть DMA нормально работает только если на фоне крутится цыкл while(1);. Начинаешь делать вычисления - и начинаются проблемы. На V-Sync вообще не нужен отдельный таймер, достаточно считать строки в прерываниях на H-sync. По статьям я понял, что эта проблема с DMA решается тем, что в мк несколько независимых блоков SRAM памяти и можно выводить данные с блока, который не будет затронут. МБ я ошибаюсь, но нормальную цветную картинку я пока видел только на F4 )
Кстати, в проекте по линку от dosikus столкнулись с похожей на вашу проблемой:
Цитата:
One curious fact was that we had to move the interrupt handlers to a fixed position at the end of the flash because adding code before those functions (in terms of position in flash) made the SPI to start sooner or later, depending on the added code. I believe in some flash fetching delay depending on the function location.
Примерно похожую задачу решали здесь http://we.easyelectronics.ru/STM8/progr ... ast-2.html. Там нужно было начать выполнять код через фиксированное время после первого фронта USB пакета. Где то было продолжение уже для m0.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 18
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения