Цифровой вольтметр на attiny2313

Сейчас всё большую популярность получают измерительные приборы на основе микроконтроллеров со встроенным АЦП, тем более что доступность и возможности таких МК постоянно растут, схемотехника упрощается, а их сборка становиться под силу даже начинающим радиолюбителям. В качестве устройств отображения информации в цифровых измерительных приборах часто используются LCD модули с собственным контроллером. Такому решению присущи недостатки: необходимость дополнительной подсветки с большим током потребления, ограниченный выбор отображаемых символов, высокая стоимость. Поэтому проще и удобнее задействовать семисегментные трёхзнаковые LED индикаторы.

Электросхема вольтметра

Схема принципиальная вольтметра на МК


Схема принципиальная вольтметра на PIC16F676 - второй вариант

ПП вольтметра на PIC16F676

Это простой вольтметр до 30 вольт на основе PIC16F676 микроконтроллера с 10-разрядный АЦП и трех 7-ми сегментных светодиодных индикаторов. Вы можете использовать эту схему для того, чтобы измерить до 30 В постоянного тока. PIC16F676 - это основа этой схемы. Внутренний АЦП микроконтроллера с резисторами делителя напряжения используют для измерения входного напряжения. Затем 3 цифры comm анод 7-сегментный дисплей используется для отображения финальной преобразованное напряжение. Для уменьшения токопотребления в схеме задействована динамическая индикация. Скачать прошивки на различные индикаторы можно здесь.

Работа прибора

На резисторах R1 и R2 собран делитель напряжения, многооборотный построечный резистор R3 служит для калибровки вольтметра. Конденсатор C1 защищает вольтметр от импульсной помехи и сглаживает входной сигнал. Стабилитрон VD1 служит для ограничения входного напряжения на входе микроконтроллера, что бы вход контроллера не сгорел при превышении напряжения по входу.

Расчеты показаний

10-ти битная АЦП позволяет получить максимальное количество 1023. Значит с 5 вольт мы получаем 5/1023 = 0.0048878 В/Д, значит, если значение 188, то входное напряжение: 188 х 0.0048878 = 0.918 вольт. С делителем напряжения максимальное напряжение 30 В, поэтому все расчеты будут 30/1023 = 0.02932 вольт/деление. Так что если сейчас мы получаем 188, то 188 х 0.02932 = 5.5 Вольта. Ещё более упростить и удешевить схему можно заменив АЛС индикаторы на простую
Answer

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry"s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five http://jquery2dotnet.com/ centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

Возникла однажды у меня потребность в нормальном блоке питания. В таком, чтоб мог отдавать в нагрузку ток 4-5 ампера и чтоб напряжение регулировалось. Сказано - сделано. Нашел старинный блок AT блок питания от компа, перепаял. Напряжение регулируется, да вот только сколько там вольт на выходе не понятно. А каждый раз подключать мультиметр мне лень.

Для этого спаял вот это чудо:


Данный вольтметр измеряет напряжение в диапазоне от 0 до 20 вольт. Диапазон может быть расширен или наоборот уменьшен. (придется немного подправить прошивку и пересчитать делитель напряжения). Аппаратная часть почти не представляет интереса: Линейный стабилизатор, источник опорного напряжения на TL431, контроллер и трёхразрядный семисегментый индикатор с общим анодом.

Трёхразрядного индикатора я в Proteus’е не нашел так что не удивляйтесь:-) В принципе, если микрухи TL431 под рукой не будет то можно использовать стабилитрон на 5.1 вольта + делитель напряжения. Но лучше оставить её т.к. измерения будут точней. Стоит она рублей 10 и дефицитом не является. Её можно найти в компьютерных блоках питания в цепях источника дежурного напряжения. Обычно она в корпусе TO-92. Резисторы обвязки лучше применить с допуском 1%. Опять же для точности. Если нет, то можно поставить и обычные. У меня с обычными резисторами источник опорного напряжения выдает около 5.02 вольта, что в принципе нормально. Конденсатор C3 следует расположить максимально близко к микроконтроллеру для снижения всевозможных наводок. Дроссель можно взять любой какой есть в запасах примерно от 10uH до 100 uH. Я нарыл старинный, советского производства. На фото его хорошо видно. Я люблю smd монтаж, и плата соответственно разведена под smd компоненты типоразмера 1206. Ни кто разумеется не запрещает развести свою печатку под выводные детали =) Вместо контроллера Atmega88 можно использовать Atmega8 без изменения схемы. Нужно всего лишь зашить соответствующую программу. Фьюзы микроконтроллера должны быть настроены на тактирование от внутреннего RC генератора работающего на частоте 2 мгц.

Разобравшись с железом поговорим о софте. Впервые я писал программу для микроконтроллера на микропаскале от Mikroelektronika. Впечатления отличные! Удобная среда разработки, справочная система, компактность генерируемого hex, всё это на высоте. Если кто-то захочет подправить прошивку, например сделать её для индикатора с общим катодом, то она в вашем распоряжении внизу страницы. Там же можно обнаружить саму среду разработки в которой этот исходник можно открыть и скомпилировать.

Недавно успешно собрал зарядное устройство, и понадобился мне хороший малогабаритный индикатор вольт и тока заряда. Решил собрать самый простенький ампервольтметр на МК Attiny26 с LCD дисплеем WH08х02. Уменьшенная копия принципиальной электрической схемы ниже:

Принцип работы ампервольтметра

Внутри контроллера, перед АЦП, есть операционный усилитель с возможностью переключать его входы в дифференциальном включении. Для измерения тока до 2 А, напряжение падения с шунта идет напрямую на вход внутреннего операционника, свыше 2А - входы ОУ переключаются на делитель после шунта. Это сделано для получения приемлемой цены деления амперметра во всем диапазоне измерений. Измеряемое напряжение идет через делитель на вход аналого-цифрового преобразователя. Собран он на небольшой плате - смотрите рисунок.

Вольтамперметр способен нормально измерять напряжение до 32 В и ток до 12 А. Индикатор можно применять любой, на основе контроллера HD44780, но оптимально, на мой взгляд - 2х8 символов.

Настройка ампервольтметра на Attiny26

При настойке был приятно удивлен его точностью, так как с измерением напряжения не у кого не было нареканий, а вот с током были разные недовольства. Однако у меня получилось добиться очень даже приличных по точности показаний погрешности. Настраивал его на ток 2 А и показания от 0.2 до 8 А не превышают 1%.

Несколько прошивок есть в архиве на форуме, в своём варианте использовал ту, которая в папке вместе с платами, там же есть еще 3 прошивки в отдельной папке. Шунт амперметра - кусок нихрома диаметром 2 мм длинной 10 см, скрученный в спираль.

Начав копаться с микроэлектроникой я начал с симуляторов. Но как правило это быстро надоедает и хочется попробовать тоже самое но в реальности, то есть чтобы устройство можно было пощупать, потрогать, посмотреть как оно на самом деле. В нашем городе в своё время смог нарыть только МК AtTiny2313 за 40 рублей (в других магазинах у нас же он стоит и 100 и 120 рублей), AtMega’у мне найти не удалось. Попробовав всякие «безделушки» на нём, вроде управления светодиодиками захотелось чего то большего, и вот лазяя по инету наткнулся на статью про вольтметр на сайте дихалта (изиелектроникс). Но! В AtTiny2313 нет АЦП… Но опять же «Но!» =) на всё том же сайте есть статья как сделать из аналогового компаратора и ШИМа этот самый АЦП. Сначала я подумал, а может легче купить атмегу? Но чета влом было искать их у нас, а по инету штучно не продает, или по крайней мере я об этом не знаю. И так, в итоге вольтметр получился, только вот числовые значения надо будем подгонять под пороговые. Так как у этого МК нет отдельного входа для определения границы измеряемого напряжения, оно равно напряжения питания МК. При создании вольтметра использовалось: AtTiny2313, экранчик от DVD-плеера и несколько самых обычных радиодеталей.

Схема самого устройства в Proteus:

Тут добавлен осциллограф чтобы отслеживать ШИМ. Вся проблема была более менее получить нормальный сглаженный выход с ШИМ, именно поэтому в схеме используется вторая RC-цепочка для сглаживания сигнала. Ниже будет показан выход с ШИМ и его сглаживание двумя RC-цепочками.

Структура файлов:

Voltmeter.asm
- - - init.asm
- - - interrupt.asm
- - - subprograms.asm
- - - macros.asm

Как видно из структуры файлов всё начинается с «voltmeter.asm», там происходит определение констант, именование регистров и код основной проги. По именам остальных файлов не сложно догадаться для чего они и всё же: инит — инициализация юарт, шим, таймера, аналогового компаратора и настройка портов; интеррапт — обработчики прерываний; макрос — тут ясно, мои макросы; субпрограмм — аналогично с макросами, мои подпрограммы.
Разберем основной файл. Там заложены основные идеи и всё самое интересное происходит там, не считая прерываний. Смысл такой, сначала объявляем нужные нам константы и переменные:

;///////////////// ;/// Константы /// ;///////////////// ;Настройки RS-232 .equ XTAL = 4000000 .equ BAUDRATE = 9600 .equ bauddivider = XTAL/(16*BAUDRATE)-1 ;Настройки измерений.equ zaderzhka_pwm = 0 ;задержка изменения выхода ШИМ.equ step_dec_pwm = 5 ;шаг изменения выхода ШИМ.equ volt_correct = 20 ;корректировка погрешности аналогового компаратора;Частота обновления значения на экране.equ timeBinBcd_H = 0x00+0x01 .equ timeBinBcd_L = 0x0F ;////////////////// ;/// Переменные /// ;////////////////// ;Временные.def t1 = R16; .def t2 = R17; ;ШИМ.def lev_pwm = R18 ;уровень.def counter_zaderzhka = R19 ;длительность уровня(задержка изменения уровня) ;Значения напряжения на входе аналогово компаратора.def LED_bin_value = R20 ;в данный момент не используется так как;потребовалось увеличить разрядность.def LED_bin_value_H = R25 ;двоичный формат.def LED_bin_value_L = R20 .def LED7segment_1 = R21 ;десятичный формат.def LED7segment_2 = R22 ;Частота обновления напряжения на сегментах экрана.def TimerBinBcd_H = R23 .def TimerBinBcd_L = R24

Затем как обычно начиная программу указываем нужные нам прерывания, а на остальные ставим заглушки. Далее мы попадаем на метку RESET, что соответствует только что включенному устройству. Самое главное первым делом не забыть инициализировать стек, иначе с устройством будет твориться что-то странное, причем даже в отладчике (я пользуюсь AVR Studio). Затем идет инициализация ШИМа, точнее совсем уж сначала =) я задал уровень и задержку, всё по нулям. Это означает что уровень ШИМа будет расти от нуля, и изменяться, то есть увеличиваться каждый раз когда приходит прерывание. Длительность и шаг ШИМа настраивается в константах, кури вставку кода выше. Там всё подробно написано. Далее инициализируются порты (входы\выходы), работа ШИМа и аналоговый компаратор. С этим всё, если посмотреть в код, можно увидеть закоменченные вызовы инициализации экрана и UART, не обращайте на них внимания. Я думал вообще подрубить его к компу и прогу накидать чтобы смотреть график, но не стал, и так нахимичился пока делал АЦП из ШИМа и UARTа, так что кому надо, можете посидеть над этим. Ну вот и всё с началом работы, далее разрешаются прерывания и записываются начальные значения для таймера по которому обновляется значение на экране.

;//////////////////////////////// ;/// Инициализация устройства /// ;//////////////////////////////// RESET: ldi t1, low(RAMEND); Main program start out SPL,t1 ;Set Stack Pointer to top of RAM LDI lev_pwm, 0 LDI counter_zaderzhka, 0 RCALL ports_init RCALL pwm_init RCALL analog_comp_init ;RCALL disp_init ;RCALL uart_init SEI ;Разрешение прерываний LDI TimerBinBcd_H, timeBinBcd_H LDI TimerBinBcd_L, timeBinBcd_L

Подобрались к выполнению основного цикла программы, тут я бы выделил 3 этапа: 1) обновление на экране старшего разряда (свечение циферки слева); 2) обновление на экране младшего разряда (свечение циферки справа); 3) изменение значения для высвечивания на экране.
На счет всех этих свечений и обновлений дело обстоит так. ШИМ постоянно меняет своё значение на выходе. Допустим у нас напряжение от 0 до 5 вольт, допустим оно изменяется за 0.3 секунды за 256 итераций(5 вольт делим на 256 получаем +0.019607843 вольта за каждую итерацию). Теперь главное не запутаться. Теперь перейдем к аналоговому компаратору, так как выход с ШИМа через RC-цепочки идет именно на него. Так вот, аналоговый компаратор, каждые 0.3 секунды выдает пару, тройку а может и десяток раз прерывание. В идеальном случае(читай в идеальных условиях) аналоговый компаратор должен выдать одно прерывание за 0.3 секунды, потому что входное нарпяжение должно один раз совпасть с напряжение на ШИМ. На ШИМе оно ведь всегда уменьшает(или всегда увеличивается) и по идее не равно предыдущему значению. Но! У нас не идеальный мир и есть погрешности, вот из-за этих погрешностей аналоговый компаратор несколько раз выдает прерывания из-за того что сигнал с ШИМа скачет. На картинках ниже это видно. Так, как работает аналоговый компаратор тоже разобрались. Еще раз(допустим у нас идеальный мир): ШИМ меняет значение от 0 до 5 вольт за 0.3 секунды в 255 интераций, аналоговый компаратор за эти 0.3 секунды вызывает один раз своё прерывание в том случае если напряжение с ШИМ и измеряемое напряжения равны.
В этом прерывании это значение записывается в память микроконтроллера (об этом ниже). Теперь возвращаясь в основную программу узнаем, что значения на экране НЕ МЕНЯЮТСЯ МГНОВЕННО с изменением напряжения на входе компаратора. А меняются тогда, когда это разрешит «искусственный» таймер. То есть, значение со входа компаратора меняется один раз в 0.3 секунды, как бы получается что и значение на экране должно меняться раз в 0.3 секунды, если напряжение конечно поменялось. НО! У нас, опять таки, не идеальный мир и за эти 0.3 секунды аналоговый компаратор может сказать что напряжение изменилось десяток раз. И что? Обновлять циферки на экране будем каждый раз, как нам об этом скажет аналоговый компаратор? А вот и нифига, представьте какой мерцание будет у вас на экранчике. Вы даже циферки разглядеть не сможете, представьте одновременно горят цифра 6 и 7, в итоге вы увидите 8 (восьмерку) на экране, потому что человеческий глазичек не успеет разглядеть эту разницу и сольет цифры 6 и 7 вместе. Ну может даже глаза тут не причем будут, а сам сегмент экранчика не успеет затушить цифру 6 и зажечь циферку 7. Так что вот так, для этого и сделан «искусственный» таймер, который меняет циферки (значения измеренного напряжения) на экране гораздо реже, чем делает это аналоговый компаратор с данными (опять же, со значениями измеренного напряжения) в памяти микроконтроллера.
Сначала думал привести код по частям с описанием, но получилось что описание я накатал не отрываясь от клавы. Теперь выкладываю код целиком с основным циклом программы, ибо нефиг тут уже чета по отдельности описывать, выше всё уже накатал. =)

;////////////////////////// ;/// Основная программа /// ;////////////////////////// beg: ;======================= ;=== Старший сегмент === ;======================= ;Выключение экрана CBI PORTB, 3 CBI PORTB, 4 ;Обновление цифры старшего сегмента;LDI t1, 3 MOV t1, LED7segment_1 RCALL DecTo7LedPort ;Включение старшего сегмента экрана CBI PORTB, 3 SBI PORTB, 4 ;Горит старший сегмент экрана loop ;======================= ;=== Младший сегмент === ;======================= ;Выключение экрана CBI PORTB, 3 CBI PORTB, 4 ;Обновление цифры младшего сегмента;LDI t1, 5 MOV t1, LED7segment_2 RCALL DecTo7LedPort ;Включение старшего сегмента экрана SBI PORTB, 3 CBI PORTB, 4 ;Горит младший сегмент экрана loop ;============================================ ;=== Получение нового значения для экрана === ;============================================ ;Насколько часто обновлять значение SUBI TimerBinBcd_L, 1 BRNE end SUBI TimerBinBcd_H, 1 BRNE not_nul_TimerBinBcd_H ;Забрать данные из аналогово компаратора и преобразовать их в двоично-десятичный код binbcd: cli LDI TimerBinBcd_H, timeBinBcd_H MOV t1, LED_bin_value_L MOV t2, LED_bin_value_H RCALL bin2bcd2REG sei not_nul_TimerBinBcd_H: LDI TimerBinBcd_L, timeBinBcd_L end: ;Возврат RJMP beg

Что же вышло. Вся отладка происходила в Proteus. После написание кода и постоянное тестирование его в proteus результат появился. Некоторые проблемы были с выводом циферок на индикаторы, сравнения напряжений на компаратора и пришлось подобрать номиналы резисторов и конденсаторов двух сглаживающих RC-цепочек. На первом скриншоте видно то о чем я писал выше, главная проблема которая была это множественное срабатывание аналогового компаратора на одном цикле ШИМа. Помните я приводил пример за 0.3 секунды 256 интераций? Так вот это оно самое, с ШИМа сигнал падает с максимального напряжения до нуля. За это время в идеальном случае аналоговый компаратор должен был сработать только один раз, а тут фигачет сколько ему захочется. Поясню что видим на экране виртуального осциллографа: желтым — выход ШИМ, голубым — первая RC-цепочка, красным — вторая RC-цепочка, зеленым — срабатывание аналогового компаратора. Первые два скриншота различают тем, что в первом я изменял входное напряжение. Это можно заметить по столбикам (срабатывает аналоговый компаратор) при разном напряжении идущим со сглаживающих RC-цепочек.




Собственно ради интереса сделал этих скриншота, ничего особенно нет, только на первом увеличен фрагмент с двумя срабатывании аналогового компаратора, а второй без. =) Второй показывает как сглаживается сигнал при уменьшении импульсов с ШИМа.



В заключение хотел бы немного уйти от темы и посоветовать всем программистам прочитать книгу «Совершенный код. Мастер-класс» С.Макконнелла , так как если бы я прочитал эту книгу до написания кода вольтметра, он был бы куда аккуратнее и понятнее. =) Так что исходники получайте такие какие есть, плюс кидаю видео как это всё работает.

Видео первой попытки «вольтметра» на Attiny2313. Почему в ковычках? Потому что стоит переменный резистор, на который идет напряжение питания и это питание делиться на 5 пороговых точек. Вот и появляются цифры от 1 до 5. Причем к двум сегментам нет проводов, поэтому они не светятся =).

Предлагаю вашему вниманию конструкцию цифрового вольтметра, который также может быть переделан в амперметр. Схема была взята из журнала Радио №2 за 2010 год. Схема представлена на рисунке

Вольтметр предназначен для измерения напряжения до 0-99,99 в, этот интервал разбит на два участка – 0-9,999в и 10-99,99 в. Переключение с одного диапазона на другой –автоматическое. Входное сопротивление на первом участке – 470 кОм, на втором – около 100 кОм, абсолютная погрешность измерения на первом участке составляет ±3мв, напряжение питания – 15-20 в, потребляемый ток – 60мА(зависит от примененного семисегментного индикатора). Период повторения измерения – 100мс, максимальное время одного цикла преобразования при входном напряжении 9,999 в – 10мс. При превышении измеряемым напряжением 99,99 в на индикаторе отображается число «9999», которое мигает с частотой 2Гц. Полярность входного напряжения - положительная.
Принцип работы вольтметра основан на методе преобразования измеряемого напряжения в частоту с помощью однократного интегрирования. Это позволяет по сравнению с микроконтроллерами, имеющими встроенные десятиразрядные АЦП, получить большую разрешающую способность в широком интервале измеряемого напряжения. Подсчет частоты, переключение пределов и вывод результатов измерения на светодиодный индикатор осуществляет микроконтроллер. Подробное описание работы можно прочитать в статье, в прилагаемом файле, так же исходный код и файл прошивки
depositfiles.com/files/9p9spo2oo
Теперь про доработку этого вольтметра. Резистор делителя напряжения R2 я сделал составным – резистор ПТМН – 0,5Вт 100кОм, ±0,25% и последовательно с ним многооборотный подстроечный СП5-2 на 22 кОм, резистор R5 поставил подстроечный СП3-39А на 15 кОм. Это было сделано для точного подбора сопротивления делителя напряжения при настройке вольтметра.
Вольтметр собран на печатной плате. Плата была перерисована из статьи в программе sprint layout, файл печатки прилагается ниже
depositfiles.com/files/rsbo4oebv
а вот печатка для SMD компонентов
depositfiles.com/files/zi6xq8x7f
Микроконтроллер прошивался при помощи программатора STK 200/300, в программе CodeVisionAVR.
Фьюзы для CodeVisionAVR

Фьюзы для Pony Prog


Питается вольтметр от трансформаторного блока питания с стабилизатором напряжения на микросхеме 7815, собранном по типовой схеме. Блок питания собран на печатной плате, так же на плате находится составной резистор R2 и R5. Файл печатной платы ниже.
depositfiles.com/files/nsaa4kzkj
Фото основной платы вольтметра




Фото блока питания




И теперь все в сборе


Настройка вольтметра заключается в установке резистором R3 тока зарядки конденсатора C2 и подбор сопротивления делителя напряжения. Предварительно делитель подстроечными резисторами настраивается – резистор R2 на сопротивление 117 кОм, резистор R5 на сопротивление 13 кОм. На вход прибора подают стабилизированное напряжение в интервале 9…9.8 в, контролируя образцовым вольтметром. Резистором R3 уравнивают показания налаживаемого и образцового вольтметров. Увеличивают напряжение до тех пор, пока вольтметр не переключится на второй диапазон измерений. Если показания вольтметра «зависли» при этом, то резисторами R2 и R5 добиваются переключения вольтметра на второй диапазон, после этого нужно повторить регулировку резистором R3. Подают на вольтметр максимально возможное напряжение до 100 в и резисторами R2 и R5 корректируют показания. Далее подают на вход от 5 до 10 в и при необходимости корректируют показания резистором R3. Проверяется показания вольтметра во всем диапазоне.
Фото показаний вольтметра на первом диапазоне и образцового прибора Щ301-1.


Фото показаний вольтметра на втором диапазоне и образцового прибора Щ301-1.

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


Показания могут лежать в диапазоне от 0,00 до 99,99А.
Децимальная точка зафиксирована, старший разряд при показаниях, меньших 10А не горит.
Делитель изъят, вместо С4 стоит танталовый конденсатор К53-4 6,8мкФ - для усреднения. В сток транзистора VT1 добавил резистор 1ом, ёмкость-то большая, хоть немного ограничивает пиковый ток разряда.
Для имеющегося шунта необходимо пересчитать ёмкость С2: Сх=(Uпоказ./Uшунт)*С2, где Сх, мкФ - искомая ёмкость конденсатора, Uпоказ., мВ - требуемое максимальное показание амперметра, Uшунт, мВ - напряжение на шунте, соответствующее максимальному измеряемому току, С2 - 2,2мкФ. Пусть на шунте падает 300мВ. Для 10А получается: (1000/300)*2,2 = 7,33 мкФ. Ёмкость лучше округлить в большую сторону, до 8,2мкФ. Номинал резистора R4 придется подобрать, он будет меньше, чем в исходной схеме. Немного измененная прошивка прилагается ниже (так же и исход)