Юрец

Частотомер На 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    8
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    8
и будет тебе счастье :-)

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

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

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

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


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

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

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


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

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

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


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

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

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

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


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

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

  • Одобряю 1

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


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

спасибо!

Вас понял.

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

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


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

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

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

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

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


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

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

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

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

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

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

Войти

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

Войти сейчас


  • Сообщения

    • Биос сбрасывали? Загрузите живой линукс с флешки. Если все ок, ставьте линукс. Если не ок, значит железо.
    • Всем привет, мне сказали что у меня не работает данная деталь, но не сказали как называеться и где искать (отмечина синим маркером) на ней написано d99241601, но по этому запросу все пусто. Подскажите пожалуйста
    • Ноутбук acer extensa 5620. Изображение есть до загрузки винды потом всё сыпется или зависает. При установке винды также только графический интерфейс появляется всё на экране сыпется. Диагностировать я пока не смогу (нет знаний), но есть два донора с заведомо рабочими чипами. Похоже это на видеочип? Хочу попробовать перепаять, но если проблема может быть в другом элементе в другом пока отложу. 
    • Спасибо, ознакомился , даже и не подозревал о существовании проходных конденсаторов. Неоднократно сталкивался с тем что конденсаторы стоящие  в сигнальных цепях неправильно называют проходными, отсюда и возникает недопонимание )
    • в общем все больше склоняюсь в пользу шириков все таки. Больше шансов получить что-то играющее
    • and13th спасибо,помогло. Теперь я понял откуда этот замечательный кабель.У нас с Вами кабели -братья. Мне его пытались сунуть на базаре как силовой для электромонтажных работ: экран как 0 а две жилы вместе как фаза.Сразу оценил его мягкость в любую погоду.Вы используете "военный" разъем на блок , а я стандартный пятипиновый, с этим кабелем лезет плотно, но зато "забыл" об это соединении. Со стороны датчика использую резиновый гермовводик для электроинструмента. промазываю водостойким "Формула-1"(можно термоклеем). Как раз из-за хорошего качества этого кабеля по прочности можно использовать  именно короткий гермоввод-,проблем не должно быть. В PG-9 (особенно китайских у меня уже было), со временем "летит" пружинка. Относительно пятого провода под графитовый экран - делал такой, пока разницы не почувствовал с ним отдельным или без него на общем экране.Может у кого больше опыта поделяться по этой теме? Пока буду экран графитовый сажать на общий экран Rх обмоток (для SD).   Посыл к rudik  Если информация про обмотку Тх - 40 грамм с вышеизложенными характеристиками шутка, принимаю без обид. Респект опыту  DesAleх ,таки пришлось перемотать Tх под диаметр не 70 , а 73 см под этот корпус. некуда лепить гермоввод(на уши не хотелось).А разница в весе составила 12 грамм( думал будет больше).