Юрец

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

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

Юрец    9

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

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

использую 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 и т.д.

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

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


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

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

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

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

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


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

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

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


Ссылка на сообщение
Поделиться на других сайтах
Юрец    9
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сек. тогда проверку на "первый импульс" для корректного отображения частоты можно и не делать.

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


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

Найдите миллионы труднодоступных

электронных компонентов

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

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

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

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

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

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


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

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

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


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

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

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

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

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

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


Ссылка на сообщение
Поделиться на других сайтах
mazzi    32
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);
}

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

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


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

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

получаю:

F=5988

F=6028

F=6028

F=6028

F=6028

F=6029

F=6028

F=6028

F=6028

F=6028

F=6028 и т.д.

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

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

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


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

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

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

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

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


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

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

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


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

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

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


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

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

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

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


Ссылка на сообщение
Поделиться на других сайтах
mazzi    32
в каком? не vmlab случайно?

AVR Studio

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


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

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

  • Одобряю 1

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


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

спасибо!

Вас понял.

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

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


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

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

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, а гораздо более точное значение. А сам алгоритм далеко не лучший по точности...

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


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

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

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


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

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

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

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


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

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

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

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

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

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

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


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

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

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

1000472731.jpg

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


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

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

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

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

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

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


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

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

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


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

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

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

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

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

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

Войти

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

Войти сейчас


  • Сообщения

    • Зачем разматывать? Намотать сверху 10 витков, измерить напряжение, найти количество витков на вольт.
    • Cиловые уже раньше забрали, да это как раз и не проблема - грят шо этот блок 8 Вт может дать без переделки как есть
    • иногда там небыло никаких защит. Тупо медная косичка к подвижному контакту. По правильному это называется- ВН (выключатель нагрузки). Но фишка в том, что на корпусе рисуют и обозначают как автоматический выключатель с двумя видами защит.
    • Ну вот вам и новый усилитель готов на 70%  
      получится конечно. А силовики-то забрали? поищите  в интернете по форумам внимательно информацию о этих выходниках, в плане конструкций на них.
      у меня таких небыло ,но  точно где-то очень давно встречал и схему и рекомендации по домотке и фото готового усилителя...сходу не нахожу.
       
    •   Всем, приветики! Банкер, Вы как чувствовали.... А в чем прогрессировать? Я желалку свою удовлетворил - получил ту искрилку которую хотел. Раз в год-полтора меняю свечи..., бо выгорають. Правда пару недель назад ДКЗ захандрила, впервые за 70тыш пробега. Захандрила так, что пришлось снять и кататься на катухе Б117А+полевик, в качестве ключа. Приехал с работы, пошуршал по домашним делам и через часика 4 надо ехать. Завел авто и пока "прогревается" собирался в дорогу. Вдруг слышу, а жужжания мотора нету. Я тык-мык, а мотор не заводится. Быстенько нашел Б117А, установил, прицепил "коммутатор" на полевике и поехал. Потом начал разбираться с ДКЗ..., верхний транзюк "умер". Заменил, установил ДКЗ на авто, дриньь, мотор завелся, но через минуты 3-4 заглох. Разбираю ДКЗ и опять верхний транзюк+диод("выпрямительный")+драйвер транзюка. Меняю все.., мотор завелся, прогрелся, поехали и..., через 3-4км опять ДКЗ умер. Забросил все и две недели катался на Б117А+полевик. В эти минувшие выходные, отчаявшись найти причину "умирания" указаных деталей, метался в поисках сотворения коммутатора на замену ДКЗ, бо Б117А+полевик - не по феншую. Попробовал вариант коммутатора IGO61(схема в прицепе) - по бембался - стало получаться, как у него задумано, но надо ешо додумывать прогу. Попробовал вариант Donec(схема в прицепе) - ну уж очень искра "худенькая". Может что-то я упустил в схемотехнике. Бо все ихние идеи реализовывал чуть по своему. Короче как не крути, а наш ДКЗ круче!  И вчера еду в дальней дороге и обдумываю..., где может быть "зарыта собака"? Ведь 70тиш км отработал нормально(было два случая замены транзюка, но потом работало беззбойно). К стати, а ДКЗ на моей ВАЗ-2105 и посей день работет…, это с 2013г!! Но там другая схема(старая-первая). Почему вышибает именно верхний транзюк и иногда "выпрямительный" диод? Вспомнил осциллограмки токов и напруги на КЗ при отладочном искрении и были редкие  моменты, когда на первой искре вдруг, ни з того, ни с сего,  появлялись огромные токи. И мелькнула мысль.., попробовать в момент генерации первых двух мощных искр, блокировать работу преобразователя. Вечером(вчера), собрал, уже разбарахолиный, ДКЗ, сделал управление(вкл/выкл) преобразователя и успешно протестил работу ДКЗ. Сегодня, утром, установил на авто и благополучно откатал первые 100км.