Самодельный частотомер на ATTINY2313. Самодельный частотомер на ATTINY2313 Простой частотомер на attiny2313 с динамической индикацией

Частотомер с хорошими характеристиками, позволяющий измерять частоты от 1Гц до 10 МГц (9,999,999) с разрешением в 1 Гц во всем диапазоне. Идеален для функиональных генераторов, цифровых шкал или как отдельное устройство. Дешев и легок в изготовлении, собран из доступных деталей, имет небольшой размер и может быть смонтирован на панели многих устройств.

Схема состоит из семи 7-сегментных индикаторов, AVR ATtiny2313 и нескольких транзисторов и резисторов. AVR делает всю работу, и дополнительные микросхемы не нужны. Микроконтроллер считает количество импульсов, пришедших на его вход за 1 секунду и отображает это число. Сама важная вещь - это очень точный таймер, и он реализован на 16-битном Timer1 в режиме CTC. Второе, 8-битный счетчик работает как Counter0 и считает импульсы на входе T0. Каждые 256 импульсов он вызывает прерывание, в котором программа увеличивает множитель. Когда мы получаем 1-секундное прерывание, содержимое множителя умножается на 256 (сдвиг влево на 8 бит). Остаток импульсов, которые посчитал счетчик записывается в регистр и добавляется к результату умножения. Это значение затем разбивается на отдельные цифры, которые отображаются на индикаторах. После этого, перед выходом из 1-секундного прерывания, оба счетчика одновременно сбрасываются и измерение начинается заново. В свободное от прерывания время контроллер занимается динамической индикацией.

Разрешение и точность:
Точность зависит от тактового генератора. Кварц должен быть хорошего качества и иметь как можно меньший ppm (допуск). Будет лучше, если частота будет кратна 1024, например, 16 МГц или 22.1184 МГц. Для измерения частоты до 10 МГц, надо использовать кварц не меньше, чем на 21 МГц, например, 22.1184 МГц. Частотомер может измерять частоту до 47% от частоты собственного кварца. Если есть хороший промышленный частотомер, то можно откалибровать схему добавлением подстроечного конденсатора (1пФ-10пФ) между одним из выводов кварца и землей, и подстроить частоту в соответствии с показаниями промушленного частотомера.

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

Форма сигнала:
В принципе, устройство понимает любую форму сигнала от 0 до 5V, не только прямоугольные импульсы. Синусоида и теугольные импульсы сичтаются по заднему фрону при переходе его ниже 0.8V.

В устройстве нет защиты от превышения входного напряжения выше 5 вольт.

Устройство имеет высокоомный вход и не нагружает тестируемую схему – вы даже можете измерить частоту переменного тока в сети 220 вольт, прикоснувшись ко входу пальцем. Частотомер может быть переделан для измерения частоты до 100 МГц с шагом 10 Гц путем добавления на вход быстродействующего делителя.

Дисплей:
Использовано семь семисегментных индикаторов с общим анодом в режиме динамической индикации. Если яркость получается недостаточной, можно уменьшить значения токоограничивающих резисторов, но нужно помнить, что максимальный импульсный ток каждого вывода микроконтроллера составляет 40 мA . По умолчанию сопротивление резисторов 100 Ом. Незначащие нули гасятся програмно. Значения обновляются каждую секунду.

Печатная плата:
Двусторонняя печатная плата размером 109mm x 23mm – к сожалению, 7 индикаторов не влезли в рабочее пространство бесплатной версии Eagle, поэтому они нарисованы от руки. На плате нужно сделать 3 соединения проводом - первое - соединение питания и вывода VCC контроллера – это соединение показано на слое silkscreen. Два других соединяют десятичные точки индикаторов с резисторами на 330 Ом расположенными на слое bottom. Сверху платы расположен коннектор Atmel ISP-6. Контакт 1 первый со стороны кварца. Этот коннектор необязателен и нужен только для программирования контроллера. Индикаторы должны припаиваться на некотором расстоянии от платы, чтобы можно было подлезть паяльником к выводам, припаиваемым с верхней стороны платы.

Данный прибор предназначен для измерения частоты в пределах 0-9999 Гц, но при использовании делителя частоты на входе этот диапазон соответствующим образом расширяется. Максимальное входное напряжение – 3V, при условии, что отсутствует дополнительный делитель напряжения, минимальное 0,15V, так же при условии что он отсутствует. Максимальную частоту измерения можно расширить посредством изменения программного кода, но об этом позже.

Схема прибора относительно простая и изображена ниже:

В основе схемы – 8-ми битный микроконтроллер производства , Atmega8A-PU. Для тактирования ядра микроконтроллера применен генератор с внешним кварцевым резонатором. Выбор такого генератора обусловлен требованиями к стабильности частоты последнего. В качестве индикатора применен семисегментный четырехразрядный LED индикатор с общим анодом и динамической индикацией. Ток сегментов индикатора не ограничивается резисторами, так как применена динамическая индикация, и естественно ток импульсный, который сегменты индикатора с успехом выдерживают, так как и порт микроконтроллера. Входной узел выполнен на элементах R2, D1, D2, C3, R3, R4, R1, Q1. Этот узел обеспечивает усиление/ограничение сигналов, поступающих на его вход (резистор и диоды на входе частотомера ограничивают входной сигнал, транзистор отвечает за усиление сигнала до ТТЛ уровня). Печатная плата устройства так же не сложная. Она изготавливается из одностороннего фольгированного материала (изначально планировалось сделать из двухстороннего, но в наличии его не нашлось, поэтому остановился на односторонней). Топология платы представлена ниже.

Что касается программы для микроконтроллера, то она была разработана в среде (файл проекта прилагается). Для подсчета импульсов я использовал прерывания по входу INT0 микроконтроллера, а для ограничения времени счета – прерывания таймера TMR0. Так как на этом таймере стоит предделитель с коэффициентом деления 1/256 (в силу того что он восьмиразрядный), то расчет частоты прерываний производится так:Fпрер.=F ген.÷256÷поргр. дел. В своей конструкции я выбрал частоту прерываний в 200 Гц. Как я уже писал выше, частоту измерения можно увеличить. Для этого нужно лишь ограничить время измерения. Это делается посредством изменения числа 200 на 2(время измерения не 1с а 10мс, граничная частота 99 999Гц), в коде, как показано на рисунке в исходнике на С.

Для программирования микроконтроллера я использовал параллельный программатор. Как видите, в моей конструкции вывод внешнего сброса используется как обычный порт. Если у вас нет параллельного программатора, то вот вариант схемы, где используется порт D микроконтроллера, и необходимость в использовании пина RESET как обычного порта вывода отпадает.

Вот пример выставления фузов в программе :

Вот схема варианта частотомера с использование RESET по прямому назначению:

А так же вот топология платы для второго варианта схемы:

Для питания схемы используется стабилизированный источник питания на напряжения 5V (я использовал компьютерный БП, поэтому никаких стабилизирующих элементов в схеме нет).

В данной схеме нет дефицитных деталей, но список замен и аналогов все же перечислю. Так микроконтроллер Atmega8A-PU можно заменить на аналогичный Atmega8-16PU (кстати, последний более предпочтителен). Резисторы можно взять на мощность 0,125 Вт, за исключением R2, его лучше взять на 0,5 Вт. Конденсаторы – для генератора дисковые, керамические, а для входного блока – любой, подходящий по параметрам. Транзистор можно заменить на отечественный КТ3102 (как показали опыты у КТ315 слишком мал коэффициент передачи тока h21Э). Светодиодный индикатор можно взять любой, подходящий по размерам (а они не критичны). Кварцевый резонатор использован на частоту 3267800Гц (3,2768МГц).

Фотографии готового устройства показаны ниже.

На первом фото видно резистор, который подключен к питу RESET МК (остался с проверки второй прошивки, со сбросом).

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
U1 МК AVR 8-бит

ATmega8A

1 ATmega 8-16 PU В блокнот
Q1 Биполярный транзистор

КТ3102

1 2N3390 В блокнот
VD1, VD2 Выпрямительный диод

1N4148

2 В блокнот
С1, С2 Конденсатор 27 пФ 2 В блокнот
С3 Конденсатор 22 нФ 1 В блокнот
R1, R4 Резистор

470 Ом

2 В блокнот
R2 Резистор

100 Ом

1
Очень полезный и несложный прибор, который просто незаменим в творческой лаборатории радиолюбителя, можно сделать на МК PIC16F628A. Для измерения частот до 30 Мгц и предназначен данный цифровой частотомер на распространённой микросхеме-контроллере PIC16F628A. Его принципиальная схема состоит из базового модуля, с подключенным к его счетному входу входным формирователем. Схема частотомера приведена на рисунке ниже:

Данный измерительный прибор может использоваться в двух режимах - цифровая шкала и измеритель частоты. При включении питания, частотомер переходит в тот режим, в котором он работало до последнего выключения питания. Если это был режим частотомера - в левом разряде индикатора высветится режим частотомера "F.". Так-же в младшем разряде индикатора высветится "0". Частотомер автоматически перейдет в режим измерения частоты и будет находиться в режиме ожидания. При подаче на вход какого-то сигнала, признак режима частотомера "F." гасится и индикатор отобразит значение измеряемой частоты в килогерцах.
Схема входного формирователя частотомера - цифровой шкалы, приведена на рисунке:


Если на момент включения питания, на входе частотомера присутствует измеряемый сигнал, то, после включения питания, признак работы частотомера "F.", высветится в течение 1-й секунды, а затем погаснет.
Для того чтобы перейти на время измерения 0,1 сек. или 10 сек., необходимо нажать либо кнопку № 1, либо одновременно нажать кнопку № 1 и кнопку № 2 соответственно (см. раскладку клавиатуры для режима частотомера), затем дождаться изменения положения десятичной точки, после чего отпустить кнопку (кнопки). Если после этого необходимо вернуться к времени измерения 1 сек., то необходимо нажать кнопку № 2 и дождаться изменения положения десятичной точки, после чего отпустить кнопку. Для любого времени измерения десятичная точка отмечает килогерцы.


Раскладка клавиатуры режима частотомера

Кнопка № 1 0,1 сек. Переход на время измерения 0,1 сек.
Кнопка № 2 1 сек. Переход на время измерения 1 сек.
Кнопка № 1 +
кнопка № 2 10 сек. Переход на время измерения 10 сек.
(кнопки нажимаются одновременно)

Если перед выключением питания происходила работа в режиме цифровой шкалы, то при следующем включении питания будет установлен именно этот режим, а внутри режима цифровой шкалы будет установлен именно тот подрежим ("минус ПЧ" или "плюс ПЧ"), в котором происходила работа до последнего выключения питания. Признаки подрежимов цифровой шкалы ("L." или "H." соответственно) будут постоянно высвечиваться в левом разряде индикатора. При отсутствии сигнала на входе цифровой шкалы, индикатор будет показывать значение записанной в память контроллера промежуточной частоты, а при его наличии - результат вычитания или сложения частоты сигнала, присутствующего на входе цифровой шкалы, и значения промежуточной частоты, записанной в энергонезависимую память PIC контроллера.


Режим цифровой шкалы имеет 4 подрежима.
- При нажатии на кнопку № 1 происходит переход в подрежим "минус ПЧ".
- При этом, в левом разряде индикатора, высветится признак подрежима "L.".
- При нажатии на кнопку № 2 происходит переход в подрежим "плюс ПЧ".
- При этом, в левом разряде индикатора, высветится признак подрежима "H.".

В процессе "прошивки" контроллера, в его энергонезависимую память записывается значение промежуточной частоты = 5,5 мГц., но потом может будет самостоятельно записать в нее любое значение и использовать ее в качестве промежуточной. Для этого надо подать на вход ЦШ внешний сигнал с частотой, которая далее будет использоваться в качестве промежуточной. Проконтролировать значение этой частоты можно, перейдя в режим частотомера.

Раскладка клавиатуры режима цифровой шкалы:
Кнопки Время измерения Пояснения
Кнопка № 1 "минус ПЧ" Промежуточная частота вычитается из
измеряемой частоты
Кнопка № 2 "плюс ПЧ" Промежуточная частота суммируется с
измеряемой частотой
Кнопка № 1 +
кнопка № 2 Установка ПЧ Запись в оперативную память значения
измеряемой частоты (ПЧ)
Повторно:
Кнопка № 1 +
кнопка № 2 Запись ПЧ Копирование значения измеряемой частоты из оперативной памяти в энергонезависимую с целью дальнейшего ее использования в качестве промежуточной


При смене режима работы, меняется раскладка клавиатуры. Если кнопка № 1 находится в нажатом состоянии меньше определенного времени, то переключения в другой режим не происходит и кнопка № 1 может либо устанавливать время измерения 0,1 сек. (в режиме частотомера), либо включать подрежим "минус ПЧ" (в режиме цифровой шкалы). Если этот порог превышен, происходит переключение в другой режим. Величина этого порога - около 4 сек., и этот интервал времени отсчитывается с момента окончания цикла счета, приходящегося на момент нажатия кнопки № 1.


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


Прошивки для микроконтроллера PIC16F84A, а также полный текст статьи на контроллере качаем тут. Схему испытал - ZU77.

Представленный в данной статье частотомер позволяет измерять частоту от 10 Гц до 60 МГц с точностью 10 Гц. Это позволяет использовать данный прибор для самого широкого применения, например измерять частоту задающего генератора, радио приёмника и передатчика, функционального генератора, кварцевого резонатора и др. Частотомер обеспечивает хорошие параметры и обладает хорошей входной чувствительностью, благодаря наличию усилителя и TTL-преобразователя. Это позволяет измерять частоту кварцевых резонаторов. Если использовать дополнительный делитель частоты, максимальная частота измерения может достигать 1 ГГц и выше.

Идея частотомера на микроконтроллере PIC, возникла у меня после прочтения апнота AN592 фирмы Microchip, где описывается измерение частоты на PIC и представлена программа. Я разработал схему и написал программу, в которой улучшил точность измерения, а значение частоты отображается на LCD-экранчике. Получился довольно простой и эффективный частотомер.

Схема частотомера довольно простая, большинство функций выполняет микроконтроллер. Единственное, для микроконтроллера необходим усилительный каскад, чтобы увеличить входное напряжения с 200-300 мВ до 3 В. Транзистор, включенный по схеме с общим эмиттером, обеспечивает псевдо-TTL сигнал, поступающий на вход микроконтроллера.

В качестве транзистора необходим какой-нибудь "быстрый" транзистор, я применил BFR91 (отечественный аналог КТ3198В).

Напряжение V кэ устанавливается на уровне 1.8-2.2 вольта резистором R3* на схеме. У меня это 10 кОм, однако может потребоваться корректировка. Напряжение с коллектора транзистора прикладывается к входу счетчика/таймера микроконтроллера PIC, через последовательное сопротивление 470 Ом. Для выключения измерения, в PIC задействываются встроенные pull-down резисторы.

В PIC реализован 32-битный счетчик, частично аппаратно, частично софтово. Подсчет начинается после того, как выключаются встроенные pull-down резисторы микроконтроллера, продолжительность составляет точно 0.4 секунды. По истечении этого времени, PIC делит полученное число на 4, после чего прибавляет или отнимает соответствующую промежуточную частоту, для получения реальной частоты. Полученная частота конвертируется для отображения на дисплее.

Калибровка

Для того, чтобы частотомер работал правильно, его необходимо откалибровать. Проще всего это сделать так: подключить источник импульсов с заранее точно известной частотой и вращая подстроечный конденсатор выставить необходимые показания.

Если данный метод не подходит, то можно воспользоваться "грубой калибровкой". Для этого, выключите питание прибора, а 10 ножку микроконтроллера подсоедините на GND. Затем, включите питание. МК будет измерять и отображать внутреннюю частоту. Если вы не можете подстроить отображаемую частоту (путем подстройки конденсатора 33 пФ), то кратковременно подсоедините вывод 12 или 13 МК к GND. Возможно, что это нужно будет сделать несколько раз, т.к. программа проверяет эти выводы только один раз за каждое измерение (0.4 сек). После калибровки, отключите 10 ногу микроконтроллера от GND, не выключая при этом питания прибора, чтобы сохранить данные в энергонезависимой памяти МК.

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
МК PIC 8-бит

PIC18F84J11

1 В блокнот
Линейный регулятор

LM7805

1 В блокнот
Транзистор BFR91 1 В блокнот
Выпрямительный диод

1N4007

1 В блокнот
Конденсатор 1 мкФ 1 В блокнот
10 мкФ 1 В блокнот
Электролитический конденсатор 1 мкФ 1 В блокнот
Конденсатор 0.1 мкФ 1 В блокнот
Конденсатор 33 пФ 1 В блокнот
Конденсатор подстроечный 33 пФ 1 В блокнот
Резистор

470 Ом

2 В блокнот
Резистор

10 кОм

1 Подбор В блокнот
Резистор

10 кОм

1 В блокнот
Переменный резистор 10 кОм 2

Данный урок будет достаточно простым. Надеюсь, вы хорошо усвоили прошлые материалы: урок по таймерам и управление кнопками.

Чтобы понять зачем нужны внешние прерывания, приведу простой пример: допустим у вас в основном цикле программы используются задержки (например, для мигания светодиодом), при этом вам кнопкой нужно перевести работу светодиода в другой режим. Если обработка кнопки находится в основном цикле, то придется ждать пока не отработают все фрагменты кода и очередь не дойдет до обработки кнопки. Иногда это не удобно.

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

Количество ножек, отведенных для внешних прерываний, зависит от типа микроконтроллера, например у atmega8 их 2, у atmega16 их 3. Называются они INT0, INT1 и т.п.

Срабатывать прерывание может по нарастанию сигнала Rise edge, по спаду Falling edge, по любому изменению Any change, Low level по низкому уровню. В визарде выглядит так:

Теперь рассмотрим, как пример, необычное использование внешнего прерывания — частотомер.

Допустим, на ножку настроенную на внешнее прерывание, по нарастанию фронта, подается пульсирующий сигнал. Соответственно каждый период будет срабатывать прерывание, нам остается только подсчитывать их количество за одну секунду.

Для этого настроим таймер 1 на срабатывание 1 раз в секунду, как в 5 уроке. При срабатывании прерывания таймера, обнуляем счетчик и выводим результат на дисплей.

#include // Alphanumeric LCD Module functions #asm .equ __lcd_port= 0x18 ; PORTB #endasm #include #include unsigned long i = 0 , freq= 0 ; char lcd_buf[ 33 ] ; interrupt [ EXT_INT0] void ext_int0_isr(void ) { i++; } interrupt [ TIM1_COMPA] void timer1_compa_isr(void ) { freq= i; i= 0 ; TCNT1H= 0x00 ; TCNT1L= 0x00 ; } void main(void ) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB= 0x00 ; DDRB= 0x00 ; PORTD= 0xFF ; DDRD= 0x00 ; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 7,813 kHz // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A= 0x00 ; TCCR1B= 0x05 ; TCNT1H= 0x00 ; TCNT1L= 0x00 ; ICR1H= 0x00 ; ICR1L= 0x00 ; OCR1AH= 0x1E ; OCR1AL= 0x85 ; OCR1BH= 0x00 ; OCR1BL= 0x00 ; // External Interrupt(s) initialization // INT0: On // INT0 Mode: Rising Edge // INT1: Off GICR|= 0x40 ; MCUCR= 0x03 ; GIFR= 0x40 ; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK= 0x10 ; // Global enable interrupts #asm("sei") lcd_init(8 ) ; while (1 ) { sprintf (lcd_buf, "freq=%d" , freq) ; lcd_gotoxy(0 , 0 ) ; lcd_puts(lcd_buf) ; } ; }

#include // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x18 ;PORTB #endasm #include #include unsigned long i = 0, freq=0; char lcd_buf; interrupt void ext_int0_isr(void) { i++; } interrupt void timer1_compa_isr(void) { freq=i; i=0; TCNT1H=0x00; TCNT1L=0x00; } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; PORTD=0xFF; DDRD=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 7,813 kHz // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x1E; OCR1AL=0x85; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization // INT0: On // INT0 Mode: Rising Edge // INT1: Off GICR|=0x40; MCUCR=0x03; GIFR=0x40; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x10; // Global enable interrupts #asm("sei") lcd_init(8); while (1) { sprintf(lcd_buf,"freq=%d",freq); lcd_gotoxy(0,0); lcd_puts(lcd_buf); }; }