Таймеры помимо прерывания по переполнению, могут работать в режиме захвата значения, это означает что по пришествии импульса на ногу ICP значение счетчика копируется в регистр хранеия Input Capture. Это дает нам возможность измерять время между соседними импульсами изменяющегося сигнала, тобишь его период и далее, если требуется, высчитать частоту. Для примера использую atmega32 и выведу показания на ЖКИ дисплей. Вывод ICP в atmega32 находится на 20 ноге (PortD.6), туда и заводим сигнал:
Настройка таймера в режим захвата практически такая-же как и в режиме прерывания по переполнению. Необходимо указать предделитель счетчика:
Prescale = 1|8|64|256|1024
и фронт по которому будет происходить захват значения:
Capture Edge = Rising|Falling
От того какой предделитель выбран зависит минимальная частота измеряемого сигнала. Например при значении предделителя 64, переполнение таймера при частоте кварца 16 МГц будет происходить каждые 0,26214 сек. Значит минимальная частота которую точно сможем измерить ~ 4Гц. Максимальная же частота (по идее) упирается в тактовую частоту применяемого кварца. Но proteus почему-то некисло врет после 50 кГц. Поэтому пока оставлю этот вопрос =) В программе предусмотрена проверка значения таймера1, на случай того, если в нем окажется 0, для того чтобы предотвратить деление на этот 0. Что может произойти с МК в противном случаем, можете глянуть здесь.
$regfile = “m32def.dat”
$crystal = 16000000
‘ указываем конфигурацию подключения дисплея к портам МК
Config Lcdpin = Pin, Rs=Portc.5, E=Portc.4, Db4=Portc.0, Db5=Portc.1, Db6=Portc.2, Db7=Portc.3
Config Lcd = 16*2 ‘ тип используемого дисплея
‘настраиваем таймер в режим захвата по восходящему фронту
Config Timer1 = Timer , Prescale = 64 , Capture Edge = Rising
Dim Timercounter As Word
Dim Period As Single ‘ период измеряемого сигнала
Dim F1 As Single
Dim F As Word ‘ переменная для хранения значения частоты
Const T = 0.000004 ‘ примерное время в секундах за которое значение
‘ счетчика увеличивается на 1
On Capture1 Zaxvat
Timercounter = 0
Waitms 50
Enable Interrupts
Enable Capture1
Cursor Off
Do ‘ главный цикл программы
If Timercounter = 0 Then ‘ проверка значения переменной
F = 0 ‘ если 0, то частота тоже 0
Else ‘ в обратном случае высчитываем частоту
Period = Timercounter * T ‘ определяем период
F1 = 1 / Period ‘ считаем частоту
F = Abs(F1) ‘ округляем до целого
EndIf
‘выводим показания на дисплей
Cls
Lcd “Frequency, Hz:”
Lowerline
Lcd F
Waitms 100
Loop
Zaxvat:
Timercounter = Timer1 ‘ копируем значение таймера в переменную
Timer1 = 0 ‘ обнуляем таймер
Return
End
Нога ICP у меня висит в воздухе и ни к чему не подключена.
Как видите, ловит нормальный радиационный электромагнитный фон =) Причем наводки сильнее в местах скопления электробытовой техники, получился простой детектор электромагнитной активности, способствующей разжижению мозга)) Файлы проекта, можно скачать ниже:
Заснял свеженькое видео, которое демонстрирует работу таймера1 в режиме захвата на Atmega8
ave!
Взято с: avrproject.ru
Последние статьи
- Лучшая практика проектирования при размещении компонентов печатной платы
- Android 6.0 на lancer X
- Простой усилитель мощности класса АВ своими руками.
- Двухтактный ультралинейный ламповый УНЧ на EL84 (6П14П).
- Люксметр на ATmega8 и цифровом датчике BH1750
- Контроллер для светодиодной ленты с ИК управлением
- Самодельный LED светильник на основе ИК датчика HC-SR501
- Простой усилитель низкой частоты на TDA7377 и NE5532
- Простейший звонок с двумя мелодиями
- LED Cube 8x8x8 на Arduino с RTC