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

10/05/2010 - 21:00

Схема

вольтметр на микроконтроллере

Логика программы

  В начале программы выполняются функции инициализации. Настраивается и запускается АЦП, конфигурируется порт, к которому подключен индикатор, и настраивается таймер Т0. Затем разрешаются прерывания, и микроконтроллер выполняет  бесконечный цикл. В цикле опрашивается программный буфер АЦП и вычисляется значение напряжения. Вычисленное значение передается функции индикатора, которая преобразует его в двоично-десятичные цифры, затем в коды цифр индикатора и записывает их в массив (буфер).
   Параллельно основной программе вызываются прерывания АЦП и таймера Т0. АЦП работает в режиме однократного преобразования, с внутренним опорным источником напряжения на 2,56В. Выравнивание вправо, используются все 10 разрядов. Результат преобразования АЦП накапливается 8 раз в переменной, усредняется и записывается в программный буфер.
   В прерывании таймера Т0 происходит его перезапуск и вызывается функция обновления индикатора. Она гасит текущий отображаемый разряд и зажигает следующий.

Структура проекта

Проект состоит из 3-ех программных модулей.
main.c – основная программа
adc.c – функции для работы с АЦП
indicator.c – драйвер семисегментного 4-ех разрядного индикатора.

Драйвер семисегментного индикатора

   В заголовочном файле indicator.h с помощью директивы #define определены порты и номера выводов микроконтроллера, к которому подключен индикатор.

//куда подключены сегменты
#define PORT_IND PORTB
#define DDR_IND DDRB

#define SEG_A 0
#define SEG_B 1
#define SEG_C 2
#define SEG_D 3
#define SEG_E 4
#define SEG_F 5
#define SEG_G 6
#define SEG_DP 7

//куда подключены упр. выводы
#define PORT_TR PORTD
#define DDR_TR DDRD

#define NUM1 0
#define NUM2 1
#define NUM3 2
#define NUM4 3

Для работы с индикатором используется три функции – функция инициализации, функция преобразования и функция обновления индикатора.

void IND_Init(void);
void IND_Output(unsigned int value, unsigned char comma);
void IND_Update(void);

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

Функция инициализации

//количество разрядов индикатора
#define AMOUNT_NUM 4

//буфер семисегментного индикатора
unsigned char
buf[AMOUNT_NUM];

void IND_Init(void)
{
  PORT_IND = 0xff;
  DDR_IND = 0xff;
 
  PORT_TR |= (1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4);
  DDR_TR |= (1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4);

  for(unsigned char i = 0; i < AMOUNT_NUM; i++) buf[i] = 0;
}

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

Функция преобразования

//массив для преобразования десятичных чисел в коды индикатора
unsigned char number[] =
{
  (1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(0<<SEG_G), //0
  (0<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(0<<SEG_D)|(0<<SEG_E)|(0<<SEG_F)|(0<<SEG_G), //1
  (1<<SEG_A)|(1<<SEG_B)|(0<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(0<<SEG_F)|(1<<SEG_G), //2
  (1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(0<<SEG_E)|(0<<SEG_F)|(1<<SEG_G), //3   
  (0<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(0<<SEG_D)|(0<<SEG_E)|(1<<SEG_F)|(1<<SEG_G), //4
  (1<<SEG_A)|(0<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(0<<SEG_E)|(1<<SEG_F)|(1<<SEG_G), //5
  (1<<SEG_A)|(0<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G), //6
  (1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(0<<SEG_D)|(0<<SEG_E)|(0<<SEG_F)|(0<<SEG_G), //7
  (1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(1<<SEG_E)|(1<<SEG_F)|(1<<SEG_G), //8
  (1<<SEG_A)|(1<<SEG_B)|(1<<SEG_C)|(1<<SEG_D)|(0<<SEG_E)|(1<<SEG_F)|(1<<SEG_G)  //9
};

void IND_Output(unsigned int value, unsigned char comma)
{
  unsigned char tmp;
  for(unsigned char i = 0; i < AMOUNT_NUM; i++){
    tmp = value % 10;
    buf[i] = number[tmp];
    value = value/10;
  }

  if (comma < AMOUNT_NUM) {
    buf[comma] |= 1<<(SEG_DP);
  }
    
}

   Эта функция преобразует переданное ей 16-ти разрядное число (value) в коды цифр индикатора и записывает в программный буфер. Кроме этого она устанавливает в определенном разряде индикатора запятую. Номер разряда определяется переменной comma.
  Преобразование выполняется следующим образом. Переданное функции число делится по модулю 10. Результатом выполнения этой операции будет остаток от деления числа на 10, что позволяет нам как бы отделить младший разряд десятичного числа от его остальной части. Используя результат деления по модулю в качестве индекса массива number, мы преобразуем это число в код цифры индикатора.

Для ясности небольшой пример.Возьмем число 123.

Первое выполнение цикла for  - i = 0
tmp = value % 10 = 123 % 10 = 3
buf[0] = number[3]
value = value/10 = 123/10 = 12

Второе выполнение цикла for  - i = 1
tmp = value % 10 = 12 % 10 = 2
buf[1] = number[2]
value = value/10 = 12/10 = 1

Третье  выполнение цикла for  - i = 2
tmp = value % 10 = 1 % 10 = 1
buf[2] = number[1]
value = value/10 = 1/10 = 0

Четвертое (последнее) выполнение цикла for  - i = 3
tmp = value % 10 = 0 % 10 = 0
buf[3] = number[0]
value = value/10 = 0/10 = 0

   Коды цифр индикатора в массиве number записаны с помощью макроопределений. Это позволяет подключать выводы сегментов индикатора к порту микроконтроллера в любом порядке. 

Функция обновления индикатора

//макросы для настройки драйвера индикатора под другую схему
#define LightOutAll()  PORT_TR &= ~((1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4))
#define BurnDigit(port, digit) port |= (1<<digit) 
#define ValueBuf() buf[count]


void IND_Update(void)
{
  static unsigned char count = 0;
 
  //гасим все разряды
  PORT_IND = 0;
  LightOutAll();

  //зажигаем соответствующий разряд
  if (count == 0) BurnDigit(PORT_TR, NUM1);
  else if (count == 1) BurnDigit(PORT_TR, NUM2);
  else if (count == 2) BurnDigit(PORT_TR, NUM3);
  else BurnDigit(PORT_TR, NUM4);
 
  //выводим код цифры в порт
  PORT_IND = ValueBuf();
 
  count++;
  if (count == AMOUNT_NUM) count = 0;
}

  Эта функция гасит текущий активный разряд семисегментного индикатора и зажигает следующий – “открывает” соответствующий транзистор и выводит в порт, к которому подключены сегменты индикатора, код цифры из массива (буфера).
  Несколько выражений используемых в функции определены с помощью директивы #define - LightOutAll(), BurnDigit(port, digit), ValueBuf(). Это позволяет быстро и безболезненно настроить драйвер под другой тип индикатора или другую схему включения. Тут в принципе возможно 4 варианта:

индикатор с общим катодом подключенный напрямую к микроконтроллеру
#define LightOutAll()  PORT_TR |= (1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4)
#define BurnDigit(port, digit) port &= ~(1<<digit)  
#define ValueBuf() buf[count]

индикатор с общим катодом подключенный к микроконтроллеру с помощью транзисторов
#define
LightOutAll()  PORT_TR &= ~((1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4))
#define BurnDigit(port, digit) port |= (1<<digit)  
#define ValueBuf() buf[count]

индикатор с общим анодом подключенный напрямую к микроконтроллеру
#define LightOutAll()  PORT_TR &= ~((1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4))
#define BurnDigit(port, digit) port |= (1<<digit)  
#define ValueBuf() ~buf[count]

индикатор с общим анодом подключенный к микроконтроллеру с помощью транзисторов
#define LightOutAll()  PORT_TR |= (1<<NUM1)|(1<<NUM2)|(1<<NUM3)|(1<<NUM4)
#define BurnDigit(port, digit) port &= ~(1<<digit)  
#define ValueBuf() ~buf[count]

Полный текст драйвера светодиодного семисегментного индикатора

Indicator.h
Indicator.c

Как вычисляется напряжение

   Диапазон входных напряжений АЦП определяется источником опорного напряжения (ИОН). В нашем случае используется внутренний ИОН на 2,56 В. Для расширения диапазона измеряемых напряжений я поставил перед АЦП резистивный делитель. Он  рассчитан таким образом, чтобы при напряжении в 30 В на входе делителя напряжение на входе АЦП не превышало 2,56 В.

Uadc = Uin*R14/(R14 + R15) = 30В*82 /(82 + 910) = 2,48 В

Чтобы вычислить напряжение на входе вольтметра нужно результат преобразования АЦП пересчитать в напряжение и домножить на коэффициент

(R14 + R15)/R14 = 992/82

Напряжение на входе АЦП - Uadc вычисляется по формуле:

Uadc = value * 2,56/(2^n – 1),

 где n – разрядность АЦП, value – цифровое значение напряжения

Отсюда напряжение на входе вольтметра будет равно:

Uin = (value * 2,56 * 992)/(82 * 1023) = (value * 30,96)/1023

Чтобы не связываться с типом float и при этом иметь возможность вычислять напряжение с точностью до 2-ух знаков после запятой, числитель этой формулы я домножил на 100

Uin = (value * 3096)/1023

Тест вольтметра

   Когда программа была завершена, мне стало интересно, насколько точные показания будет давать вольтметр по сравнению с мультиметром. Я подключил вольтметр к источнику питания и в диапазоне напряжений от 0 до 30 В снял его показания.
   Результаты вы можете видеть в таблице. Первая колонка – это напряжение выставляемое на источнике питания, вторая - показания мультиметра Fluke, а третья – цифровой вольтметр на ATmega8.


Файлы

IAR.Вольтметр на микроконтроллере
WinAvr.Вольтметр на микроконтроллере
CodeVision.Вольтметр на микроконтроллере
Проект для Proteus`a.Вольтметр на микроконтроллере

Comments   

# foxit 2010-05-11 14:44
Спасибо
Супер!
# Pashgan 2010-05-11 19:41
Да пожалуйста.
# foxit 2010-05-16 13:43
А как сделать вольтметр многоканальным и выводить значения по нажатию кнопки по очереди на 7led индикатор?
# Pashgan 2010-05-16 19:36
Добавить в код обработчика прерывания смену каналов, а в основной цикл - обработку нажатия кнопки.
# Паша 2012-02-09 21:26
напишите пожалуйста пример как менять каналы...
# Валерий Юрье.. 2012-12-05 20:11
при непрерывном измерении, по окончании измерения и выводе информации, инвертируем например 0 бит в регистре ADMUX будут чередоваться каналы 0 и 1

ADMUX ^=1
# kotyara 2010-06-07 13:59
Собрал вольтметр, прошил но устройство не работает, может я что то пропустил. Я fuse не трогал оставил на заводских настройках. Подскажите что сделал не правильно?
# Pashgan 2010-06-07 15:24
Сделай тему на форуме, там разберемся.
# Guest 2010-06-21 11:40
А вот бы туда еще и амперметр встроить, ампер до 5ти:)
Во это было бы вещь:)
# Guest 2010-06-21 20:12
Quoting Яр:
А вот бы туда еще и амперметр встроить, ампер до 5ти:)
Во это было бы вещь:)


Я сейчас делаю автоматическое зарядное устройство для авт. акумуляторов, там у меня будет и вольтметр и амперметр до 10А. Когда сделаю могу поделиться!
# foxit 2010-06-21 20:18
Quoting nemo:
Quoting Яр:
А вот бы туда еще и амперметр встроить, ампер до 5ти:)
Во это было бы вещь:)


Я сейчас делаю автоматическое зарядное устройство для авт. акумуляторов, там у меня будет и вольтметр и амперметр до 10А. Когда сделаю могу поделиться!

ждем с нетерпением
# Guest 2010-06-22 15:59
Блин это прямо то что я ищу:) только я хотел делать для свинцовых-герми тичных. И с монитором заряда-разряда по UART. Эдакий модуль автономного питания с возможностью зарядки, для каких либо портитивных устройств.
foxit, может поможешь с проектом. а то боюсь знаний не хватит:(
# foxit 2010-06-24 12:25
постараюсь помочь чем смогу
# Guest 2010-08-03 15:34
Не умаляя никак заслуг автора, я бы все-таки порекомендовал начинающим прочитать и проникнуться сначала вот этим от уважаемого urry:

http://vrtp.ru/index.php?s=3371dc0157532aa94f7ba847e7ac1934&showtopic=10583&st=0&#entry175838

ИМХО, шедевр!
# Guest 2010-08-23 09:42
nemo, ну где же, где автоматическая зарядка
# Alexander 2010-09-02 11:29
День добрый, а не подскажите как этой красоте еще и Com port прикрутить )). в принципе схему подключения через max232 знаю но вот как в коде реализовать?
# Pashgan 2010-09-02 20:36
Ответил на форуме
# Nemo 2010-09-09 09:48
Quoting Яр:
nemo, ну где же, где автоматическая зарядка


Нет времени полностью закончить,печат ная плата уже сделана - нужно только запаять детали.Прошивка сделана только на 80%. Если нет терпения- напишите свой мейл,и я скину то что я сделал (платы сделаны в Sprint-Layout)
# Indigo 2010-12-12 16:04
Здравствуйте. Вот Вы привели таблицу пограшностей Вашего вольтметра. Значит, точность имеете в виду. Но тогда зачем Вы в прерывании делаете операцию >>3 ? Это же мало того что увеличивает время в прерывании, но еще и гробит точность! Проверим. ADC дал 8 показаний: 799 799 799 799 800 800 800 800. Посчитаем на калькуляторе точноe значение Uin.
1. Сумма 8-ми измерений = 6396.
2. 6396/8 = 799.5
3. 799.5 * 3096 / 1023 = 2419,60
Это наш "эталон" - 24.19 на индикаторе.
Давайте сделаем Ваш пример:
1. Сумма 8-ми измерений = 6396.
2. 6396/8 = 799 (int!)
3. 799 * 3096 / 1023 = 2418 (int!)
На индикаторе 24.18 вместо 24.19. Ошибка небольшая, но зачем она нужна? Делаем:
1. Сумма 8-ми измерений = 6396.
2. 6396 * 3096 / (1023*8) =
6396 * 3096 / 8184 = 2419 (int)
На индикаторе 24.19 как надо. Да еше и размер кода уменьшился, и время обработки прерывания.
# Pashgan 2010-12-12 19:18
Quote:
1. Сумма 8-ми измерений = 6396. 2. 6396/8 = 799.5 3. 799.5 * 3096 / 1023 = 2419,60
Эти вычисления сделаны с учетом того, что во всех из восьми измерений мы получили один и тот же результат. На деле этого не произойдет.
Наш сигнал представляет собой сумму Uполезн. и Uшума. Полезное напряжение у нас константа, а значение шума подчинено закону нормального распределения. Вычисляя среднее значение нескольких выборок АЦП, мы уменьшаем шумовую составляющую. Этот подход называется синхронной фильтрацией или синхронным накоплением.
Quote:
Да еше и размер кода уменьшился, и время обработки прерывания.
Это здесь вообще не критично
# Indigo 2010-12-13 16:01
Эти результаты были неодинаковыми: 799 799 799 799 800 800 800 800. Отсюда и среднее значение 799.5. А с помощью паразитного >>3 получается у Вас не выборка среднего значения (это усреднение ведь же не пропадет, она все равно будет совершено на следующих этапах, но - без потерь, за счет бОльших чисел), а вредоносное действо по грубому отсеканию дробной части на начальном участке вычислений. Чего этим добились - я показал в цифрах.
Правило одно - как можно большие числа хранить как можно дольше. С ними точнее.
# Kvark85 2010-12-24 11:47
Автору огромнейшее спасибо! Уже не в первый раз помогают его статьи, сильно помогают!!!
# foxit 2011-02-25 16:36
не получается прикрутить к вольтметру индикатор с общим анодом.
Что еще нужно поменять кроме макросов драйвера под другой тип индикатора или другую схему включения?
Нужно ли изменять массив для преобразования десятичных чисел в коды индикатора?
Если не сложно поделитесь проектом для индикатора с общим анодом.
# Pashgan 2011-02-26 09:30
Ничего не нужно менять. Только макросы.
# foxit 2011-02-26 09:38
Все
разобрался.
Перепутал подключение сегментов и анодов.
# Pashgan 2011-03-03 11:21
Бывает.
# foxit 2011-02-27 20:48
Собрал вольтметр. Заработал.
Но показывает значительную погрешность.
Скорее всего из-за разноса значений резисторов делителя напряжения.
Как программно(ввес ти коэффициент поправки) или аппаратно(добав ить переменный резистор в делитель) учитывать это?
Как произвести калибровку?
# Pashgan 2011-03-03 11:21
Измерь мультиметром сопротивление резисторов и подставь в формулу.
# Новичок 2011-04-02 07:52
Я так понимаю "Земля аналогового сигнала" и "Земля микроконтроллер а" соединены? Если я их разделяю, показания скачут от 0 до 255. Как сделать возможным их разделение?
# foxit 2011-05-19 18:35
греются резисторы делителя напряжения. отчего бы? интересно, а какой максимальный ток может протекать через ножку ацп?
# pirat_os 2011-06-15 17:23
всем привет!
судя по названию индикатора он с общим анодом, а по схеме должен быть с общим катодом. Это ошибка в схеме, или я уже совсем все забыл?
# alex1991 2011-06-19 15:32
Да с общим катодом но даже если есть под рукой с общим анодом не проблема прошивку и под нее переделать
# Димка 2011-07-23 07:07
Всё классно! а как всё это можно вывести на lcd дисплей? может быть это есть в каких то уроках? ткните носом пожалуйста...
# VLDDnepr 2012-03-03 12:13
Есть вопрос. Очень заметно и неприятно для глаз мерцание индикатора (вольтметр показывает правильные значения)- это так и надо или у меня пролезла ошибка в схему?
# RAYN3 2012-04-02 07:49
это явление стробоскопа)
# dimon16 2012-11-04 17:02
всем доброе время суток. не могу прокомпелироват ь проект в CodeVision. я начинаюший и не могу втыкнуть.
Error: C:\cvavr2\7seg\ adc.c(7): undefined symbol 'REFS1'
Error: C:\cvavr2\7seg\ adc.c(9): undefined symbol 'ADCSR'
Error: C:\cvavr2\7seg\ adc.c(11): undefined symbol 'ADCSR'
Error: C:\cvavr2\7seg\ adc.c(38): undefined symbol 'ADCSR'
Error: C:\cvavr2\7seg\ main.c(30): undefined symbol 'TOIE0'
Error: C:\cvavr2\7seg\ main.c(31): undefined symbol 'CS02'
# Pashgan 2012-11-04 17:41
Поставь CodeVision 2.04. Ты, судя по всему, пользуешься старой версией, а в ней не определены биты регистров микроконтроллер ов AVR.
# Pavel-f 2012-12-10 21:16
Не знаю как у Вас, но у меня в протеусе индикатор с общий анодом подключенный напрямую к мк не заработал пока я не исправил:
void IND_Update(void)
{
static uint8_t count = 0;

//гасим все индикаторы
LightOutAll();

//загружаем в порт символ
PORT_IND = ValueBuf();

//"поджигаем" нужное знакоместо
if (count == 0) BurnDigit(PORT_ TR, NUM1);
else if (count == 1) BurnDigit(PORT_ TR, NUM2);
else if (count == 2) BurnDigit(PORT_ TR, NUM3);
else BurnDigit(PORT_ TR, NUM4);

count++;
if (count == AMOUNT_NUM) count = 0;
}
# nonstop222 2013-04-03 12:16
Добрый день, а вы не могли бы написать конфигурацию фьюзбитов для codevision,зара нее благодарен.
# Pashgan 2013-04-03 17:24
Нужно установить источник тактового сигнала - внутренний RC генератор с частотой 8 МГц. Больше ничего менять не надо. Числовые значения не помню.
# Артём 2013-04-05 10:03
Здравствуйте! Статья отличная, все хорошо раскрыто, но я собрал прошивку под ATMega16 с конвертацией в децибелы. В протеусе все отлично работает, но когда собрал схему - показывает 0 Вольт(-535 Дб).
К выводу AREF(32 нога) подавал 5В, к AVCC(30 нога) подавал 5В, замыкал их, в прошивке выставил внешний ИОН,

ADMUX = (0
# Pashgan 2013-04-05 22:37
Код режется движком сайта, если он не заключен в специальные теги code. Выложи проект в эту временную ветку, я посмотрю. chipenable.ru/index.php/forum/materialy-sajta-chipenable/3245-vetka-dlya-vremennogo-khraneniya-proektov.html
# Артём 2013-04-09 11:14
Разобрался, не сбрасывался бит ADIF - флаг прерывания АЦП. Его нужно было отдельно установить в ф-и инициализации и сбрасывать при завершении прерывания.
Можете добавить в проект
Code:ADCSRA |=(1<<ADIF) | (1<<ADSC);
# Nick 2013-10-28 19:18
При замыккании входа ацп на землю - ацп колебается от 2-5 единиц ацп. Это нормально?(Може те подсказать сколько у Вас ед. показывает?)
# Pashgan 2013-10-29 05:00
Такое может быть из-за ошибки смещения. Это когда при нулевом входном напряжении, АЦП дает выходной код отличный от нуля. И разводка земляной цепи влиять может.
# foxit 2014-03-04 06:52
А как добавить измерение отрицательного напряжения?
# Dimm 2015-10-28 16:43
Как расширить предел измерения- пробовал 155ид3( sn74154) в Proteus глюк- менял выводы в программе индикатора подключал port digit напрямую связывал числовые показания с Burn Digit ставя номера в 16 системе исчисления чтобы поджечь 16 выходов- задействовал только 4-в Proteus показывает ерунду- 128, 256- и так далее разные результаты- что это, глюк?
# Александр 2016-03-07 22:31
Нехорошо CamelCase применять в макросах, очень нехорошо.
# Jman 2016-09-06 08:36
Скажите, как вы рассчитывали антиалисинговый фильтр?
# Олег Ya 2016-10-31 14:03
Очень понравилось, размер кода 1 К , а как переделать на tinny13+74HC595.
Тогда и ресурсы МК будут использоваться рационально! И почему ошибка при компиляции под Mega32 ? Даташит посмотрю сам. Потом.
# mortis 2016-11-23 08:43
Pashgan, не подскажите ли вы какой интерфейс вы применяли (RS-485, RS-422, RS-232,Serial Peripheral Interface или Controller Area Network)?
# Pashgan 2016-11-30 21:14
Все перечисленные интерфейсы применял, кроме CAN.
# mortis 2016-12-07 14:35
А в данном вольтметре какой-именно интерфейс вы применяли?
# mortis 2016-12-07 14:37
И какой датчик
# Валерий 2017-03-04 18:42
Добрый день. Хочу собрать вольтметр, используя индикатор с общим анодом. Поменял определения #define на соответствующие для индикатора. После этого CvAvr 2.05 стал выдавать ошибку компиляции в строке Code: LightOutAll();
';' expected, but ')' found
.
При возврате к прежнему коду пропадает и сообщение. НЕ подскажете, в чём дело?
# Валерий 2017-03-14 19:31
С этим разобрался. CVavr2.5 приходится запускать от имени админа.
Но после введения изменений под общий анод в Протеусе пропадает динамическая индикация. В пошаговом режиме индикация на разрядах меняется, а в режиме непрерывной работы индикатор тёмный. CPU загружен до 60%.
http://my-files.ru/50eg5l -измененные файлы.
# wind 2017-05-15 17:51
Доброго времени суток, подскажите как расширить диапазон значений у вольтметра до 0-400 В? настроил делитель R15=240kOm,R14= 1,5kOm. максимальное значение выдал 32 вольта. И как перенести точку? вывод dP куда пересадить?
# Alan 2018-05-25 13:54
Привет, у меня очень глупый вопрос, но очень нужно получить помощь.... Что нужно изменить, чтоб оно всё работало на MEGA16?...Больш ое спасибо!

У вас недостаточно прав для комментирования.