Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.54/139: Рейтинг темы: голосов - 139, средняя оценка - 4.54
Tpo-o
0 / 0 / 0
Регистрация: 07.12.2010
Сообщений: 52
1

Вольтметр на AVR.

25.01.2011, 00:04. Просмотров 25107. Ответов 26
Метки нет (Все метки)

Добрый вечер! Мне нужно сделать вольтметр на мк и я не как не могу понять, как преобразовать код, который выдаёт АЦП, в Вольты на ассемблере. Помогите, пожалуйста!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.01.2011, 00:04
Ответы с готовыми решениями:

AVR AVRISP STK500 V3.0 USB ISP Programmer for AVR IC
Люди помогите плз. не могу разобраться. приобрел этот чудный девайс (AVR...

AVR Atmega324PU не прошивается AVR ISP Mk2
Добрый день. На плату впаян данный микроконтроллер в корпусе tqfp. При...

Анализ стека AVR / AVR stack analysis
Привет! Уперся я в стек, и решил понять что почем. Нашел вот такой вот...

AVR Studio 6 и AVR Toolchain вопросы!
Всем доброго времени суток. Решил я написать софтинку в новой студии от...

Вольтметр на Mega32
Здравствуйте. Решил обратиться за помощью, т.к. сам пока такую проблему решить...

26
Sysorsky
0 / 0 / 0
Регистрация: 24.12.2010
Сообщений: 279
02.02.2011, 03:51 21
Цитата Сообщение от d@vymshy
далее идет расчет:
Код:
val:=ADC_Read(0);
u:=((val/1023) * 5)*4;
тут "5" это значение опорного напряжения, а что означает "4" - это что за коэффициент?
и если используется 8-ми битный АЦП, то соответственно делить надо на 256?
как пересчитать 8-ми битные данные АЦП и получить результат с точностью до десятых (ХХ.Х)?
На 5 правильно, это опорное. На 4 - это как раз делитель. АЦП меряет от 0 до 5в, а до делителя подаётся от 0 до 20 в. На 256 ничего делить не надо, смотри в даташите формулу расчёта значения АЦП от напряжения.
Вообще то, мне тоже не понятно, почему автор делит на 1023, если надо делить на 1024. Погрешность получается..
В итоге: если использовать выравнивание по левому краю, то в старшем регистре (8 бит) будут старшие биты сначения АЦП. Дальше, берёшь 16 битовую переменную и вычисляешь:

temp16 = ((ADCRisult << 2) * 5 * 10) / 1024;

на 2 сдвигаешь, потому что два младших бита ещё есть, 5 - опорное, на 10 умножить, чтобы получить целочисленный результат в десятых долях вольт, а деление по формуле. Конечно, эту формулу можно упростить. Если применяется делитель, то домножаешь на коэфициент.
0
d@vymshy
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 64
02.02.2011, 13:08 22
в ДШ на мегу 8535 для пересчета результата две формулы и обе совсем не похожи на эту и там вообще нигде не присутствует коэффициент делителя, поэтому не понятно куда его подставлять...
Код
temp16 = ((ADCRisult << 2) * 5 * 10) / 1024;
тут тоже малость не понятно... ADCRisult я так понимаю это 16-ти битная переменная, которая содержит результат АЦП из регистров ADCH и ADCL, который выглядит при выравнивании по левому краю так:
[9][8][7][6][5][4][3][2]:[1][0][x][x][x][x][x][x]
если мы сдвиним биты влево на 2, то получим:
[7][6][5][4][3][2][1][0]:[x][x][x][x][x][x][x][x]
и тут на сколько я понимаю, чтобы работать с "правильным" числом надо двинуть еще на 8 вправо чтобы получить:
[x][x][x][x][x][x][x][x]:[7][6][5][4][3][2][1][0]
иначе мы будем производить математические вычисления не с тем числом или я не прав?

не проще тогда использовать выравнивание по правому краю и в формуле использовать только значение регистра ADCL, тогда формула будет:
Код
temp16 = (ADCL * 5 * 10) / 1024;
и вот с делителем тоже не понятно... в формуле автора коэффициент делителя 4, а почему не 3, он же делит измеряемое напряжение в соотношении 3 к 1, т.е. на АЦП поступает 3-я часть от измеряемого напряжения...
и как получить значение АЦП с учетом делителя:
Код
temp16 = ((ADCL * 5 * 10) / 1024) * <коэффициент делителя>;
так правильно?
0
Sysorsky
0 / 0 / 0
Регистрация: 24.12.2010
Сообщений: 279
02.02.2011, 16:20 23
Цитата Сообщение от d@vymshy
Код:
temp16 = ((ADCRisult << 2) * 5 * 10) / 1024;
тут тоже малость не понятно... ADCRisult я так понимаю это 16-ти битная переменная, которая содержит результат АЦП из регистров ADCH и ADCL
Нет, это только старшая часть. 8 бит ADCH, два бита из ADCL отброшены.
То есть мы записываем в 16 битную переменную значение ADCH, получаем
ADCRisult = [x][x][x][x][x][x][x][x]:[9][8][7][6][5][4][3][2]
Теперь надо сдвинуть на два бита влево, чтобы получить 10 бит АЦП без младших незначащих бит. Если будем сдвигать в 8 битной переменной, получим бред, потому что потеряем старшие значащие биты.
Итого: [x][x][x][x][x][x][9][8]:[7][6][5][4][3][2][-0-][-0-].
Цитата Сообщение от d@vymshy
Код:
temp16 = (ADCL * 5 * 10) / 1024;
и вот с делителем тоже не понятно... в формуле автора коэффициент делителя 4, а почему не 3, он же делит измеряемое напряжение в соотношении 3 к 1, т.е. на АЦП поступает 3-я часть от измеряемого напряжения...
Потому что ты не правильно понимаешь работу делителя. Смотри тут http://iosyitistromyss.ru/osnovy-na-palcax-chast-2.html, а особенно тут http://dihalt.vhost.su/main/ee/Sortir/4.gif. Коэффициент равен 4.
Цитата Сообщение от d@vymshy
Код:
temp16 = ((ADCL * 5 * 10) / 1024) * <коэффициент делителя>;
так правильно?
С учетом вышесказанного - нет. Правильно в прошлом моём посте.
Цитата Сообщение от d@vymshy
в ДШ на мегу 8535 для пересчета результата две формулы и обе совсем не похожи на эту и там вообще нигде не присутствует коэффициент делителя, поэтому не понятно куда его подставлять...
Там есть формула ADC = Vin * 1024 / Vref
ADC - это значение с ноги, Vref - опорное напряжение, Vin - напряжение на ноге. То есть, Vin = ADC * Vref / 1024. Так формула похожа, правда? ;)
Преобразователь меряет напряжение от 0 до Vref. Если надо больший диапозон мерить, то ставится делитель. Соответственно, чтобы получать значения до делителя, надо домножать результат на коэффициент.
Уф.. Вроде всё подробно рассказал, хоть статью оформляй...
0
d@vymshy
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 64
02.02.2011, 17:01 24
Цитата Сообщение от Sysorsky
Нет, это только старшая часть. 8 бит ADCH, два бита из ADCL отброшены.
То есть мы записываем в 16 битную переменную значение ADCH, получаем
ADCRisult = [x][x][x][x][x][x][x][x]:[9][8][7][6][5][4][3][2]
дык вот оно как, а я думал надо саршие биты отбрасывать, т.е. 9 и 8, теперь с этим понятно...
Цитата Сообщение от Sysorsky
Потому что ты не правильно понимаешь работу делителя. Смотри тут http://iosyitistromyss.ru/osnovy-na-palcax-chast-2.html, а особенно тут http://dihalt.vhost.su/main/ee/Sortir/4.gif. Коэффициент равен 4.
еще раз перчитал, теперь вроде догнал... рассчитываем по формуле Uвых с делителя, потом делим Uвх на Uвых и получаем коэффициент - так?
Цитата Сообщение от Sysorsky
Там есть формула ADC = Vin * 1024 / Vref
ADC - это значение с ноги, Vref - опорное напряжение, Vin - напряжение на ноге. То есть, Vin = ADC * Vref / 1024. Так формула похожа, правда? ;)
Да, действительно...
Цитата Сообщение от Sysorsky
Уф.. Вроде всё подробно рассказал, хоть статью оформляй...
Sysorsky, большое тебе спасибо за терпение и выдержу, все стало понятно!
0
d@vymshy
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 64
07.02.2011, 05:50 25
Почему не происходит автоматический повтор пересчета ADC, в инициализации все для этого указано:
Код
  //InitADC
ADCSRA = (1 << ADIM) | (1 << ADSC) | (1 << ADATE) | (1 << ADIE) | (6 << ADPS0);
ADMUX  = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR);
код прерывания:
Код
ISR(ADC_vect)
{
ADCRisult = ADC; // сохраняем значение ADC в глобальной перемнной ADCRisult типа uint16_t
ADCSRA |= (1 << ADSC); // вот тут если в ручную не установить флаг запуска пересчета, то повторный автоматический пересчет не начинается
}
мега8535, моделирую в протеусе, на железе еще не пробовал, может это глюк протеуса?
0
zhu4oro
0 / 0 / 0
Регистрация: 03.12.2010
Сообщений: 167
17.02.2011, 01:02 26
Цитата Сообщение от d@vymshy
Почему не происходит автоматический повтор пересчета ADC, в инициализации все для этого указано:
Код:
//InitADC
ADCSRA = (1 << ADIM) | (1 << ADSC) | (1 << ADATE) | (1 << ADIE) | (6 << ADPS0);
ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR);
код прерывания:
Код
ISR(ADC_vect)
{
ADCRisult = ADC; // сохраняем значение ADC в глобальной перемнной ADCRisult типа uint16_t
ADCSRA |= (1 << ADSC); // вот тут если в ручную не установить флаг запуска пересчета, то повторный автоматический пересчет не начинается
}
мега8535, моделирую в протеусе, на железе еще не пробовал, может это глюк протеуса?
Опять этот шпротеус... сколько раз твердили миру: "Делайте в железе на макетке" - это точно такой же шпротеус только пощупать можно. А у шпротеуса в симуляции глюк на глюке!
0
d@vymshy
0 / 0 / 0
Регистрация: 12.12.2010
Сообщений: 64
17.02.2011, 02:00 27
Макетка ИМХО дедовский метод и для каждого изменения схемы макетку задолбаешься перепаивать... проще знать о некоторых глюках протеуса (если они действительно есть)...
0
17.02.2011, 02:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2011, 02:00

термометр вольтметр
Нужна схема термометра-вольтметра на avr в автомобиль на lcd дисплее. Дайте...

Attiny15 вольтметр 12 вольт
сразу прошу прощенья за может глупые вопросы. я начинающий. а вопрос вот вчём....

Вольтметр пробник с высоким Rвх.
Здравствуйте уважаемый DY HOTT! А также все форумчане! Чтение некоторых...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru