Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 00:26:56

Суть вопроса заключается в следующем. Мне нужно, чтобы, например, после прерывания А, прерывание Б происходило ровно, скажем, через 600 тактов. Вопрос решается, скажете вы, довольно просто, запусти таймер на 600 тактов, который вызывает прерывание. Ан нет, давно уже мучаюсь с этим, но ничего не выходит. Прерывание происходит не ровно через 600 тактов, а через 601-602 и т.д. в зависимости от фоновых действий.

То есть я запускаю таймер 1 с прерыванием. Он его генерит. В прерывании запускается таймер 2 на 600 тактов. Я что-то делаю в первом прерывании и выхожу из него. Срабатывает второе... но проходит не ровно 600 тактов! И как решить эту задачу я уже голову сломал. Да, счётчик таймера я сбрасываю.

Пробовал делать всё в одном прерывании, просто запомнить значение другого таймера в начале прерывания. Сделать какие-то дела в прерывании. И дождаться нужного значения в эти 600 тактов просто в вайле, но не тут то было! Арм и тут меня подловил и судя по всему иногда происходит, а иногда не происходит лишняя инструкция сравнения, но стабильности нет.

Пока единственный способ решения задачи, который я нашёл - просто ждать в for опрелённое количество цыклов в одном прерывании до события Б. Тогда выходит, что всегда отсчитывается нужное значение от начала прерывания А до события Б. Но! Это же такая бессмысленная трата ресурсов, которые мне очень нужны. Прошу помощи в решении этой нелёгкой задачи.

Единственное решение, которое я сейчас предполагаю - как-то отправить камень в сон и ждать прерывания от второго таймера после действий в событии А. Тогда, предположительно, он всегда будет одинаково выходить из сна и я буду получать свои фиксированные 600 тактов, но как это сделать я так и не понял. Ну или как-то ждать в самом прерывании значения таймера без вайла, какой-то скрытой командой, о которой я ничего не знаю.

Хочу сделать ремарку, что 600 тактов число навсидку. Мне просто нужно всегда чтобы событие Б происходило через фиксированное количество тактов от события А.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 01:34:17

Виновата флешпамять.
Доступ к данным не мгновенный и зависит от латентности (FLASH->ACR). Вариант - выполнять программу из памяти.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 02:33:18

после прерывания А, прерывание Б происходило ровно, скажем, через 600 тактов.

надежно - никак.
Единственное решение, которое я сейчас предполагаю - как-то отправить камень в сон и ждать прерывания от второго таймера после действий в событии А. Тогда, предположительно, он всегда будет одинаково выходить из сна

с режимами сна я особо не ковырялся, но емнип первое, что делает контроллер по пробуждении - дожидается стабилизации частоты тактового генератора. Это время не фиксировано.
Мне просто нужно всегда чтобы событие Б происходило через фиксированное количество тактов от события А.

а зачем, если не секрет?

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 03:49:14

Виновата флешпамять.
Доступ к данным не мгновенный и зависит от латентности (FLASH->ACR). Вариант - выполнять программу из памяти.


Nope, попробовал через конфиг кейла закидывать функции в рам - не помогло.

с режимами сна я особо не ковырялся, но емнип первое, что делает контроллер по пробуждении - дожидается стабилизации частоты тактового генератора. Это время не фиксировано.


Ну я предполагал, что есть режим сна, в котором тактирование не отключается. Впрочем, он так глубоко уходит в сон по WFI, что до него даже программатор достучаться не может.

надежно - никак.


Печалька. Но, отвечая на ваш последний вопрос - вывод на vga. Я давно с ним воюю. Но в итоге победил, не знаю как, но мне удалось методом проб и ошибок добиться того, чтобы более менее фиксированный был промежуток между синхроимпульсом в первом прерывании и началом отрисовки во втором. Остаётся только дивиться, как люди умудряются на восьмибитках его (vga) поднимать.

Ответ на свой вопрос я получил, спасибо. (никак)

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 07:42:09

вывод на vga

может поглядеть как тут сделано:
http://bitboxconsole.blogspot.com/p/blog-page.html

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 14:21:44

вывод на vga

может поглядеть как тут сделано:
http://bitboxconsole.blogspot.com/p/blog-page.html


В stm32f4 многое по другому и проще. Речь идёт именно о серии stm32f1.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:11:23

Тогда забудьте про подсчеты тактов а'ля авр , и читайте здесь https://www.artekit.eu/vga-output-using-a-36-pin-stm32/

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:23:46

В прерывании запускается таймер 2 на 600 тактов. Я что-то делаю в первом прерывании и выхожу из него. Срабатывает второе... но проходит не ровно 600 тактов!


Ошибка в самом построении задачи.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:31:53

Тогда забудьте про подсчеты тактов а'ля авр , и читайте здесь https://www.artekit.eu/vga-output-using-a-36-pin-stm32/

Я читал. Там одноцветная картинка через SPI. Идея понятна, но не подходит, я хочу цвет.

Ошибка в самом построении задачи.

Не очень понял, в чём ошибка.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:35:59

Black_lizard, у меня все работает, не важно из флеша выполнять или RAM. Пишу в CCR1 600, в прерывании сохраняю в массив текущее значение счетчика, CCR1 увеличиваю на 600, когда массив заполняется сверяю разницу между соседними значениями массива и она всегда равна 600.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:37:21

Не очень понял, в чём ошибка.

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

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:39:16

Black_lizard, у меня все работает, не важно из флеша выполнять или RAM. Пишу в CCR1 600, в прерывании сохраняю в массив текущее значение счетчика, CCR1 увеличиваю на 600, когда массив заполняется сверяю разницу между соседними значениями массива и она всегда равна 600.


Хм. Возможно тогда это где-то всё-таки моя ошибка была. Спасибо.

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


Ну если он успевает выполниться до следующего прерывания, то в чём проблема?

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 15:41:37

Ну если он успевает выполниться до следующего прерывания, то в чём проблема?

В чем проблема вы вроде сами выше написали. Надеюсь, вы в курсе, что пока код выполняется, вы сидите в прерывании?

Собственно, Reflector предложил одно из возможных ее решений.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 16:16:52

Речь идёт именно о серии stm32f1

с F1 мало дела имел, но таймер там вроде умеет запускать другой таймер, DMA вроде тоже есть - разве нельзя на F1 так типа сделать:
Изображение

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 18:12:37

Ну если он успевает выполниться до следующего прерывания, то в чём проблема?

В чем проблема вы вроде сами выше написали. Надеюсь, вы в курсе, что пока код выполняется, вы сидите в прерывании?

Собственно, Reflector предложил одно из возможных ее решений.


Конечно, в курсе. И что прерывание не сработает до тех пор, пока мы сидим в прерывании с большим приоритетом. Тем не менее ранее я всех поблагодарил за помощь и написал, что решением проблемы нашлось. И, видимо, это была моя ошибка. Во всяком случае стабильности я добился.

oleg110592, с DMA я делал изначально и всё бы хорошо, но на его работу воздействует фоновая программа. То есть DMA нормально работает только если на фоне крутится цыкл while(1);. Начинаешь делать вычисления - и начинаются проблемы. На V-Sync вообще не нужен отдельный таймер, достаточно считать строки в прерываниях на H-sync. По статьям я понял, что эта проблема с DMA решается тем, что в мк несколько независимых блоков SRAM памяти и можно выводить данные с блока, который не будет затронут. МБ я ошибаюсь, но нормальную цветную картинку я пока видел только на F4 )

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 18:31:20

Кстати, в проекте по линку от 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.

Re: Как отсчитать равный промежуток тактов на stm32f1

Пт окт 13, 2017 20:03:34

Примерно похожую задачу решали здесь http://we.easyelectronics.ru/STM8/progr ... ast-2.html. Там нужно было начать выполнять код через фиксированное время после первого фронта USB пакета. Где то было продолжение уже для m0.
Ответить