Юрец

Частотомер На Atmega

53 сообщения в этой теме

Юрец    7

здравствуйте!

делаю частотомер-тахометр.

использую atmega16, частота от кварца 14,7456000 MHz. таймер по прерыванию 1 сек .

в программе:

int p,i=0;

в теле таймера:

interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{if (p==225) {p=0;printf(" F = %u\r\n",i);i=0;}else p++;

;}

(14,7456000 MHz / 256 / 256=225). при TCCR0=0b00000100;

теоретически таймер тикает правильно (смотрел в протеусе).

в обработчике int0, на который тикают входящие проверяемые импульсы так:

interrupt [EXT_INT0] void ext_int0_isr(void)

{i++;}

трабла в следующем:

при симуляции (подав частоту 6000Гц в протеусе) на терминале вижу:

F=5988

F=6018

F=6018

F=6017

F=6018 и т.д.

что это? глюк протеуса или ошибка в программе? или я неправильно сделал алгоритм подсчета импульсов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
Zenner    1

А почему бы не использовать ещё один таймер для счета импульсов ?

Если ты подашь на внешнее прерывание больше ~150кГц то программа просто застрянет в нем...

Глюки протеуса имеют место быть. Я делал частотомер до 5МГц, тоже на меге. В реале меряет 5МГц с точностью 1-2гц, в протеусе - частота скачет сильнее, намного...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
demonchik    0

Здравствуйте. Алгоритм вашей программы ясен - подсчет импульсов по прерыванию за единицу времени. а как вы включаете таймер с приходом импульса? вель нам надо его включить с приходом 1-го импульса и считать их количество... вроде верно? ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
1.А почему бы не использовать ещё один таймер для счета импульсов ?

2.Если ты подашь на внешнее прерывание больше ~150кГц то программа просто застрянет в нем...

3.Глюки протеуса имеют место быть. Я делал частотомер до 5МГц, тоже на меге. В реале меряет 5МГц с точностью 1-2гц, в протеусе - частота скачет сильнее, намного...

1.может я что-то недопонимаю, но ЗАЧЕМ?

2.фактически это алгоритм автомобильного тахометра. скажем до 8000 оборотов. 8000 * 4 цилиндра = 32кГц. пока это будет максимумом.

3.частотомер до 5МГц своя разработка? можно взглянуть на исходник (если можно, то на Си, т.к. в ассемблере не силен...)

Здравствуйте. Алгоритм вашей программы ясен - подсчет импульсов по прерыванию за единицу времени. а как вы включаете таймер с приходом импульса? вель нам надо его включить с приходом 1-го импульса и считать их количество... вроде верно? ;)

у меня получается так: прерывание по INT0 постоянно срабатывает по входящему импульсу, а таймер тикает постоянно (TIMSK=0X01 - запуск таймера при инициализации), причем обнуляя накопившееся значение каждую секунду.

можно ввести доп. переменную, скажем first_impulse=1 при подаче питания на микроконтроллер, а при первом срабатывании interrupt [EXT_INT0] void ext_int0_isr делаем так: включаем таймер, потом first_impulse=0.

фактически в автомобиле так: сперва вставляем ключ зажигания, поворачиваем, заводим. пусть между подачей питания на микроконтроллер и до момента "зеведенного двигателя" пройдет 0,5-2сек. тогда проверку на "первый импульс" для корректного отображения частоты можно и не делать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zenner    1
1.может я что-то недопонимаю, но ЗАЧЕМ?

2.фактически это алгоритм автомобильного тахометра. скажем до 8000 оборотов. 8000 * 4 цилиндра = 32кГц. пока это будет максимумом.

3.частотомер до 5МГц своя разработка? можно взглянуть на исходник (если можно, то на Си, т.к. в ассемблере не силен...)

1,2. Внешних прерываний у меги увы, не много. Могут куда-нибудь ещё пригодиться. А если есть свободный таймер - почему бы не использовать? Тем самым разгрузив проц для занятия чем-нибудь более полезным.

3. Да, своя. См. ЛС.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
demonchik    0

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
1,2. Внешних прерываний у меги увы, не много. Могут куда-нибудь ещё пригодиться. А если есть свободный таймер - почему бы не использовать? Тем самым разгрузив проц для занятия чем-нибудь более полезным.

3. Да, своя. См. ЛС.

спасибо! разбираюсь.

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

Zenner любезно предоставил : http://kb.3bb.ru/viewforum.php?id=5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
mazzi    3
interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{if (p==225) {p=0;printf(" F = %u\r\n",i);i=0;}else p++;

;}

Я думаю проблема в функции printf

зафиксируй полученное значение в буферной переменной и вынеси printf в основной цикл

{if (p>224) {p=0; i_view=i;i=0; flag=1;}else p++;}

а в основном цикле добавь следующую строку

if (flag) {
   flag=0;
   printf("F=%u\r\n",i_view);
}

и будет тебе счастье :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
и будет тебе счастье :-)

попробовал так, как вы советовали.

получаю:

F=5988

F=6028

F=6028

F=6028

F=6028

F=6029

F=6028

F=6028

F=6028

F=6028

F=6028 и т.д.

все больше склоняюсь к тому, что это глюк протеуса.

Изменено пользователем Юрец

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
mazzi    3
и будет тебе счастье :-)

попробовал так, как вы советовали.

все больше склоняюсь к тому, что это глюк протеуса.

Возможно. Я протеусом не пользуюсь, всё делаю в железе и симуляторе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
Возможно. Я протеусом не пользуюсь, всё делаю в железе и симуляторе.

в каком? не vmlab случайно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А не проще использовать функцию захвата таймера, перевести в обратный код и преобразовать в десятичное значение. Все это делается в основном цикле. Внешнее прерывание будет освобождено "про запас"..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
А не проще использовать функцию захвата таймера, перевести в обратный код и преобразовать в десятичное значение. Все это делается в основном цикле. Внешнее прерывание будет освобождено "про запас"..

имеете ввиду использовать внешнее прерывание таймера по нарастающему фронту? при его появлении запускать другой таймер, и считать кол-во импульсов его?

есть пример для ознакомления?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
Я имею ввиду использовать вход ICP и функцию захвата таймера/счетчика. При возникновении прерывания по данному входу (фронт/спад конфигурируются) достаточно прочитать состояние таймера и вычесть из него предыдущее. Получится измерение периода, правда результат будет получаться обратнопропорциональный. Потребуется перевести полученный результат в обратный код, а так как счетчик работает в двоичном коде, то для читаемости результата потребуется преобразовать двоичный в десятичный. Но все это уже можно делать в основном цикле не нагружая прерывания. 

спасибо!

Вас понял.

з.ы. а случайно нет кода на си - не хочется изобретать велосипед (а то пока разберусь)...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Goodefine    92

Чего то непонятно, в чем нашли проблему.

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{if (p==225) {p=0;printf(" F = %u\r\n",i);i=0;}else p++;
;}

В соответствии с Вашим алгоритмом проверки и инкрементирования счетчика р, таймер на самом деле оттикает 226 интервалов (на один больше чем константа в условии, в этом легко убедится, заменив 225 на, скажем на число 2 - будет три цикла. ). Это и дает погрешность в плюс 26-27. Поэтому и в проверку надо ставить число не единицу меньше. Т.е. 224. И будет не 6028, а гораздо более точное значение. А сам алгоритм далеко не лучший по точности...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
А сам алгоритм далеко не лучший по точности...

а какой лучше? (хотя-бы теорию)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zenner    1

А чем Вам собственно не понравился подсчет импульсов за секунду с помощью ещё одного таймера?

Захват - херня ИМХО. Больно уж низкое разрешение получим(т.к. этот режим не юзал - предполагаю что минимум два такта, а это много.).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
А чем Вам собственно не понравился подсчет импульсов за секунду с помощью ещё одного таймера?

Захват - херня ИМХО. Больно уж низкое разрешение получим(т.к. этот режим не юзал - предполагаю что минимум два такта, а это много.).

тупо держу перед собой даташит на мегу16. пытаюсь вникнуть в регистры таймеров. пока дается с трудом.

я совсем замучил google своими поисками "даташит на мегу16 на русском"... пока безрезультатно...

p.s. все пытаюсь воткнуться в программу.

Изменено пользователем Юрец

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zenner    1

Вот эта книга есть что-то похожее на даташит. На русском.

Там описание всей периферии можно найти...Ну или почти всей...

1000472731.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Юрец    7
Вот эта книга есть что-то похожее на даташит. На русском.

Там описание всей периферии можно найти...Ну или почти всей...

большое СПАСИБО!

скачал. разбираюсь.

а пока вопрос по программе: однократный положительный импульс на вход Т1 вызывает однократный "тик" таймера, или все-таки запускает его счет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Zenner    1

Раз выбрано внешнее тактирование - значит однократный "тик".

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сообщения

    • - у меня есть двухканальная нагрузка на IRFP460 (если не ошибаюсь). По термосопротивлению - они точно как IRFP260, только, естественно, допустимое напряжение повыше. Можно отключить один канал, и практически показать, что все нормально держит 120 В 0,8 А. Но - совсем не до этого.  Если вы так уверены в своей правоте, то скажите номер рисунка, или название зависимости из даташита, куда смотреть? 
    • Источники, оказывается, НЕ балансные, извиняюсь  - это выходы на наушники, в т.ч. от Айпада.  Уровень их шумов - в пределах допустимого. Задача не в том, как уменьшить шумы при смешивании, а в том, чтобы НЕ создать новые. Да, пассивное смешивание неплохо. Но, я не вижу средств не потерять при этом полезный сигнал. Он и так "на грани". Поэтому минимальное усиление, но и одновременно, вновь согласование с низкоомной нагрузкой требует некоторой схемы.  Пусть LM, пусть 2882... Но, надо только однополярное питание. У вас есть ссылки на ОУ с о/п успешно работающие? Я не нашел. Везде критика.  По помехам... Я не могу понять их источник. Да, землю разводить не умею. Но пока у меня шумит все и БЕЗ цифры. Что это? Возбуждение? наводки? Неустойчивый режим ОУ? Обратная связь? Не знаю... Качество  нужно не слишком высокое, думаю, что такой синус меня бы и устроил)) 
    • Помогите опознать деталь с блока сигнализации. Кажись стабилизатор. Но нужно купить такой же.
    • Датчики подкидывал другие,но из одной партии.Подтяжку не менял.Я вобщето думал если датчик цифровой то и код температуры оин на всех 
    • Ну столько времени тут разговор вели,думаю правильным было бы отчет сделать,и соааторов назвать,нарисуйте схему как всё получилось,конечно полную , если не трудно...
    • Могу себе представить эту картину... Говорят, "скупой платит дважды", а если человек идиот... то платит, наверное, пожизненно ))))) Меня один заказчик тоже подбивал на подобный "эксперимент", аргументируя, мол, сам сделал - докажи, что все работает. Я ему доходчиво объяснил, что за свою работу, то есть за правильность сборки схем и качество всех электрических соединений я действительно отвечаю и без вопросов переделаю за свой счет в случае халтуры (перегорания) или ошибки, но если не сработают купленные им же дешевые автоматы или поплавятся дешевые провода, то это будут уже его проблемы. Долго мялся, ходил вокруг да около, пробовал зайти с разных сторон... Но так и не решился ))))) А я вот до конца был уверен, что дурость возмет верх над здравым разумом, поскольку в процессе электромонтажных работ он проявлял невиданное самодурство и просто сказочно выносил мозги.