<
  • Главная
Статьи

Главная Новости

АЦП микроконтроллеров AVR. Делаем цифровой вольтметр 0 - 25V


Опубликовано: 01.09.2018

видео АЦП микроконтроллеров AVR. Делаем цифровой вольтметр 0 - 25V

Easy AVR 2016-05-22 Встроенный АЦП микроконтроллера AVR

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



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


Микроконтроллеры avr для начинающих "aцп в Atmega 16"

Входом АЦП является линия 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, глобально разрешаем прерывания, так же в коде вычисляем средний показатель результата преобразования и выводим данные на индикатор. Полный текст программы ниже.

// Использование АЦП. Цифровой вольтметр. Общий анод #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> //------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80}; volatile unsigned char segcounter = 0; volatile unsigned int display = 0; // Прерывание по переполнению T2, динамическая индикация ISR (TIMER2_OVF_vect) { PORTD = 0xFF; // Гасим все сегменты PORTB = (1 << segcounter); // Последовательно зажигаем общие аноды switch (segcounter) { case 0: PORTD = ~(SEGMENTE[display % 10000 / 1000]); // Выводим первый разряд break; case 1: PORTD = ~((SEGMENTE[display % 1000 / 100])|0x80); // добавляем десятичную точку break; case 2: PORTD = ~(SEGMENTE[display % 100 / 10]); // Выводим третий разряд break; } if ((segcounter++) > 1) segcounter = 0; } volatile unsigned long value; volatile unsigned int adc_counter; // Прерывание по окончанию преобразования АЦП ISR (ADC_vect) { value = value + (ADC*11/4); // Суммируем старое и новое значения АЦП, преобразуем adc_counter++; // Увеличиваем счетчик измерений } // Главная функция int main (void) { DDRB = 0xFF; // Выходы на общие аноды PORTB = 0x00; // Ноль на выходе DDRD = 0xFF; // Выходы на сегменты PORTD = 0x00; // Ноль на выходе // Настройка Таймера 2 TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2 TCCR2 |= (1 << CS21); // Предделитель на 8 // Настройка АЦП ADCSRA |= (1 << ADEN) // Разрешение АЦП |(1 << ADSC) // Запуск преобразования |(1 << ADFR) // Непрерывный режим работы АЦП |(1 << ADPS2)|(1 << ADPS1) // Предделитель на 64 (частота АЦП 125kHz) |(1 << ADIE); // Разрешение прерывания от АЦП ADMUX |= (1 << REFS1)|(1 << REFS0); // Внутренний ИОН 2,56V, вход ADC0 sei(); // Глобально разрешаем прерывания // Главный цикл while(1) { if(adc_counter > 300) // Если количество измерений больше 300 { display = value/adc_counter; // Вычисляем среднее значение АЦП adc_counter = 0; // Обнуляем счетчик измерений value = 0; // Обнуляем буфер АЦП } _delay_ms(50); } }

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

// Использование АЦП. Цифровой вольтметр. Общий катод #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> //------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80}; volatile unsigned char segcounter = 0; volatile int display = 0; //Прерывание по переполнению T2, динамическая индикация ISR (TIMER2_OVF_vect) { PORTD = 0x00; // Гасим все сегменты PORTB = ~(1 << segcounter); // Последовательно зажигаем общие катоды switch (segcounter) { case 0: PORTD = SEGMENTE[display % 10000 / 1000]; // Выводим первый разряд break; case 1: PORTD = (SEGMENTE[display % 1000 / 100])|0x80; // добавляем десятичную точку break; case 2: PORTD = SEGMENTE[display % 100 / 10]; // Выводим третий разряд break; } if ((segcounter++) > 1) segcounter = 0; } volatile unsigned long value; volatile unsigned int adc_counter; // Прерывание по окончанию преобразования АЦП ISR (ADC_vect) { value = value + (ADC*11/4); // Суммируем старое и новое значения АЦП, преобразуем adc_counter++; // Увеличиваем счетчик измерений } // Главная функция int main (void) { DDRB = 0xFF; // Выходы на общие аноды PORTB = 0x00; // Ноль на выходе DDRD = 0xFF; // Выходы на сегменты PORTD = 0x00; // Ноль на выходе // Настройка Таймера 2 TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2 TCCR2 |= (1 << CS21); // Предделитель на 8 // Настройка АЦП ADCSRA |= (1 << ADEN) // Разрешение АЦП |(1 << ADSC) // Запуск преобразования |(1 << ADFR) // Непрерывный режим работы АЦП |(1 << ADPS2)|(1 << ADPS1) // Предделитель на 64 (частота АЦП 125kHz) |(1 << ADIE); // Разрешение прерывания от АЦП ADMUX |= (1 << REFS1)|(1 << REFS0); // Внутренний ИОН 2,56V, вход ADC0 sei(); //глобально разрешаем прерывания // Главный цикл while(1) { if(adc_counter > 300) // Если количество измерений больше 300 { display = value/adc_counter; // Вычисляем среднее значение АЦП adc_counter = 0; // Обнуляем счетчик измерений value = 0; // Обнуляем буфер АЦП } _delay_ms(50); } }

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

Обсуждение статьи на форуме .

Архив для статьи "АЦП микроконтроллеров AVR. Делаем цифровой вольтметр 0 - 25V"
Описание: Файлы проекта для AVR Studio
Размер файла: 16.51 KB Количество загрузок: 7 087 Скачать


Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью

rss