No Image

Вольтметр на микроконтроллере atmega8

СОДЕРЖАНИЕ
1 164 просмотров
12 декабря 2019

Простой вольтметр-амперметр можно собрать на микроконтроллере Atmega8. Вывод информации осуществляется на символьный LCD дисплей 16×2.

  • диапазон измеряемого напряжения: 0 до 25 В;
  • диапазон тока: от 0 до 2.5 В;

Для работы нам понадобятся два канала АЦП, это каналы ADC0 и ADC1, при помощи одного мы мерием напяржение при помощи другого силу тока. В качестве источника внутренного напряжения используется внтуренней опорное напряжение в 2.56 В. АЦП работают с разрядность в 10 бит. Микроконтроллер Atmega8 затактирован от внутреннего RC генератора с частотой в 4 МГц.

Схема Вольтметра-Амперметра на микроконтроллере Atmega8

Вывод информации на дисплей осуществляется следующим образом:

Напряжение которое нам нужно померить сначала подается на делитель напряжения, и уже с него подается на вход АЦП ADC1. Делить собран на резисторах с номиналами в 100 кОм и 10 кОм, получается что отношение входного и выходного напряжения 10 к 1. Максимальное напряжение которое можно подать на вход делителя составляет 28.13 В.

Для того чтобы померить силу тока нам понадобится токовый шунт, его включаем в разры цепи ток в которой хотим померть. Падение напряжения на шутнте нетрудно определить по закону Ома, эта величина меряется други АЦП ADC0. Нужно стремится к уменьшению сопротивлению шунта, чем он меньше тем лучше. Если сопротивление равно 0,1 Ом то при силе тока в 1 Ампера получается падение напряжения в 0,1В.

Если у нас ток в 2 А то падение напряжения составит 0,2 В. Это значение очень мало для того чтобы его подать на вход АЦП микроконтроллера, поэтому его можно устелить при помощи ОУ (операционного усилителя). В нашем примере можно использовать схему неинвертирующего усилителя. Коэффициент усиления составит

Нудно чтобы это коэффициент был равен 10, для того чтобы измеряемы ток, к примеру 1 А соответствовал напряжение на выходе ОУ в 2В. В связи с тем что ИОП (источник опорного напряжения) 2.56 В. то мы не может подать больше этого значения. Шаг измерения тока состовит: 2.56А/2024=2.5 мА.

Таким образом для того чтобы получить значение тока, нам нужно напряжение измеренное АЦП умножить на 2.5

Измерение происходит по прерыванию окончания преобразования АЦП. Сначала выбирается канал 1 и снимается напряжения, далее выбирается второй и также снимается напряжение. Измерения каналов происхоид 400 раз, далее вычисляется среднее значение и выводятся на символьный дисплей.

Диапазон измерения, В……………. 0…19,99 (0…39,99);

Дискретность измерения, мВ………. 10;

Точность во всём диапазоне, мВ…. ±10;

Напряжение питания, В……………. 7…20*;

Потребляемый ток, мА……………. ≤40**;

Габаритные размеры, мм…………. 43х20х11.

Индикация…………………………. 4-х разрядный 7-сегментный с ОА или ОК.

* — при использовании DA1 78L05A

** — зависит от сопротивлений R4…R11

Схема электрическая вольтметра:

Входное измеряемое напряжение поступает на делитель R1, R2, R3, R13 с коэффициентом деления 1:8, а с него на вход PC4 АЦП микроконтроллера DD1. Конденсатор C2 – помехоподавляющий.

Микроконтроллер выбран широко распространённый ATmega8A в малогабаритном корпусе TQFP-32.

В качестве источника опорного напряжения (ИОН) для АЦП использован внутренний напряжением Vref=2.56В. При этом максимальное измеряемое напряжение на входе делителя составляет 2,56•8=20,48В.

Если применить входной делитель с коэффициентом деления 1:16, максимальное измеряемое напряжение можно увеличить до 2,56•16=40,96В.

В программе МК предусмотрены оба варианта делителя. Максимальный предел измерения программно ограничивается величиной 19,99В (39,99В). При превышении предела на индикатор выводится “ 1 -. — — “ (как в старой доброй КР572ПВ2) или “ 3 -. — — ”.

При 10-ти разрядном АЦП его диапазон измерения составляет 0…1023, что дает дискретность измерения непосредственно на входе АЦП: 2560мВ/1024=2,5мВ. С учётом входного делителя напряжения получается дискретность измерения 2,5мВ•8=20мВ (для предела 0…20В) или 2,5мВ•16=40мВ (для предела 0…40В). Для получения необходимой дискретности 10 мВ использован приём многократных выборок АЦП с усреднением результата. На официальном сайте Atmel есть интересный pdf-документ под названием “AVR121. Enhancing ADC resolution by oversampling” (Расширение разрешающей способности АЦП, используя передескритезацию).

На 8-й странице этого документа в таблице 3-1 (правда для Vref=5В) показано, как растёт разрешающая способность 10-разрядного АЦП при увеличении числа выборок. При 4-х выборках с усреднением результата наш АЦП “превращается” в 11-разрядный (0…2047), при 16-ти выборках – в 12-разрядный (0…4095), при 64-х выборках – в 13-разрядный (0…8191) и т.д.

Общая формула для вычисления необходимого количества выборок для прибавки к разрешению АЦП дополнительных n бит: sf = 2 n .

В данном случае для полного использования переменной накопления результата АЦП типа unsigned int (0…65535) оказалось удобным применить 64 выборки. При этом даже при максимальном коде АЦП 1023 переменная накопления результата никогда не переполнится (1023•64=65472), а разрешающая способность вольтметра для случая (0…40В) улучшится в 8 раз и составит 5 мВ, что вполне подходит.

Для компенсации разброса сопротивлений резистивного делителя и начального напряжения ИОН служит подстроечный резистор R3. Подбором сопротивления резистора R13 можно подстроить точность показаний вольтметра более грубо.

Для варианта (0…19,99)В соотношение сопротивлений верхнего плеча делителя к нижнему должно быть 7:1 , а для варианта (0…39,99)В – 15:1 , т.е. во втором случае сопротивление резистора R1 нужно будет увеличить до 510кОм, и возможно подобрать R13.

Светодиодный 4-х разрядный индикатор HL1 KW4-361AGB (с общим анодом) подключен к МК без дополнительных ключевых транзисторов, учитывая небольшой ток потребления. Резисторы R4…R11 определяют яркость свечения индикатора. Можно применить также индикатор с общим катодом, зашив МК соответствующим вариантом hex-файла прошивки. Схема включения при этом остаётся прежней.

Питание микроконтроллера производится через линейный стабилизатор DA1 78L05A, для которого по DataSheet типовая разность между входом и выходом составляет не менее 1,7 В. Практически минимальное напряжение питания схемы составляет около 7 В. Максимальное – не более 30 В. Если необходимо запитать схему от меньшего напряжения, то следует заменить стабилизатор DA1 на другой тип. Выходное напряжение стабилизатора может находиться в пределах от 3 до 5 В. При питании схемы от большего напряжения, чем 20В, последовательно с цепью питания желательно включить стабилитрон для гашения избыточного напряжения с целью снижения мощности рассеивания на DA1.

Программа для микроконтроллера написана на языке Си в хорошо зарекомендовавшей себя среде WinAVR-20060125. Вот вкраце рабочий вариант программы для индикатора с ОА и пределом измерения 19.99В.

Начинается программа традиционно, с подключения библиотек:

#include //Подключение библиотеки задержек

Определяем константы в flash-памяти микроконтроллера::

//Знакогенератор сегментов светодиодного индикатора с ОА:

static unsigned char __attribute__ ((progmem)) SEGMENTE[] =

Это байты, которые будут выводиться в порт D микроконтроллера для получения различных символов в разряде индикатора. Сегменты индикатора a, b, c, d, e, f, g, h, соответствуют линиям порта D следующим образом:

Так оказалось проще разводить печатную плату.

Для коммутации разрядов для порта B также используется табличный массив в flash-памяти:

//Таблица динамической коммутации разрядов индикатора

static unsigned char __attribute__ ((progmem)) RAZR[] =

//4 разр. 3 разр. 2 разр. 1 разр.

Далее определяем глобальные переменные:

volatile unsigned char segcounter = 0 ; //Счётчик разрядов индикатора (0-младший справа, 3-старший слева)

volatile unsigned char mass_ind[]=< 12, 12, 12, 12 >; //Массив выводимых чисел для каждого индикатора (0-младший справа, 3-старший слева), при включении вывод «—.—«

volatile unsigned char p_count= 0 ; //Счётчик прерываний (каждые 0,256мс)

Буфер mass_ind[] будет использоваться для хранения индицируемых цифр каждого разряда. Заноситься информация в него будет после каждого суммарного замера АЦП и преобразования результата в формат ХХ.ХХ В. Считывание информации будет производиться в прерывании по переполнению таймера-счётчика 2 (каждые 0,256мс) для динамической индикации. Первоначально в mass_ind[] заносим данные для вывода на индикатор при включении питания значков “— -. — —«.

В прерывании выставляем лог.1 на аноде текущего разряда в соответствии с состоянием счётчика segcounter, выводим в порт D байт данных из массива mass_ind[] и увеличиваем на 1 переменную segcounter (с проверкой на переполнение и ограничением до 3). Также инкрементируем счетчик прерываний p_count для отсчёта интервалов времени в 0,256мс. Т.о. в каждом прерывании выводится цифра одного из разрядов через каждые 0,256мс. Для 2-го разряда дополнительно добавляется разделительная точка.

//Прерывание по переполнению T2 (), динамическая индикация

PORTB = (PORTB & 0b11110000 ) | pgm_read_byte(RAZR+segcounter); //Активация текущего разряда индикатора

PORTD = pgm_read_byte(SEGMENTE+mass_ind[segcounter]); //Вывод сегментов текущего разряда

if (segcounter== 2 ) //Если 2-й разряд с точкой

PORTD = PIND & pgm_read_byte(SEGMENTE+ 10 ); //Добавка десятичной точки

segcounter++; //Инкремент разрядов индикатора

if (segcounter> 3 ) segcounter= 0 ; //Ограничение счетчика

p_count++; //Инкремент счётчика прерываний

Никаких сложных вычислений в прерывании специально не делается, чтобы обеспечить минимальное время выполнения. Благодаря этому скорость переключения разрядов индикатора составляет 1/0,256мс=3906,25 Гц, а каждый из четырёх разрядов мигает с частотой 3906,25 Гц/4=976,5625 Гц. Частота довольно высокая, так что никакого мерцания индикатора не заметно.

Далее следует основная функция программы, начинающаяся с конфигурации портов, таймера-счетчика 2 и АЦП:

unsigned char adc_counter= 0 ; //Счётчик замеров АЦП

unsigned int display = 0 ; //Выводимое напряжение ХХХХ В

TCCR2 |= ( 1 0 0 //Предделитель на N=1, прерывания каждые 0,256мс (1000000 Гц / 256 = 3906,25 Гц), Fинд=3906,25 Гц/4 = 976,5625 Гц

TIMSK |= ( 1 //Разрешение прерывания по переполнению таймера 2

ADMUX = ( 1 1 //Внутренний ИОН 2,56V

|( 0 //Правое выравнивание результата

|( 0 1 0 0 //Вход АЦП — PC4

_delay_ms( 50 ); //Задержка времени на 50 мс

sei(); //Глобальное разрешение прерываний

В следующем бесконечном цикле при помощи счетчика p_count отсчитываем 15 прерываний по 0,256мс, в результате чего получаем интервал 3,84мс и запускаем одиночное преобразование АЦП. Одновременно увеличиваем на 1 счетчик замеров adc_counter. Результат накапливаем в переменной value.

< if (p_count>= 15 ) //Если прошло 15*0,256мс=3.84мс; общее время замеров 64*3.84=245.76мс (4 замера в сек)

ADCSRA= 0b11000011 ; //Пуск АЦП (Кдел=8, f=125 кГц, однократн.)

while (bit_is_set(ADCSRA, ADSC)); //Ожидание завершения преобразования

value = value + ADC; //Чтение и накопление результата преобразования

adc_counter++; //Инкремент счётчика замеров

После 64 замеров вычисляем напряжение в мВ*10:

Измеренное напряжение для N замеров:

Для отображения 4-х разрядов в формате ХX.ХХ В результат делится на 10 с округлением (прибавляется 5 перед делением)

mVolt=(value+5)/32 (N=64, Кдел=8)

if (adc_counter >= 64 ) //Если прошло 64 замера АЦП

При общем количестве замеров 64 получается суммарное время измерения 3,84мс*64=245,76 мс, т.е. примерно 4 измерения в секунду. Чаще делать нет смысла, иначе показания индикатора будут меняться слишком быстро.

Ну и наконец, заполняем буфер mass_ind[4] для вывода из него информации в прерывании.

//Заполнение массива mass_ind[4] для вывода индикации

if (display > 1999 ) //Если напряжение больше 19,99В

mass_ind[ 1 ] = 12 ; //Вывод "-" в 1-м разряде

mass_ind[ 2 ] = 12 ; //Вывод "-" во 2-м разряде

mass_ind[ 3 ] = 1 ; //Вывод "1" в старший разряд (слева)

mass_ind[ 1 ] = (display/ 10 )% 10 ; //1-й разряд

mass_ind[ 2 ] = (display/ 100 )% 10 ; //2-й разряд

mass_ind[ 3 ] = display/ 1000 ; //Старший разряд (слева)

if (mass_ind[ 3 ]== 0 ) mass_ind[ 3 ]= 11 ; //Если в старшем разряде "0" — гашение старшего разряда

Скриншот симуляции работы программы в Протеусе:


Схема вольтметра собрана на плате из одностороннего фольгированного стеклотекстолита размерами 43х20 мм по лазерно-утюжной технологии:

C1 = 10,0х20В (Танталовый, корпус B)

C2, С4…C6 = 0,47 (0603)

C3 = 22,0х6,3В (Танталовый, корпус A)

DA1 = MC78L05A (SOIC-8)

DD1 = ATmega8A-AU (TQFP-32) или ATmega8

HL1 = KW4-361AGB (4 сегмента, общий анод)

L1, L2 = 22uH (0805)

R1 = 240к или 510к (0805)

R3 = 1к (Подстроечный SMD CV-035, EVM (3×3мм))

R4, R5, R7…R12 = 270* (0603)

Для подключения программатора на плате предусмотрены соответствующие контактные площадки MOSI, MISO, SCK, RESET, GND, +Vcc:

После прошивки программы следует запрограммировать следующие фьюзы ("0"-галочки установлены):

CKSEL3…0=0001 (Внутр.RC-генератор 1 МГц),

CKOPT=1 ,

BODEN=1 (схема BOD выключена),

SUT10=10 (16 CK, 65 ms, Slowly rising power),

Подключение вольтметра производится тремя проводниками: +Uизмер. , +Uпит. и Общий . Если измеряемое напряжение не опускается ниже минимального входного напряжения питания стабилизатора DA1, цепи +Uизмер. и +Uпит. соединяются вместе.

В первый момент после включения на индикаторе высветится “ — -. — — “, т.к. измерения и обработка результата ещё не проведены. Это корректнее, чем выводить первоначально нулевое напряжение, как сделано во всех встраиваемых вольтметрах. После завершения первой серии замеров на индикатор будет выведено напряжение в вольтах.

Подключив параллельно измеряемой цепи образцовый цифровой вольтметр, подстроечным резистором R3 необходимо выставить одинаковые с ним показания. Для повышения точности настройки желательно использовать напряжение ближе к верхнему пределу измерения. Регулировка получается довольно плавная. Возможно придётся дополнительно подобрать сопротивление резистора R13 для “попадания” в нужный диапазон подстройки.

Испытания вольтметра совместно с образцовым мультиметром показали, что погрешность измерения не превышает единицы младшего разряда (±10 мВ) во всём диапазоне 0…19.99 В.

Дата публикации: 25 мая 2011 .

Продолжим изучать аналого-цифровой преобразователь микроконтроллеров AVR на примере цифрового вольтметра постоянного напряжения, с пределами измерения от 0 до 25V. Измеряемое напряжение будет отображаться на трехразрядном семисегментном индикаторе с общим анодом. В этом примере применим динамическую индикацию о которой подробней рассказано на одном из предыдущих занятий, кусок исходного кода возьмем от туда же. Микроконтроллер Atmega8 тактируется от внутреннего генератора частотой 8MHz.

Далее займемся настройкой АЦП. В этот раз попробуем использовать внутренний источник опорного напряжения 2,56V, т.к. выход Aref микроконтроллера соединен с ИОН, для обеспечения стабильности ИОН подключаем к выводу Aref конденсатор. Резистор R3 — подстроечный, он служит для регулировки номинального уровня напряжения, желательно многооборотный.

Входом АЦП является линия PC0(ADCO), т.к. вольтметр у нас должен измерять напряжение до 25V, а 25V для порта контроллера это очень много, в таких случаях используют делитель напряжения. Например, если напряжение на входе будет меняться от 0 до 25V, то на выходе оно будет меняться от 0 до 5V.

Рассчитаем максимальное напряжение Uemax подаваемое на вход АЦП по формуле:

Uemax = 1023*Uref/1024

Uemax = 1023*2.56/1024 = 2,5575V

Рассчитаем максимальное входное напряжение делителя, исходя из параметров: R1=100k, R2=10k, Uemax=2,5575, применим такую формулу:

Uemax = Uin*R2/R1+R2

,где Uin максимальное напряжение подаваемое на вход делителя.

Uin = 2,5575*110k/10k = 28,1325V

Из этого мы знаем, что больше 28,1325V на вход вольтметра подавать нельзя. Также надо знать какой результат будет сохраняться в регистре ADC при изменении напряжения на входе АЦП. Результат преобразования вычисляется по формуле:

ADC = 1024*Uemax/Uref

Например при максимальном напряжении на входе 2,5575V результат преобразования будет таким:

ADC = 1024*2,5575/2,56 = 1023

При напряжении на входе 2V результат будет таким:

ADC = 1024*2/2.56 = 800

Чтобы на индикаторе получить реальные цифры в Вольтах результат преобразования надо умножить на коэффициент равный отношению максимального напряжения(4 разряда) подаваемого на вход делителя к максимальному результату преобразования АЦП.

k = 2813/1023 = 2,75

В программе обработчика прерываний от АЦП результат преобразования перемножаем на этот коэффициент и получаем величину напряжения подаваемого на вход делителя, т.к для операции умножения на дробное число микроконтроллеру потребуется много памяти, существует способ представить число 2,75 по другому, например: (ADC*11)/4. Настраиваем регистры АЦП и Таймера2, глобально разрешаем прерывания, так же в коде вычисляем средний показатель результата преобразования и выводим данные на индикатор. Полный текст программы ниже.

Исходный код для индикатора с общим катодом

При программировании установить такие Fuse — биты:

Читайте также:  Lexman схема подключения проходного двухклавишного выключателя
Комментировать
1 164 просмотров
Комментариев нет, будьте первым кто его оставит

© 2019 | All rights reserved.
Adblock detector