Страница 1 из 2
ATmega16 - измерение частоты: внешнее прерывание и расчет
Добавлено: Вт фев 28, 2012 14:21:19
GhostAnton
Делаю небольшой много функциональный прибор, необходимо сделать тахометр и спидометр, уже битых несколько дней пытаюсь понять как это реализовать на atmega16 и cvavr. Использую внешнее прерывание int0, не понимаю как сделать измерение.... Нашел много информации, но во многих случаях очень поверхностно все описано а брать готовое решение не хочу, есть желание разобраться как это работает, как это реализуется программно. Сниматься показания планируются с 1 цилиндрового 4-х тактного двигателя, максимальная частота 10000 оборотов, измерения хочу выводить раз в секунду.
Очень прошу Вас помочь разобраться в этом. Прошу прощения за столь глупую просьбу, но контроллерами недавно начал увлекаться.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 15:00:51
pyzhman
Светодиод зажигать по кнопке можешь? Мигать светиком с частотой 0,7 Гц можешь? Скважность 1/4 мигания можешь? Время между двумя нажиманиями кнопки измерить можешь?
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 17:22:43
codenamehawk
Пока не ясно на чем застряли. А так ищите код частотомера и разбирайтесь как он работает.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 21:08:12
GhostAnton
pyzhman писал(а):Светодиод зажигать по кнопке можешь? Мигать светиком с частотой 0,7 Гц можешь? Скважность 1/4 мигания можешь? Время между двумя нажиманиями кнопки измерить можешь?
Этого я не умею, прошу помощи разобраться с моментами которые вы описали, по кнопке зажигать светодиод от внешнего прерывания я могу, а вот раотать с частотами просто не понимаю.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 21:29:55
pyzhman
Хех. Тогда для начала тренируемся с выводом инфы на дисплей. Задаем в переменной число(будущий ваш тахометраж) и выпуливаем на экран.
много функциональный прибор
Бонапартовские замашки однако при таком раскладе.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 21:36:00
Coolish
Для работы с интервалами времени используют таймеры.
Чтоб сделать прерывание таймера в CVAVR, есть мастер генерации кода. Сначала нужно указать, на какой частоте работает контроллер - вкладка Chip, она определяется кварцем. Без кварца, по умолчанию, будет 1 Мгц, но стабильность этой частоты, а значит, и результатов измерений, привязанных к ней, не гарантируется.
После установки тактовой частоты контроллера, в мастере можно включить любой из трёх таймеров, выставить предделитель. Мастер показывает вместо значения предделителя сразу значение тактовой частоты, поступающей на таймер.
Для примера возьмём Timer1, заводскую частоту 1 МГц и сделаем прерывание, которое будет срабатывать каждую секунду.
Включаем таймер, Clock Source: System Clock. Выставляем предделитель 64, при котором частота таймера станет 1000000/64 = 15625 Гц (Clock Value: 15,625 kHz). Далее, выставляем в регистре сравнения OCR1A значение 15625, для чего пишем в поле Comp.A его шестнадцатеричное представление- 3D09. Режим таймера устанавливаем Mode: CTC TOP OCR1A. Далее ставим галку Interrupt On: Compare A Match
Мастер в результате сгенерит код инициализации таймера 1, а также код обработчика прерывания, который и будет вызываться раз в секунду.
Код: Выделить всё
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
}
Для проверки можно в него запихнуть включение и отключение светодиода.
Решение, которое я описал, весьма "грязное" по причине отсутствия понимания действий, но может помочь увидеть что-то работающее и получить стимул разбираться дальше - читать учебники по AVR.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 21:52:58
GhostAnton
pyzhman писал(а):Хех. Тогда для начала тренируемся с выводом инфы на дисплей. Задаем в переменной число(будущий ваш тахометраж) и выпуливаем на экран.
много функциональный прибор
Бонапартовские замашки однако при таком раскладе.
Выводить на экран я могу, это не проблема, у меня уже есть кое-какие наработки
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вт фев 28, 2012 22:06:01
GhostAnton
Coolish писал(а):Для работы с интервалами времени используют таймеры.
Чтоб сделать прерывание таймера в CVAVR, есть мастер генерации кода. Сначала нужно указать, на какой частоте работает контроллер - вкладка Chip, она определяется кварцем. Без кварца, по умолчанию, будет 1 Мгц, но стабильность этой частоты, а значит, и результатов измерений, привязанных к ней, не гарантируется.
После установки тактовой частоты контроллера, в мастере можно включить любой из трёх таймеров, выставить предделитель. Мастер показывает вместо значения предделителя сразу значение тактовой частоты, поступающей на таймер.
Для примера возьмём Timer1, заводскую частоту 1 МГц и сделаем прерывание, которое будет срабатывать каждую секунду.
Включаем таймер, Clock Source: System Clock. Выставляем предделитель 64, при котором частота таймера станет 1000000/64 = 15625 Гц (Clock Value: 15,625 kHz). Далее, выставляем в регистре сравнения OCR1A значение 15625, для чего пишем в поле Comp.A его шестнадцатеричное представление- 3D09. Режим таймера устанавливаем Mode: CTC TOP OCR1A. Далее ставим галку Interrupt On: Compare A Match
Мастер в результате сгенерит код инициализации таймера 1, а также код обработчика прерывания, который и будет вызываться раз в секунду.
Код: Выделить всё
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
}
Для проверки можно в него запихнуть включение и отключение светодиода.
Решение, которое я описал, весьма "грязное" по причине отсутствия понимания действий, но может помочь увидеть что-то работающее и получить стимул разбираться дальше - читать учебники по AVR.
Спасибо, с этим немного понятно, такое сравнение в 16 меге можно делать только таймером1, в 0 и 2 таймерах таких настроек нет, у меня таймер1 используется для генерации звука, другими двумя таймерами этого реализовать я так понимаю что нельзя?
Правильно ли я понимаю, для того чтоб прерывание сработало раз в секунду мне необходимо установить компареА равную частоте с предделителем кот орую я выбра?
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 01:40:57
clawham
Давайте сначала уясним что такое частота?
чем отличается сигнал 1 килогерц и 2 килогерца?
ответ прост - временем между импульсами
частота - это величина обратная времени 1/время = частота
1/частоту= время
потому есть два варианта измерения частоты :
1) посчитать кол-во импульсов исследуемого сигнала за единицу времени(например секунду - тогда результат будет в герцах)
2) посчитать время между двумя импульсами исследуемого сигнала(тогда частота =1/время между импульсами)
всё это могут и должны считать таймеры....например таймер можно заставить отрабатывать секундные интервалы(как - неважно...можно подобрать кварц чтоб по предделителям было подходящее значение) а второй таймер заставить тактоваться от внешней ножки...в прерывании первого таймера(секунд) считываем показания второго таймера(что он успел насчитать) и это и есть частота...проблем нет - всё точно...но...частот меньше 1 герца не увидеть...промежуточных частот тож не увидеть
второй способ проще
в прерывании смотрим - если таймер не запущен то обнуляем его, запускаем на макс частоте процесора и выходим из прерывания
когда потом прийдёт второе прерывание и мы увидим что таймер запущен - останавливаем его, считываем сколько он там наклацать успел, и делаем простой расчет:
F=Fcpu/Tcnt
тоесть мы частоту проца(в герцах) делим на то что натикал таймер...
тут есть одна особенность - таймер умеет считать только до 256 или до 65535 а дальше начнет сначала - потому надо настроить прерывание по переполнению в котором мы будем считать сколько раз таймер переполнялся...тогда во втором приходе прерывания мы возьмём то что в самом таймере есть и прибавим вол-во прерываний таймера умноженное на 256(или 65535 если таймер 16-тибитный используется)
достоинство метода - суперточное измерение низких частот с любым возможным колвом дробной части...это бывает важно для спидометра...вы же не хотите видеть на экране скорость 6, 12, 18, 24, 30 и так далее...вам захочется видеть промежуточные значения...
недостаток метода - скорость обновления напрямую зависит от времени импульсов...тоесть если вы едите 1 км/ч с датчиком выдающим 1 импульс на км то вы и увидите значение скорости только через километр(в лучшем случае)...ну если вдаваться в подробности то есть методы увидеть промежуточные результаты....
главное - начните а там мы Вам поможем....наработки есть готовые приборы тоже есть так что подскажем
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 11:54:45
GhostAnton
GhostAnton, не надо цитировать, тем более полностью, сообщение на которое сразу за ним отвечаешь..
Форум не резиновый и читать такие темы не удобно.. Привыкай сразу и к правильному..
МитяРа..
Получается тогда следующее, чтоб посчитать 1 секунду времени при тактовой частоте процессора 8000000Гц используя Timer2 нужно таймер настроить так 8000000Гц/64 (предделитель) получаем 125000Гц и используем сброс при совпадении 125 получим 1000Гц и это будет ровняться 1мс времени работы, подсчитав 1000 таких прерываний получим ровно 1 секунду, далее для тахометра просто получим значение счетчика внешних прерываний, это и будет частота вращения в секунду *60 и получаю количество оборотов в 1 минуту, сбрасываю счетчик по внешнему прерыванию в 0 и повторяю все операции. Поправьте меня если я не правильно понял.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 12:14:25
clawham
прав! для тахометра лучше и не придумаеш....только надо считать не одну секунду а хотябы в десять раз меньший отрезок времени....потому что знать какой была скорость двигателя секунду назад неинтересно ) медленно обновляться будут показания....ну и умножать "насчитанное" надо будет не на 60 а на 600 (если отмерять не 1000 миллисекунд а 100)
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 12:32:57
Аlex
умножать "насчитанное" надо будет не на 60 а на 600
Только тут один минусик появляется: дискретность показаний будет = 600, т.е. на дисплее обороты будут показываться +-600 об/мин. Об этом не стоит забывать.
ИМХО, мерить период - самый нормальный вариант. Обороты можно будет считать с хорошим разрешением.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 12:44:45
akl

Неее, дискрет будет 120об/мин, т.к.
GhostAnton писал(а):...Сниматься показания планируются с 1 цилиндрового 4-х тактного двигателя, максимальная частота 10000 оборотов, измерения хочу выводить раз в секунду.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 13:49:26
GhostAnton
Аlex писал(а):мерить период - самый нормальный вариант.
Не получается правильно замерить период между импульсами, я пробую при обработке внешнего прерывания получить частоту = 1/число прерываний по 1000 гц, получаются слишком большие числа и высокие обороты не получается измерить. К каким частотам лучше всего привязаться?
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 16:37:08
clawham
так так так
ещё раз
у вас мотор 10000 об/мин выдаёт?
это сколько в секунду(герц) с датчика? что есть датчик? прерыватель зажигания?
10000 об /мин это 166 герц если импульс с каждого оборота приходит
при замере периода это мелочь..у меня мега на 8 мегагерцах 2 килогерца периодами с прерыванием высчитывала нормально (+-10%) шаг
просто системный таймер надо на 8 мегагерцах запустить или 16-ти - тоесть на системной частоте проца
и не 1/число тиков таймера между импульсами а 8000000/число тиков таймера между прерываниями
вообще говоря можно и без прерывания обойтись...у таймера есть режим захвата...но ваш случай это показометр и +-5% это ничего
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Ср фев 29, 2012 18:01:10
Аlex
akl писал(а)::cry: Неее, дискрет будет 120об/мин, т.к.
Точно, там же 4 такта на оборот. Согласен, +-120 об/мин.
GhostAnton, Вам нужно считать не переполнения таймера, а считывать сам таймер, затактированный от тактовой частоты МК. А его переполнения считать нужно для расширения разрядности. Кол-во переполнений - это будут старшие байты периода.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Сб апр 07, 2012 15:13:51
GhostAnton
Не совсем получается реализовать, слишком неточно получается измерение по способу
в прерывании смотрим - если таймер не запущен то обнуляем его, запускаем на макс частоте процесора и выходим из прерывания
когда потом прийдёт второе прерывание и мы увидим что таймер запущен - останавливаем его, считываем сколько он там наклацать успел, и делаем простой расчет:
F=Fcpu/Tcnt
тоесть мы частоту проца(в герцах) делим на то что натикал таймер...
Алгоритм получается следующий, как и описано, в прерывании внешнем такой код
if(TCCR0==0x00)
{ //запустим таймер
TCCR0=0x01;
TCNT0=0x00;
OCR0=0x00;
}
else
{
//остановим таймер и сделаем расчеты i - количество полных кругов таймера
TCCR0=0x00;
Count = TCNT0;
frequency = 8000000UL/(i*255+Count);
i=0;
}
Получается что когда подаю частоту 1000 гц (в моем рассматриваемом случает это 1000 оборотов) то получается 1150 при увеличении частоты погрешность достигает более 1000, каким образом сделать расчеты и подсчеты чтоб погрешность составляла 1%, для моего прибора это очень важно.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Сб апр 07, 2012 20:54:14
clawham
погрешность? а проц тактуете от чего?
и зачем делить в прерывании?
и ксатти да...при повышении частоты падает и точность...
поэтому частоту проца повыше и постабильней
есть и другой вариант....точнее вопрос - а что мешает в каждом прерывании не перезапуская таймера делать расчеты? искллючится переменная составляющая
тоесть
заводите внешнюю переменную замеренного времени
при попадании в прерывание первым делом снимаете показания таймера в локальную переменную , вторым - обнуляете счетчик , третим - скачиваете кол-во переполнений счетчика, четвертым обнуляете переполнения
а дальше во временную переменную кидаете кол-во переполнений, сдвигаете влево на 8 бит(если таймер 8 бит или на 16 если 16тибитный(что лучше)) и приплюсовываете значение сохраненное самого таймера,
при выходе из прерывания взводите битовый флаг - готов новый замер
в основном цикле крутитесь гденибуть проверяя битфлаг готов новый замер(я например высчитываю текущее возможное показание частоты (если она меньше предыдущей точной) и вывожу на экран то что было бы если б прерывание пришло прямо сейчас....а когда битфлаг поднимается - считаю реальное точное показание частоты, умножения и деления провожу привидения типов и коэффициенты применяю...готовлю к печати и обновляю переменную битфлаг в ноль...
как-то так...но ещё есть уловка - если пока я считал битфлаг снова поднялся прерыванием - значит частота слишком большая - переходим на учет кол-ва импульсов в какой-то промежуток времени и тут я выключаю внешнее прерывание и естественно ещё какой-то флаг перевожу что учёт не по времени а по кол-ву

да что я рассказываю - скачайте исходники ваттметра и сами посмотрите...
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вс апр 08, 2012 12:00:11
akl
GhostAnton писал(а):Не совсем получается реализовать, слишком неточно получается измерение по способу
Здравствуйте. Не получается потому, что все подготовительные операции нужно делать до начала измерения, а не во время измерения. Т.е.
-запретить прерывания INT0 и переполнение Т0
-провести начальные установки
i=0
TCCR0=0; остановить таймер и
TCNT0=9; установить начальное значение Т0, компенсирующее начальную задержку, вызванную
; прерыванием от входного сигнала на INT0 и запуском Т0
TIFR=0 ;
GIFR=0 ;
- глобально разрешить все прерывания
- и вот только сейчас будет следовать
if(TCCR0==0x00)
{ //запустим таймер
TCCR0=0x01;
}
else
{
//остановим таймер и сделаем расчеты i - количество полных кругов таймера
TCCR0=0x00;
Count = TCNT0;
frequency = 8000000UL/(
i*255+Count);
это ошибка - нужно i*256 i=0;
}
GhostAnton писал(а):Получается что когда подаю частоту 1000 гц (в моем рассматриваемом случает это 1000 оборотов) то получается 1150 при увеличении частоты погрешность достигает более 1000, каким образом сделать расчеты и подсчеты чтоб погрешность составляла 1%, для моего прибора это очень важно.
Погрешность определения частоты таким методом определяется P[Гц]>=Fx/(Fclk*Tизм.) или для Ваших данных P[Гц]>=1000/(8'000'000*0.001)>=0.125Гц
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Добавлено: Вс апр 08, 2012 16:54:04
s_black
Топикстартеру.
А почему Вы упёрлись во внешнее прервание? Кто мешает таймером считать внешние импульсы в течении, допустим, 100 мс (ну, или сколько там нужно), подавая их на вход Т1 (Т3)?