Jump to content

    
Sign in to follow this  
lomy

Таймер для генерации импульсов

Recommended Posts

Здравствуйте, уважаемые коллеги.

Прошу помочь с решением задачи. Сразу оговорюсь, что я инженер-схематехник, и практического опыта программирования микроконтроллеров у меня нет. Задача такая, используя микроконтроллер STM32L476RG (можно другой серии, главное STM32) нужно генерировать сигнал на двух портах микроконтроллера как на прикрепленном изображении. Сигналы должны быть обязательно синхронизированы.

IMG_20180319_152743.jpg

На данный момент я уже попытался по-разному решить эту задачу несколькими способами, в каждом из которых столкнулся с проблемами, опишу их:

Способ 1: активировал два таймера (ведущий и ведомый), один отсчитывает длинные периоды по 15 мс и тактирует второй, который в режиме one pulse генерирует прямой и комплементарный сигнал, проблема состоит в том, что в инверсном канале, когда таймер 2 «бездействует» устанавливается 1 (это правильно по логике работы инверсного канала, но не удовлетворяет решению)

IMG_20180319_153312.jpg

Способ 2: активировал два таймера, один отсчитывает длинные периоды по 15 мс второй считает короткие полупериоды 0,5 мкс порты переключаю вручную в обработчике прерываний, получается, довольно криво. Синхронизировать два канала не удается (сгенерированные импульсы смещены друг относительно друга)

Способ 3: активировал 3 таймера один отсчитывает длинные периоды по 15 мс и тактирует второй, который генерирует два импульса и тактирует третий таймер, который генерирует одиночный импульс, проблема в том, что все это почему-то работает только с тактовой частотой контроллера 80 МГц, стоит только начать настраивать частоты тактирования контроллера или самих таймеров как все разваливается.

Если у кого то есть идеи или готовое решение, пожалуйста, ответьте.

 

Share this post


Link to post
Share on other sites

Спасибо за ответ.

Я активно использовал этот Application note, и научился его помощью генерировать пачки импульсов. Но я не смог решить своей задачи. Если у Вас будет время взгляните, пожалуйста, на диаграмму стр. 68. Там видно, что в инверсном канале остается «лишний импульс». Возможно ли сделать то, что там называется “Commutation update to inactive mode” на один импульс раньше?

Share this post


Link to post
Share on other sites
Сразу оговорюсь, что я инженер-схематехник, и практического опыта программирования микроконтроллеров у меня нет. Задача такая, используя микроконтроллер STM32L476RG (можно другой серии, главное STM32)

А чем вызваны такие ограничения? По религиозным соображениям? Или у вас нет программистов, а есть только кубо-кодеры? :laughing:

 

Способ 1: активировал два таймера (ведущий и ведомый), один отсчитывает длинные периоды по 15 мс и тактирует второй, который в режиме one pulse генерирует прямой и

...

Способ 2: активировал два таймера, один отсчитывает длинные периоды по 15 мс второй считает короткие полупериоды 0,5 мкс порты переключаю вручную в обработчике прерываний,

...

Способ 3: активировал 3 таймера один отсчитывает длинные периоды по 15 мс и тактирует второй, который генерирует два импульса и тактирует третий таймер, который генерирует

Вообще это элементарно решается на любом МК LPC имеющем интерфейс SGPIO - он как раз и предназначен для генерации таких пачек последовательных импульсов синхронно по нескольким ногам.

Я его как раз и использовал для генерации очень похожих пачек из фиксированного числа импульсов и по разным ногам для управления пьезоизлучателем. Только у меня было 3 импульса с периодом 200нс.

 

Ну а если на любом другом МК (в том числе и на STM32), то можно использовать dual-SPI например.

 

Также это легко реализуется на семействе МК Infineon XMC4xxx - там есть богатые возможности по синхронной работе нескольких таймеров.

Share this post


Link to post
Share on other sites

Да, к сожалению, свободных программистов для этого проекта нет, поэтому приходится делать самому.

Если есть возможность дайте ссылки на инфу как можно использовать dual-SPI для решения задачи.

Share this post


Link to post
Share on other sites
Если есть возможность дайте ссылки на инфу как можно использовать dual-SPI для решения задачи.

Так это вроде самоочевидно. Почитайте как работает dual-SPI.

Там в режиме OUT вместо одного пина MOSI на вывод работают 2 пина: чётные биты слова - через один пин, нечётные - через другой. Вот и всё.

Подключаете верхнюю линию осциллограммы к DATA0, нижнюю - к DATA1, настраиваете порт на SCLK==1МГц, вывод, выводите байт == 0x19 и получаете на пинах первую группу импульсов со своей осциллограммы.

Главное чтоб Ваш МК умел dual-SPI. Или quad-SPI.

Share this post


Link to post
Share on other sites

Хорошо, буду читать. Но разве там линии не полностью инверсны друг другу? Мне нужно что бы когда нет импульсов обе линии были в нуле.

Share this post


Link to post
Share on other sites
Хорошо, буду читать. Но разве там линии не полностью инверсны друг другу? Мне нужно что бы когда нет импульсов обе линии были в нуле.

dual-SPI - это SPI выводящий два бита за такт SCLK. Соответственно - на эти две линии можно выставлять данные совершенно независимо, но полностью синхронно.

Читайте мануал! Хотя бы гугл используйте: https://www.totalphase.com/support/articles...Serial-Software

Share this post


Link to post
Share on other sites

Вариант, проверен на stm32f107 такт таймера 1мкс.

у таймера используются два канала сравнения, два канала DMA, две таблицы в памяти.

по сравнению одного канала таймера, DMA транзакция из таблицы в GPIOx->BSRR устанавливаю или сбрасываю нужные пины выбранного порта.

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

каналы срабатывают одновременно.

Share this post


Link to post
Share on other sites
Вариант, проверен на stm32f107 такт таймера 1мкс.

у таймера используются два канала сравнения, два канала DMA, две таблицы в памяти.

Сто раз уже эту байду обсуждали... :twak:

Никакой жёсткой синхронности такой метод не даёт, только с точностью +-трамвайная остановка и в тепличных условиях (когда CPU остановлен/спит, никакие другие bus-master-ы в системе не работают).

Достаточно хоть немного подумать головой что будет если в момент когда DMA нужно что-то переслать в GPIO-порт, шина окажется занятой (хоть всего на пару тактов). Будет постоянный джиттер фронтов сигналов, зависящий от приоритета DMA-каналов, работы других bus-master-ов в системе, кода выполняемого CPU, пятен на солнце...

Share this post


Link to post
Share on other sites

Если синхронности не дает, то не буду тратить на это время.

 

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

Share this post


Link to post
Share on other sites
К тому моменту как я обратился на форум, я перерыл много информации в интернете. У меня сложилось такое ощущение, что это задача имеет решение с помощью двух таймеров (один ведомый другой ведущий) и периферии которой они могут управлять напрямую. Наверное я заблуждался.

Так возможно тоже можно, я просто не использовал работу связок таймеров в STM32 и не знаю возможно ли это. Но в других МК это возможно.

Если нужны жёстко детерминированные временные зависимости неких сигналов генерируемых МК, то эти сигналы не должны зависеть от неизвестных временнЫх величин, коими являются транзакции по внутренним шинам МК. А значит это можно сделать и на связках таймеров если они связаны своими внутренними сигналами синхронизации без привязки к CPU или DMA.

Как только изменение некоего сигнала становится зависимым от пересылки по матрице шин (с помощью CPU или DMA), так сразу возникает неопределённость во времени перепада этого сигнала так как пересылка по шине не выполняется мгновенно или даже просто фиксированное время - это величина переменная, зависящая от загрузки шины. Так как шина - общая.

Но проще, имхо, будет сделать на dual-SPI - и периферии меньше задействовано.

Share this post


Link to post
Share on other sites

Спасибо за разъяснение. Я уже начал читать про dual-SPI.

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

Share this post


Link to post
Share on other sites
Достаточно хоть немного подумать головой что будет если в момент когда DMA нужно что-то переслать в GPIO-порт, шина окажется занятой (хоть всего на пару тактов). Будет постоянный джиттер фронтов сигналов, зависящий от приоритета DMA-каналов, работы других bus-master-ов в системе, кода выполняемого CPU, пятен на солнце...

Так передавать по DMA надо не в порты GPIO, а перепрограммировать режим таймера. У таймера все необходимые регистры буферизованы и могут обновляться разом, будет вам синхронизация.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this