ATmega16 - измерение частоты: внешнее прерывание и расчет
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
ATmega16 - измерение частоты: внешнее прерывание и расчет
Делаю небольшой много функциональный прибор, необходимо сделать тахометр и спидометр, уже битых несколько дней пытаюсь понять как это реализовать на atmega16 и cvavr. Использую внешнее прерывание int0, не понимаю как сделать измерение.... Нашел много информации, но во многих случаях очень поверхностно все описано а брать готовое решение не хочу, есть желание разобраться как это работает, как это реализуется программно. Сниматься показания планируются с 1 цилиндрового 4-х тактного двигателя, максимальная частота 10000 оборотов, измерения хочу выводить раз в секунду.
Очень прошу Вас помочь разобраться в этом. Прошу прощения за столь глупую просьбу, но контроллерами недавно начал увлекаться.
Очень прошу Вас помочь разобраться в этом. Прошу прощения за столь глупую просьбу, но контроллерами недавно начал увлекаться.
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Светодиод зажигать по кнопке можешь? Мигать светиком с частотой 0,7 Гц можешь? Скважность 1/4 мигания можешь? Время между двумя нажиманиями кнопки измерить можешь?
Docendo discimus
-
codenamehawk
- Вымогатель припоя
- Сообщения: 528
- Зарегистрирован: Вт фев 09, 2010 17:52:26
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Пока не ясно на чем застряли. А так ищите код частотомера и разбирайтесь как он работает.
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
pyzhman писал(а):Светодиод зажигать по кнопке можешь? Мигать светиком с частотой 0,7 Гц можешь? Скважность 1/4 мигания можешь? Время между двумя нажиманиями кнопки измерить можешь?
Этого я не умею, прошу помощи разобраться с моментами которые вы описали, по кнопке зажигать светодиод от внешнего прерывания я могу, а вот раотать с частотами просто не понимаю.
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Хех. Тогда для начала тренируемся с выводом инфы на дисплей. Задаем в переменной число(будущий ваш тахометраж) и выпуливаем на экран.
Бонапартовские замашки однако при таком раскладе.
много функциональный прибор
Бонапартовские замашки однако при таком раскладе.
Docendo discimus
- Coolish
- Опытный кот
- Сообщения: 785
- Зарегистрирован: Сб фев 27, 2010 21:45:37
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Для работы с интервалами времени используют таймеры.
Чтоб сделать прерывание таймера в 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, а также код обработчика прерывания, который и будет вызываться раз в секунду.
Для проверки можно в него запихнуть включение и отключение светодиода.
Решение, которое я описал, весьма "грязное" по причине отсутствия понимания действий, но может помочь увидеть что-то работающее и получить стимул разбираться дальше - читать учебники по AVR.
Чтоб сделать прерывание таймера в 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.
Сделать хотел грозу, а получил КоЗу
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
pyzhman писал(а):Хех. Тогда для начала тренируемся с выводом инфы на дисплей. Задаем в переменной число(будущий ваш тахометраж) и выпуливаем на экран.много функциональный прибор
Бонапартовские замашки однако при таком раскладе.
Выводить на экран я могу, это не проблема, у меня уже есть кое-какие наработки
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
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 используется для генерации звука, другими двумя таймерами этого реализовать я так понимаю что нельзя?
Правильно ли я понимаю, для того чтоб прерывание сработало раз в секунду мне необходимо установить компареА равную частоте с предделителем кот орую я выбра?
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Давайте сначала уясним что такое частота?
чем отличается сигнал 1 килогерц и 2 килогерца?
ответ прост - временем между импульсами
частота - это величина обратная времени 1/время = частота
1/частоту= время
потому есть два варианта измерения частоты :
1) посчитать кол-во импульсов исследуемого сигнала за единицу времени(например секунду - тогда результат будет в герцах)
2) посчитать время между двумя импульсами исследуемого сигнала(тогда частота =1/время между импульсами)
всё это могут и должны считать таймеры....например таймер можно заставить отрабатывать секундные интервалы(как - неважно...можно подобрать кварц чтоб по предделителям было подходящее значение) а второй таймер заставить тактоваться от внешней ножки...в прерывании первого таймера(секунд) считываем показания второго таймера(что он успел насчитать) и это и есть частота...проблем нет - всё точно...но...частот меньше 1 герца не увидеть...промежуточных частот тож не увидеть
второй способ проще
в прерывании смотрим - если таймер не запущен то обнуляем его, запускаем на макс частоте процесора и выходим из прерывания
когда потом прийдёт второе прерывание и мы увидим что таймер запущен - останавливаем его, считываем сколько он там наклацать успел, и делаем простой расчет:
F=Fcpu/Tcnt
тоесть мы частоту проца(в герцах) делим на то что натикал таймер...
тут есть одна особенность - таймер умеет считать только до 256 или до 65535 а дальше начнет сначала - потому надо настроить прерывание по переполнению в котором мы будем считать сколько раз таймер переполнялся...тогда во втором приходе прерывания мы возьмём то что в самом таймере есть и прибавим вол-во прерываний таймера умноженное на 256(или 65535 если таймер 16-тибитный используется)
достоинство метода - суперточное измерение низких частот с любым возможным колвом дробной части...это бывает важно для спидометра...вы же не хотите видеть на экране скорость 6, 12, 18, 24, 30 и так далее...вам захочется видеть промежуточные значения...
недостаток метода - скорость обновления напрямую зависит от времени импульсов...тоесть если вы едите 1 км/ч с датчиком выдающим 1 импульс на км то вы и увидите значение скорости только через километр(в лучшем случае)...ну если вдаваться в подробности то есть методы увидеть промежуточные результаты....
главное - начните а там мы Вам поможем....наработки есть готовые приборы тоже есть так что подскажем
чем отличается сигнал 1 килогерц и 2 килогерца?
ответ прост - временем между импульсами
частота - это величина обратная времени 1/время = частота
1/частоту= время
потому есть два варианта измерения частоты :
1) посчитать кол-во импульсов исследуемого сигнала за единицу времени(например секунду - тогда результат будет в герцах)
2) посчитать время между двумя импульсами исследуемого сигнала(тогда частота =1/время между импульсами)
всё это могут и должны считать таймеры....например таймер можно заставить отрабатывать секундные интервалы(как - неважно...можно подобрать кварц чтоб по предделителям было подходящее значение) а второй таймер заставить тактоваться от внешней ножки...в прерывании первого таймера(секунд) считываем показания второго таймера(что он успел насчитать) и это и есть частота...проблем нет - всё точно...но...частот меньше 1 герца не увидеть...промежуточных частот тож не увидеть
второй способ проще
в прерывании смотрим - если таймер не запущен то обнуляем его, запускаем на макс частоте процесора и выходим из прерывания
когда потом прийдёт второе прерывание и мы увидим что таймер запущен - останавливаем его, считываем сколько он там наклацать успел, и делаем простой расчет:
F=Fcpu/Tcnt
тоесть мы частоту проца(в герцах) делим на то что натикал таймер...
тут есть одна особенность - таймер умеет считать только до 256 или до 65535 а дальше начнет сначала - потому надо настроить прерывание по переполнению в котором мы будем считать сколько раз таймер переполнялся...тогда во втором приходе прерывания мы возьмём то что в самом таймере есть и прибавим вол-во прерываний таймера умноженное на 256(или 65535 если таймер 16-тибитный используется)
достоинство метода - суперточное измерение низких частот с любым возможным колвом дробной части...это бывает важно для спидометра...вы же не хотите видеть на экране скорость 6, 12, 18, 24, 30 и так далее...вам захочется видеть промежуточные значения...
недостаток метода - скорость обновления напрямую зависит от времени импульсов...тоесть если вы едите 1 км/ч с датчиком выдающим 1 импульс на км то вы и увидите значение скорости только через километр(в лучшем случае)...ну если вдаваться в подробности то есть методы увидеть промежуточные результаты....
главное - начните а там мы Вам поможем....наработки есть готовые приборы тоже есть так что подскажем
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Не доверяйте русским лужам - это может быть вход в метро.
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
GhostAnton, не надо цитировать, тем более полностью, сообщение на которое сразу за ним отвечаешь..
Форум не резиновый и читать такие темы не удобно.. Привыкай сразу и к правильному..
МитяРа..
Получается тогда следующее, чтоб посчитать 1 секунду времени при тактовой частоте процессора 8000000Гц используя Timer2 нужно таймер настроить так 8000000Гц/64 (предделитель) получаем 125000Гц и используем сброс при совпадении 125 получим 1000Гц и это будет ровняться 1мс времени работы, подсчитав 1000 таких прерываний получим ровно 1 секунду, далее для тахометра просто получим значение счетчика внешних прерываний, это и будет частота вращения в секунду *60 и получаю количество оборотов в 1 минуту, сбрасываю счетчик по внешнему прерыванию в 0 и повторяю все операции. Поправьте меня если я не правильно понял.
Форум не резиновый и читать такие темы не удобно.. Привыкай сразу и к правильному..
МитяРа..
Получается тогда следующее, чтоб посчитать 1 секунду времени при тактовой частоте процессора 8000000Гц используя Timer2 нужно таймер настроить так 8000000Гц/64 (предделитель) получаем 125000Гц и используем сброс при совпадении 125 получим 1000Гц и это будет ровняться 1мс времени работы, подсчитав 1000 таких прерываний получим ровно 1 секунду, далее для тахометра просто получим значение счетчика внешних прерываний, это и будет частота вращения в секунду *60 и получаю количество оборотов в 1 минуту, сбрасываю счетчик по внешнему прерыванию в 0 и повторяю все операции. Поправьте меня если я не правильно понял.
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
прав! для тахометра лучше и не придумаеш....только надо считать не одну секунду а хотябы в десять раз меньший отрезок времени....потому что знать какой была скорость двигателя секунду назад неинтересно ) медленно обновляться будут показания....ну и умножать "насчитанное" надо будет не на 60 а на 600 (если отмерять не 1000 миллисекунд а 100)
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Не доверяйте русским лужам - это может быть вход в метро.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Только тут один минусик появляется: дискретность показаний будет = 600, т.е. на дисплее обороты будут показываться +-600 об/мин. Об этом не стоит забывать.умножать "насчитанное" надо будет не на 60 а на 600
ИМХО, мерить период - самый нормальный вариант. Обороты можно будет считать с хорошим разрешением.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
GhostAnton писал(а):...Сниматься показания планируются с 1 цилиндрового 4-х тактного двигателя, максимальная частота 10000 оборотов, измерения хочу выводить раз в секунду.
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Аlex писал(а):мерить период - самый нормальный вариант.
Не получается правильно замерить период между импульсами, я пробую при обработке внешнего прерывания получить частоту = 1/число прерываний по 1000 гц, получаются слишком большие числа и высокие обороты не получается измерить. К каким частотам лучше всего привязаться?
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
так так так
ещё раз
у вас мотор 10000 об/мин выдаёт?
это сколько в секунду(герц) с датчика? что есть датчик? прерыватель зажигания?
10000 об /мин это 166 герц если импульс с каждого оборота приходит
при замере периода это мелочь..у меня мега на 8 мегагерцах 2 килогерца периодами с прерыванием высчитывала нормально (+-10%) шаг
просто системный таймер надо на 8 мегагерцах запустить или 16-ти - тоесть на системной частоте проца
и не 1/число тиков таймера между импульсами а 8000000/число тиков таймера между прерываниями
вообще говоря можно и без прерывания обойтись...у таймера есть режим захвата...но ваш случай это показометр и +-5% это ничего
ещё раз
у вас мотор 10000 об/мин выдаёт?
это сколько в секунду(герц) с датчика? что есть датчик? прерыватель зажигания?
10000 об /мин это 166 герц если импульс с каждого оборота приходит
при замере периода это мелочь..у меня мега на 8 мегагерцах 2 килогерца периодами с прерыванием высчитывала нормально (+-10%) шаг
просто системный таймер надо на 8 мегагерцах запустить или 16-ти - тоесть на системной частоте проца
и не 1/число тиков таймера между импульсами а 8000000/число тиков таймера между прерываниями
вообще говоря можно и без прерывания обойтись...у таймера есть режим захвата...но ваш случай это показометр и +-5% это ничего
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Не доверяйте русским лужам - это может быть вход в метро.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Точно, там же 4 такта на оборот. Согласен, +-120 об/мин.akl писал(а)::cry: Неее, дискрет будет 120об/мин, т.к.
GhostAnton, Вам нужно считать не переполнения таймера, а считывать сам таймер, затактированный от тактовой частоты МК. А его переполнения считать нужно для расширения разрядности. Кол-во переполнений - это будут старшие байты периода.
-
GhostAnton
- Первый раз сказал Мяу!
- Сообщения: 20
- Зарегистрирован: Пн ноя 21, 2011 19:07:28
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Не совсем получается реализовать, слишком неточно получается измерение по способу
Алгоритм получается следующий, как и описано, в прерывании внешнем такой код
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%, для моего прибора это очень важно.
в прерывании смотрим - если таймер не запущен то обнуляем его, запускаем на макс частоте процесора и выходим из прерывания
когда потом прийдёт второе прерывание и мы увидим что таймер запущен - останавливаем его, считываем сколько он там наклацать успел, и делаем простой расчет:
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%, для моего прибора это очень важно.
-
clawham
- Поставщик валерьянки для Кота
- Сообщения: 1957
- Зарегистрирован: Пт окт 31, 2008 09:38:55
- Откуда: Одесса
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
погрешность? а проц тактуете от чего?
и зачем делить в прерывании?
и ксатти да...при повышении частоты падает и точность...
поэтому частоту проца повыше и постабильней
есть и другой вариант....точнее вопрос - а что мешает в каждом прерывании не перезапуская таймера делать расчеты? искллючится переменная составляющая
тоесть
заводите внешнюю переменную замеренного времени
при попадании в прерывание первым делом снимаете показания таймера в локальную переменную , вторым - обнуляете счетчик , третим - скачиваете кол-во переполнений счетчика, четвертым обнуляете переполнения
а дальше во временную переменную кидаете кол-во переполнений, сдвигаете влево на 8 бит(если таймер 8 бит или на 16 если 16тибитный(что лучше)) и приплюсовываете значение сохраненное самого таймера,
при выходе из прерывания взводите битовый флаг - готов новый замер
в основном цикле крутитесь гденибуть проверяя битфлаг готов новый замер(я например высчитываю текущее возможное показание частоты (если она меньше предыдущей точной) и вывожу на экран то что было бы если б прерывание пришло прямо сейчас....а когда битфлаг поднимается - считаю реальное точное показание частоты, умножения и деления провожу привидения типов и коэффициенты применяю...готовлю к печати и обновляю переменную битфлаг в ноль...
как-то так...но ещё есть уловка - если пока я считал битфлаг снова поднялся прерыванием - значит частота слишком большая - переходим на учет кол-ва импульсов в какой-то промежуток времени и тут я выключаю внешнее прерывание и естественно ещё какой-то флаг перевожу что учёт не по времени а по кол-ву
да что я рассказываю - скачайте исходники ваттметра и сами посмотрите...
и зачем делить в прерывании?
и ксатти да...при повышении частоты падает и точность...
поэтому частоту проца повыше и постабильней
есть и другой вариант....точнее вопрос - а что мешает в каждом прерывании не перезапуская таймера делать расчеты? искллючится переменная составляющая
тоесть
заводите внешнюю переменную замеренного времени
при попадании в прерывание первым делом снимаете показания таймера в локальную переменную , вторым - обнуляете счетчик , третим - скачиваете кол-во переполнений счетчика, четвертым обнуляете переполнения
а дальше во временную переменную кидаете кол-во переполнений, сдвигаете влево на 8 бит(если таймер 8 бит или на 16 если 16тибитный(что лучше)) и приплюсовываете значение сохраненное самого таймера,
при выходе из прерывания взводите битовый флаг - готов новый замер
в основном цикле крутитесь гденибуть проверяя битфлаг готов новый замер(я например высчитываю текущее возможное показание частоты (если она меньше предыдущей точной) и вывожу на экран то что было бы если б прерывание пришло прямо сейчас....а когда битфлаг поднимается - считаю реальное точное показание частоты, умножения и деления провожу привидения типов и коэффициенты применяю...готовлю к печати и обновляю переменную битфлаг в ноль...
как-то так...но ещё есть уловка - если пока я считал битфлаг снова поднялся прерыванием - значит частота слишком большая - переходим на учет кол-ва импульсов в какой-то промежуток времени и тут я выключаю внешнее прерывание и естественно ещё какой-то флаг перевожу что учёт не по времени а по кол-ву
да что я рассказываю - скачайте исходники ваттметра и сами посмотрите...
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Не доверяйте русским лужам - это может быть вход в метро.
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Здравствуйте. Не получается потому, что все подготовительные операции нужно делать до начала измерения, а не во время измерения. Т.е.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;
}
Погрешность определения частоты таким методом определяется P[Гц]>=Fx/(Fclk*Tизм.) или для Ваших данных P[Гц]>=1000/(8'000'000*0.001)>=0.125ГцGhostAnton писал(а):Получается что когда подаю частоту 1000 гц (в моем рассматриваемом случает это 1000 оборотов) то получается 1150 при увеличении частоты погрешность достигает более 1000, каким образом сделать расчеты и подсчеты чтоб погрешность составляла 1%, для моего прибора это очень важно.
- s_black
- Мучитель микросхем
- Сообщения: 411
- Зарегистрирован: Вс авг 10, 2008 19:35:49
- Откуда: Евпатория
- Контактная информация:
Re: ATmega16 - измерение частоты: внешнее прерывание и расче
Топикстартеру.
А почему Вы упёрлись во внешнее прервание? Кто мешает таймером считать внешние импульсы в течении, допустим, 100 мс (ну, или сколько там нужно), подавая их на вход Т1 (Т3)?
А почему Вы упёрлись во внешнее прервание? Кто мешает таймером считать внешние импульсы в течении, допустим, 100 мс (ну, или сколько там нужно), подавая их на вход Т1 (Т3)?