А что на фото особенного? Обычный частотомер с методом прямого счета даст такое разрешение при измерительном интервале 1 сек. Прямой счет легко реализуется на STM, причем с учетом асинхронного прескалера может работать до относительно высоких частот. Но речь не про этот метод.
На высоких частотах смысла нет. Но человек спрашивал про конфигурацию таймеров для этого метода, и что-то там придумал. Вот и интересно, что именно. Таймеры у STM32 навороченные, возможно, существует более изящный способ реализации такого метода. У меня ничего не выходит, а Ваша реализация - пока единственная, которая попадалась во всем огромном Интернете. На easy недавно в сообществе увидел тему "Частотомер на STM32", бросился читать, а там - УГ.
Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.
ЛИ, как раз хотел изложить свою мысль в расчете на Вашу критику.
Легко доступны кварцы с точностью порядка 1 ппм или чуть лучше. При тактовой частоте 72 МГц и gate time 0.1 сек получаем разрешение такого же порядка. Поэтому хочется програмным путем сделать reciprocal counter без внешней логики.
Моя идея такова. Для простоты рассуждений предположим что опорная частота 65536 КГц. 16 битный таймер переполняется за 1 мсек. Входной сигнал идет в 2 места: на вход другого таймера, считающего импульсы, и на вход capture первого таймера.
Обнуляем оба таймера и запускаем. 1-й от такта, 2-й от входного сигнала. Захватываем состояние первого таймера в момент прихода фронта входного импульса. Записываем t1. При каждом переполнении таймера увеличиваем програмный счетчик. Раз в мсек не обременительно. Когда 1й таймер переполнится например 100 раз (через 0.1 сек от начала), опять включим захват фронта входного сигнала. Сохраним t2 Если его частота 1 МГц или меньше, у нас есть 72 такта или больше чтобы считать из таймера 2 кол-во импульсов за "подотчетный период", легко вычисляемый из t1, t2 и 100 раз периода переполнения таймера (1 мсек). Делим число импульсов на это время и показываем частоту. Заметим, что таймеры мы не остонавливаем и можем продолжать процесс. Что то типа непрерывного time stamping.
Единственная (?) тонкость - если входной сигнал настолько быстрый, что лишний фронт подсчитается за то время, пока мы реагируем на предпоследний фронт, но это видимо можно учесть програмно. Если время реакции скажем 30 тактов, такое произойдет при входной частоте больше 2 МГц. При gate time 0.5 sec это даст погрешность 1 ппм, если не отнимем единицу. Но с такой частотой можно и прямой счет использовать, раз все програмно делается.
Еще вариант: после 100 переполнений разрешаем захват по фронту и сразу останавливаем таймер 2. К его значению прибавим 1, когда произойдет захват по фронту. Но приятнее таймер не останавливать. Тогда точность накапливается.
И еще. Таймеров у нас много, регистров захвата - еще больше. На один вход захвата подадим секундные импульсы от GPS. Измерим кол-во тактов за 1 сек и учтем поправку при вычислении частоты, если эти импульсы присутствуют. Чтобы не открывать коробку и не подкручивать генератор.
Если входная частота низкая, то это все получится. Но метод reciprocal counter дает выигрыш вплоть до входной частоты, равной опорной. Переходить на частотах выше 1 МГц на метод прямого счета - это терять точность почти в 100 раз. Это несерьезно. А на больших частотах описанный Вами алгоритм на таймерах STM32 красиво реализовать не получится - нужно аппаратно одновременно разрешать и запрещать оба таймера, а такой возможности нет. Программно мы никак не сможем узнать, к какому именно подсчитанному входному импульсу относится тот или иной захват.
метод reciprocal counter дает выигрыш вплоть до входной частоты, равной опорной. Переходить на частотах выше 1 МГц на метод прямого счета - это терять точность почти в 100 раз. Это несерьезно.
В данном случае... ИМХО до опорной/2... "Или нет?"(С)...
_________________ "Я не даю готовых решений, я заставляю думать!"(С)
Метод reciprocal counter имеет на любой частоте постоянную относительную погрешность. Она равна погрешности метода прямого счета при входной частоте, равной опорной. Поэтому выигрыш будет до опорной. Но если учитывать конкретную архитектуру МК (наличие синхронизаторов при переходе от внешнего клок-домена к внутреннему), то можно реализовать измерение только до 1/2 опорной. Все равно, на частоте 1 МГц при тактовой 72 МГц у метода прямого счета погрешность будет больше в 72 раза.
alexf58, если смириться с тем, что процесс измерения будет осуществляться не полностью аппаратно и согласиться со всякими оговорками типа "у нас есть 72 такта чтобы считать из таймера", то вообще можно обойтись одним таймером. На вход захвата подать измеряемую частоту, а в прерывании по захвату программно считать входные импульсы. Тогда все получается еще проще. Например, по такому алгоритму "голый" AVR при тактовой 20 МГц может измерять входную частоту почти до 1 МГц, имея на интервале 0.1 сек погрешность 0.5 ppm.
alexf58, если смириться с тем, что процесс измерения будет осуществляться не полностью аппаратно
Леонид Иванович,
можно решать разные задачи. Вы блестяще решили создание недорогого и очень точного прибора. Для моих целей тысячных долей герца не требуется, и я просто задумался о том, как улучшить параметры без аппаратных довесков. Программируемая логика меня не пугает, я делал на FPGA весьма существенные проекты. (Посмотрите, если интересно, http://alexfreed.com/FPGApple).
Просто увидев, насколько наворочены таймеры в STM32, решил подумать, как их можно применить в данном случае. Я начал с того, что 1 ппм соизмерим с точностью опоры, так что потеря после 2 МГц не так велика. Кроме того, на частоте больше 1 МГц можно подключить внутрений prescaler. Программно. Видим около 2 МГц - поделим на 2. Если 10 МГц - поделим на 8.
Я ни секунды не спорю, что у Вас лучше и точнее. У меня просто мысли на тему что можно получить чисто программно.
Ну, не чисто программно, а на встроенной периферии, так, наверное, будет правильней. В STM32 действительно навороченные таймеры, но, как ни странно, они споткнулись на задаче построения частотомера. То, что конкретно в Вашем случае можно обойтись предложенным Вами выше алгоритмом - понятно. Но этот алгоритм - шаг назад даже по сравнению с не очень изящным решением от HHIMERA.
"ызящно, не ызящно"... а работает как надо... На других МК ваще мрак беспросветный...
Цитата:
В описанной реализации мне не очень нравится формирование интервала измерения через число периодов Fin.
А как по другому??? Число периодов то должно быть целое!!!???
Цитата:
Пытался сделать через Output Compare (в начале интервала настраиваем на set, в конце - на clear), но пока ничего не получается.
Другого варианта может и не быть... такое тоже бывает...
Цитата:
специальные ситуации в частотомере - это отдельная тема. У себя делал так: ожидание в течение измерительного интервала фронта входного сигнала. Если не приходит - частота = 0. Если пришел, начинаем счет. Если интервал закончился, а следующего фронта всё нет, ждем еще один интервал. Если не приходит - частота = 0. Ожидание еще одного интервала нужно для того, чтобы гарантированно обеспечить на интервале 1 с измерение сигнала 1 Гц.
Это изящно??? И чем оно отличается от текущего изящества??? Ждём 0,1-0.5сек. ... считываем CNT... домножаем его до 1сек. и заносим в ARR ... CNT==0??? Если да, то ждём еще один интервал (умножаем ARR ещё на два)... "чтобы гарантированно обеспечить на интервале 1 с измерение сигнала 1 Гц."...
_________________ "Я не даю готовых решений, я заставляю думать!"(С)
Это изящно??? И чем оно отличается от текущего изящества???
В Вашем случае формирование интервала зависимо от входного сигнала. Я не говорю про урезание интервала измерения до целого количества входных периодов - это другое. При Вашем алгоритме могут быть грубые ошибки формирования измерительного интервала. На входе может быть все, что угодно. За первую половину интервала в TIM2->CNT может насчитаться одно, а за другую половину - другое, если частота на входе меняется. Частотомер должен показать среднюю частоту, но за фиксированный интервал, а не за какое-то неопределенное время. В идеале мы должны сказать периферии "начать измерение", затем, спустя любое желаемое время, "закончить измерение". В результате в таймерах должно оказаться число входных импульсов и число импульсов заполнения. В моем частотомере на ПЛИС так и есть, а вот STM32 так не может. Все эти манипуляции с формированием измерительного интервала "на лету" я и называю "не очень изящными". То, что Ваш алгоритм работает, не сомневаюсь. Возможно даже, что это единственный вариант для STM32, ведь его навороченные таймеры не имеют возможности синхронного запуска/остановки.
В Вашем случае формирование интервала зависимо от входного сигнала.
В вашем варианте... насколько я понимаю... 1сек. тоже не выдерживается точно... девиация присутствует... потому что тоже привязана к целому числу входных периодов...
Цитата:
При Вашем алгоритме могут быть грубые ошибки формирования измерительного интервала. На входе может быть все, что угодно. За первую половину интервала в TIM2->CNT может насчитаться одно, а за другую половину - другое, если частота на входе меняется. Частотомер должен показать среднюю частоту, но за фиксированный интервал, а не за какое-то неопределенное время.
Показания при 0,9 1,0 и 1,1 сек. я выкладывал... При желании измерительный интервал можно и подстроить... если это нужно... Если частота плавает... то говорить уже о точности как-то... "плюс-минус лапоть"...
Цитата:
В идеале мы должны сказать периферии "начать измерение", затем, спустя любое желаемое время, "закончить измерение". В результате в таймерах должно оказаться число входных импульсов и число импульсов заполнения. В моем частотомере на ПЛИС так и есть, а вот STM32 так не может.
Здесь уже конечно... "Я его слепила из того что было."(С)... Типа "начать измерение", затем, спустя любое желаемое время, "закончить измерение" здесь не главное... Это легко делается...
Цитата:
Все эти манипуляции с формированием измерительного интервала "на лету" я и называю "не очень изящными". То, что Ваш алгоритм работает, не сомневаюсь. Возможно даже, что это единственный вариант для STM32, ведь его навороченные таймеры не имеют возможности синхронного запуска/остановки.
Почему??? Если не Reciprocal... то от одного таймера два-три запускаются и останавливаются одновременно влёгкую... На STM8L15x делал простой частотомер до 60МГЦ... три канала работали одновременно... Фишка в периодах входного сигнала... STM32 оборвёт входной сигнал и референс в любом месте... а нам это не нужно...
_________________ "Я не даю готовых решений, я заставляю думать!"(С)
Спорить здесь не о чем. Ваш способ реализации на сегодняшний день является самым лучшим. Первоначально я считал, что на STM32 вообще невозможно внутри реализовать такой частотомер, отсюда и пошло "HHIMERA гонит". Я бы никогда не додумался до таких вывертов. Когда синтезируешь логику в ПЛИС, каждый узел делает ровно то, что нужно. Все просто и понятно. А в STM логика синтезирована до нас. Приходится для каждой задачи пытаться сделать "из буханки хлеба троллейбус". Это не программирование контроллеров, а головоломка, извращение какое-то.
Приходится для каждой задачи пытаться сделать "из буханки хлеба троллейбус". Это не программирование контроллеров, а головоломка, извращение какое-то.
Может все намного проще , вы всего лишь не в состоянии осознать и принять что весь накопленный опыт на AVR летит коту под хвост? Мышленье на уровне софтовых извращений AVR принесло свои плоды ? Однако прогресс пошел - уже не отвергается все на корню, появились сомнения и думы ...
Никто и не спорит... Способ витиеватый... но что поделать... Многоканальный хардварный 1-wire ещё витиеватее...
Цитата:
А в STM логика синтезирована до нас. Приходится для каждой задачи пытаться сделать "из буханки хлеба троллейбус". Это не программирование контроллеров, а головоломка, извращение какое-то.
Ну... "Чем богаты, тем и рады!"(С)... Это не извращение... это использование железа по максимуму... Программирование контроллеров само по себе является головоломкой... Вопрос только в том... кто и на сколько готов ломать свою голову... Пару раз посещала мысль сделать ещё и синхронизацию внутренними средствами STM32... но что-то "не додумалось"...
_________________ "Я не даю готовых решений, я заставляю думать!"(С)
Вопрос интересный, на сколько нужно ломать свою голову. Это ведь тоже затраты, по крайней мере, сил и времени.
Применительно к наляпанным на скорую свистоперделкам на SPL , естественно не стоит. Здесь же задача как можно быстрей наляпать и сбагрить. Речь-то о вменяемых разработках ...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 18
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения