Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.70/23: Рейтинг темы: голосов - 23, средняя оценка - 4.70
Stiom
0 / 0 / 0
Регистрация: 20.07.2011
Сообщений: 2
1

Обнаружение синхронизирующих импульсов

23.07.2011, 15:08. Просмотров 4191. Ответов 5
Метки нет (Все метки)

Доброе время суток!
Я практически не имею опыта в работе с МК (использую ATmega 8). Имеется вот такой сигнал:

<Изображение удалено>
Основной сигнал + синхронизирующие импульсы (частота в 2 раза меньше частоты основного сигнала).
Частота основного сигнала меняется от 100 Гц до 6 000 Гц. Меняется не резко, а постепенно - система имеет некую инерциальность. Допустим что в течении 6 периодов существенно сигнал не меняется.
Необходимо, чтобы МК считал частоту основного сигнала, записывал её в ОЗУ, а при наличии синхронизирующего импульса выполнялась определённая подпрограмма.

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

Вот как считать частоту... Вот например при каждом срабатывании прерывания (по захвату) складывать значение таймера, пока, например, прерываний не пройдет 6 штук, а далее поделить все это время на 6. Мне не требуется высокая точность. Т.е. если у меня в ходе вычислений получится 5 980 Гц, вместо 6 000 Гц, то ничего страшного.

Спасибо за внимание!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.07.2011, 15:08
Ответы с готовыми решениями:

Генерация импульсов
Здравствуйте! Помогите пожалуйста с генерацией импульсов на atmega8. ( Какой таймер использовать и...

Генератор импульсов
Доброе утро, форумчане! Просьба, по возможности помочь. Необходимо на МК Atmega(16 или 32)...

Декодирование PSK (обнаружение смены фазы) на ATMega16
Добрый день! Народ подскажите пожалуйста как на avr обнаружить изменение фазы? Хотя бы просто...

Считывание последовательности импульсов
Доброго времени суток.уповаю на вашу помощь.Проект несколько не по моим силам но тем не...

Алгоритм генерации импульсов
добрый день, помогите пожалуйста составить алгоритм генерации импульсов fИ = 700…1000 Гц с числом...

5
BykTiho
0 / 0 / 0
Регистрация: 12.04.2010
Сообщений: 3,260
23.07.2011, 19:24 2
Один из тех замечательных случаев, когда автор вопроса сам ответил на свой же вопрос. Может, немного не полностью, но суть понятна.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
24.07.2011, 12:30 3
имхо, если я правильно понял, для определения частоты идеально подходит медианный фильтр.
а считать период с сравнивать с порогом - правильное решение.
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
24.07.2011, 22:10 4
Я частоту мерял так:

Таймер0 - тактируется от внешнего сигнала.
Таймер1 - считает такты контроллера (прескалер=1)

В момент прихода стартового импульса запоминаем или обнуляем Таймер1.
После определенного кол-ва импульсов на Таймере0 (напрммер по переполнению - 256) - запоминаем еще раз Таймер1.

В итоге разница показаний Таймера1, деленная на кол-во тактов Таймер0 - вот будет частота, верней, период.

Еще нужны будут ухищрения, типа еще одна переменная - счетчик переполнения Таймера1. Возможно, для большей точности, можно использовать и прерывание по ICP - тогда нужно соединить входы ICP и Таймер0.
0
Stiom
0 / 0 / 0
Регистрация: 20.07.2011
Сообщений: 2
01.08.2011, 01:06 5
Всем спасибо за ответы!
Дописал исходник (архив приложен). Пока только меряет частоту основного сигнала и ловит синхроимпульсы. Далее хочу, чтоб АЦП смотрел ногу МК и мерил напряжение. А потом высчитывал кое-что по напряжению и частоте сигнала. Можно высчитывать через кусочно-линейную функцию или по таблице.
Ну в общем мне частоту именно знать не надо, а надо знать сколько тактов проходит за 1/6 периода основного сигнала.
Вкратце опишу алгоритм:
При прерывании таймера по захвату загружаем из памяти значение предыдущего захвата (tostCapture), сохраняем текущее и вычитаем текущее из прошлого. Это и будет период текущего импульса. Дополнительно, если переменная-счётчик (counter) равна 0, то заносим в память текущий захват в отдельную переменную (stCapture). Загружаем из памяти длительность прошлого импульса (tostImputsi), умножаю на 1.5 через сдвиг вправо и сложение и сравниваю с текущей длительностью. Если текущая больше, чем 1.5 прошлой, то ставлю флаг F_SYNC в регистре, а если меньше, то ставлю флаг F_SPEEDCALC. Далее сохраняю длительность импульса и выхожу. Дальше в зависимости от установленного флага запускаю процедуру. Если F_SPEEDCALC, то сравниваем counter с 6 (измеряю период так - смотрю сколько времени прошло за 6 захватов и делю его на 6), и если не равно, то выходим. Если равно, то делим длительность на 36 (6 импульсов и нужная 1/6 длительности). Делю через процедуру умножения 3х байтового числа на 2х байтовое. 2х байтовое число - это 1/36 записанная в формате 0.16, т.е. 65 536 / 36. В итоге на выходе получаю 24.16, округляю до 24.0, пишу в память. Сбрасываю counter. И всё начинается с начала. А по F_SYNC пока всего-лишь обнуляю counter, чтоб длительность синхроимпульса не мешала измерению.
Скорее всего можно сделать как-то проще и быстрее, но ничего более умного в голову пока не пришло. Но скорость выполнения программы меня вполне устраивает.

Так а собственно вопрос... Касательно вычисления по таблице. Как эту таблицу то сделать? Допустим 16 столбцов и 16 строк для начала. Вот допустим писать таблицу во флеш. Он же адресуется по словам, а мне то и 1 байта за глаза хватит. К сожалению, никогда табличными вычислениями не занимался.

Спасибо за внимание!

[2.05 Кб]
0
vystor_b_k
0 / 0 / 0
Регистрация: 08.05.2010
Сообщений: 332
01.08.2011, 01:54 6
Цитата Сообщение от Stiom
Всем спасибо за ответы!
Дописал исходник (не могу приложить к ответу - пишет "Расширение asm запрещено администратором"). Пока только меряет частоту основного сигнала и ловит синхроимпульсы. Далее хочу, чтоб АЦП смотрел ногу МК и мерил напряжение. А потом высчитывал кое-что по напряжению и частоте сигнала. Можно высчитывать через кусочно-линейную функцию или по таблице.
Ну в общем мне частоту именно знать не надо, а надо знать сколько тактов проходит за 1/6 периода основного сигнала.
Вкратце опишу алгоритм:
При прерывании таймера по захвату загружаем из памяти значение предыдущего захвата (tostCapture), сохраняем текущее и вычитаем текущее из прошлого. Это и будет период текущего импульса. Дополнительно, если переменная-счётчик (counter) равна 0, то заносим в память текущий захват в отдельную переменную (stCapture). Загружаем из памяти длительность прошлого импульса (tostImputsi), умножаю на 1.5 через сдвиг вправо и сложение и сравниваю с текущей длительностью. Если текущая больше, чем 1.5 прошлой, то ставлю флаг F_SYNC в регистре, а если меньше, то ставлю флаг F_SPEEDCALC. Далее сохраняю длительность импульса и выхожу. Дальше в зависимости от установленного флага запускаю процедуру. Если F_SPEEDCALC, то сравниваем counter с 6 (измеряю период так - смотрю сколько времени прошло за 6 захватов и делю его на 6), и если не равно, то выходим. Если равно, то делим длительность на 36 (6 импульсов и нужная 1/6 длительности). Делю через процедуру умножения 3х байтового числа на 2х байтовое. 2х байтовое число - это 1/36 записанная в формате 0.16, т.е. 65 536 / 36. В итоге на выходе получаю 24.16, округляю до 24.0, пишу в память. Сбрасываю counter. И всё начинается с начала. А по F_SYNC пока всего-лишь обнуляю counter, чтоб длительность синхроимпульса не мешала измерению.
Скорее всего можно сделать как-то проще и быстрее, но ничего более умного в голову пока не пришло. Но скорость выполнения программы меня вполне устраивает.

Так а собственно вопрос... Касательно вычисления по таблице. Как эту таблицу то сделать? Допустим 16 столбцов и 16 строк для начала. Вот допустим писать таблицу во флеш. Он же адресуется по словам, а мне то и 1 байта за глаза хватит. К сожалению, никогда табличными вычислениями не занимался.

Спасибо за внимание!
Чтобы выложить Ваш файл, поменяйте расширение, например, было:
myprog.asm, а станет - myprog.asm.txt
А что за проблема - работа с таблицами? Все как обычно! Единственно нужно помнить, что поскольку память программ шестнадцатиразрядная, а указатель Z адресует память побайтово, нужно загружать в указатель удвоенное значение адреса метки начала таблицы.
Особенно легко это делать не на асме, а на Algorithm Builder: Label*2 ->Z
А дальше прибавьте к указателю необходимое смещение в байтах и выбирайте табличные значения.
0
01.08.2011, 01:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2011, 01:54

Генератор импульсов на C8051F020
Уважаемые господа! Есть задача настроить вывод микроконтроллера так, чтобы с него исходили импульсы...

Генератор импульсов на Attiny2313
Короче я не правильно выразился наверное. Мне надо для одного проекта, так что бы с одной ноги...

обнаружение ip
работаю на заводе, тут развернута локальная сеть. и маршрутизаторы и вайфай роутеры все в общем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru