Нужна помощь по работе АЦП

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Нужна помощь по работе АЦП

Сообщение Sannex »

Значит вот в чем суть: после ацп преобразования мы получаем 10 битный результат (от 0 до 1023). Вопрос такой - если я подаю на вход 5В (при этом опорное напряжение = 5В), то после умножения результата на 5 и перекодировки в 4-х значное 2-10-е число, я получаю 5,115. Подскажите как выйти на показание 5,000В: что нужно сделать программно - вычесть какую-либо константу или что-то еще.. Проект для КодеВижн и Протеус прилагаю.
Просьба сразу ногами не пинать (ну только если в нужном направлении :)) ), т.к. только въезжаю в эту кухню.
Вложения
2.zip
(44.98 КБ) 293 скачивания
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Реклама
Аватара пользователя
Иван23
Нашел транзистор. Понюхал.
Сообщения: 163
Зарегистрирован: Ср дек 05, 2007 18:55:07
Откуда: Санкт-Петербуг

Сообщение Иван23 »

обычно опорное ставят 5.12в тогда один шаг равен 0,005в и после преобразований все ровно , а если опорное 5в то шаг будет 0,0048828125в и наверно после преобразований набегает ошибка я думаю так :)), а вот как исправить не знаю :))
Реклама
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Re: Нужна помощь по работе АЦП

Сообщение smac »

Sannex писал(а):Значит вот в чем суть: после ацп преобразования мы получаем 10 битный результат (от 0 до 1023). Вопрос такой - если я подаю на вход 5В (при этом опорное напряжение = 5В), то после умножения результата на 5 и перекодировки в 4-х значное 2-10-е число, я получаю 5,115. Подскажите как выйти на показание 5,000В: что нужно сделать программно - вычесть какую-либо константу или что-то еще.. Проект для КодеВижн и Протеус прилагаю.
Просьба сразу ногами не пинать (ну только если в нужном направлении :)) ), т.к. только въезжаю в эту кухню.
Во-первых каков алгоритм преобразования, никак не пойму зачем умножать результат на 5?. Чтобы получить значение напряжения, действующего на входе АЦП нужно число, получившееся после преобразования (назовем это число ADC) умножить на Опорное напряжение и поделить на 2 возведенное в степень разрядности АЦП (в нашем случае 10) т. е. Vin=ADC*Vref/1024. Из вашего ассемблерного листинга совсем не ясно как вы делаете преобразование.
Во-вторых как вы думаете что будет делать контроллер после команды

Код: Выделить всё

sbi ADCSRA, 6
если будет выполнять вашу программу?
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

То что программа написана через пень-колоду - это я и не скрываю.
Вот, замысел был таков: зная, что опорное равно 5В, при максимальном входном напряжении 5В, мы бы получили после преобразования 1023, что и было видно на индикаторе. Вот, а чтобы его догнать до 5000 и умножал полученное на 5.
После команды
sbi ADCSRA, 6
по идее желательно бы контроллер отправить спать, а в данном случае он идет выполнять код до тех пор, пока не настанет прерывание от ацп

Vin=ADC*Vref/1024 - по поводу этой формулы, не могли бы показать ее в коде?
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Реклама
Эиком - электронные компоненты и радиодетали
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Sannex писал(а): После команды
sbi ADCSRA, 6
по идее желательно бы контроллер отправить спать, а в данном случае он идет выполнять код до тех пор, пока не настанет прерывание от ацп
Правильно, а какой код следует за командой ? Там же у вас обработчик прерывания от АЦП начинается, естественно контроллер его и будет выполнять, а после этого вернется из прерывания в никуда, странно как вообще программа работает. Чтобы контроллер ничего не делал нужно либо отправить его спать как вы правильно заметили, либо зациклить на одном месте, например так

Код: Выделить всё

sbi ADCSRA, 6
rjmp PC
В этом случае в прерывании от АЦП перед командой reti нужно стартовать новое преобразование, т. е.

Код: Выделить всё

sbi ADCSRA, 6
reti
Vin=ADC*Vref/1024 - по поводу этой формулы, не могли бы показать ее в коде?
Обычно я не пишу готовый код, а пытаюсь подсказать так, чтобы человек сам до этого дошел, но сегодня что-то лень другими делами заниматься, поэтому попробую, как напишу выложу.
З. Ы. Контроллер как я понимаю мега8?
Реклама
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

да, мега8
sbi ADCSRA, 6
rjmp PC
я так понимаю после установки бита и перехода к команде rjmp PC произойдет переход на тоже самое место - rjmp PC?
если правильно понял, то РС - системный счетчик, или счетчик команд, или как он там правильно зовется...
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Реклама
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Sannex писал(а): если правильно понял, то РС - системный счетчик, или счетчик команд, или как он там правильно зовется...
PC- Programm Counter , по-русски действительно счетчик команд.
В данном случае rjmp PC означает прыжок на саму себя - бесконечный цикл.
Как я понял Вам нужно только отображать результат преобразования на семисегментом четырехразрядном индикаторе для этого не стоит лезть в арифметику с плавающей точкой. Напряжение вычисляется по формуле: Vin=ADC*Vref/1024
Самому было лень писать, поэтому нашел вот чтоhttp://www.caxapa.ru/134707.html
вам нужна самая первая программа
Прокомментирую принцип:
Если представлять Vin в миливольтах, то нужно результат домножить на 1000, т. е.
Vin=ADC*Vref*1000/1024
Vin=ADC*Vref*0,9765625 тоже самое получится если
Vin=ADC*Vref*0,9765625*62536/62536
Отсюда получаем Vin=ADC*Vref*64000/65536
Операция деления на 65536 - тривиальна нужно просто отбросить два младших байта результата
(единственное, что это без округления но ошибка там получается совсем небольшая)
поскольку у нас Vref=5 В, то результат преобразования нужно домножить на 5
это можно сделать и так как вы сделали, или вот так, в этом случае нужно быть увереннным, что ADC*5 не
будет больше 65535 (но оно точно не будет, ибо чтобы это произошло нужно умножить ADC на число большее 64)

Код: Выделить всё

; r4 = 5, r17r16 = ADCH:ADCL в r4 число на которое умножаем
; в r17 и r16 старший и младший байты результата аналого-цифрового преобразования (смещение правое)
; результат в R9:r8

        mul     r4,r16
        movw     r8,r0

        mul     r4,r17
        add     r8,r0
        adc     r9,r1 ; результат в r9:r8

Код: Выделить всё

Вот примерный код, который будет нормировать результат к 5000 мВ (миливольт)
        mul     r4,r16
        movw     r8,r0

        mul     r4,r17
        add     r8,r0
        adc     r9,r1
	 
	movw	r4, r8	;кидаем результат умножения на 5 в пару r5:r4
	ldi	r17, high(64000)
	ldi	r16, low(64000)
	call scale16uu
	;после выполнения подпрограммы результат будет в r9:r8, его нужно преобразовать из бинарной формы
	; в двоично-десятичную и вывести на индикатор
вот нашел на сайте атмела апликейшен ноут по преобразованию в двоично-десятичный код - может пригодится,
http://www.atmel.com/dyn/products/app_n ... ily_id=607
по ссылке ищете на странице AVR204, там есть и прога и описание в ПДФ может пригодится.

После выполнения преобразования в двоично-десятичную форму остается только вывести число на индикатор и поставить запятую в нужном месте, т. е. после старшего разряда, в результате получим напругу в вольтах.


Вот как-то так. Дальше сами, если будет трудно - спрашивайте, думаю вам многие здесь смогут помочь.
Уфф, уморился писАть.
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

Спасибо за разъяснения. Буду вникать в написанное
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

;
r4 = 5, r17r16 = ADCH:ADCL в r4 число на которое умножаем
; в r17 и r16 старший и младший байты результата аналого-цифрового преобразования (смещение правое)
; результат в R9:r8

mul r4,r16
movw r8,r0

mul r4,r17
add r8,r0
adc r9,r1 ; результат в r9:r8
Не совсем понятно. Буду идти по строчкам:
1. я так понимаю, что после команды mul r4,r16 результат сохраняется в регистре r0, или в паре регистров - r0:r1?;
2. movw - скопировать пару регстров - честно говоря не совсем понимаю эту конструкцию;
3. умножили r17 на 5;
4.
запутался.
Допустим, что в r16=1111 1111, тогда при умножении на 5, получим
1 0011 1111 1011 - как нам это поместить в r8? или же в r8 ляжет только 1111 1011, но тогда остальное потеряется, или нет?

И еще, можно пояснить запись:
ldi r17, high(64000)
ldi r16, low(64000)
Все будет хорошо... Или нет... Но тогда все будет очень плохо
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Sannex писал(а):
Не совсем понятно. Буду идти по строчкам:
1. я так понимаю, что после команды mul r4,r16 результат сохраняется в регистре r0, или в паре регистров - r0:r1?;
Так и быть поясню, но затем вы уж прочитайте пожалуйста AVR Instruction Set (можно скачать по адресу www.atmel.com/atmel/acrobat/doc0856.pdf - около 1,3 МБ.) а также помощь в АВРСтудии по atmel AVR assembler.
mul r4,r16 - результат в паре регистров r1(стр. байт):r0(мл. байт).
movw r4, r0 - скопировать пару регистров r1:r0 в пару регистров r5:r4, при этом операнды movw могут быть только четными.
Допустим, что в r16=1111 1111, тогда при умножении на 5, получим
1 0011 1111 1011 - как нам это поместить в r8? или же в r8 ляжет только 1111 1011, но тогда остальное потеряется, или нет?
Если вы про команду movw r8,r0 , то при выполнении ее скопируется пара r1:r0 в пару r9:r8, т. е. ничего не потреяется.
И еще, можно пояснить запись:
ldi r17, high(64000)
ldi r16, low(64000)
Эта запись означает следующее: загрузить в r17 старший байт константы 64000, загрузить в r16 младший байт константы 64000
ЛеонидК
Встал на лапы
Сообщения: 85
Зарегистрирован: Чт янв 08, 2009 22:06:13
Откуда: Киев

Сообщение ЛеонидК »

Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

Re: Нужна помощь по работе АЦП

Сообщение yaotzin »

кстате почему напряжение меньше выходит.
формула Vin=ADC*Vref/1024


входное 5 вольт - это точно :)))
ADC при этом = 1111111111(bin) т.е. 1023(dec) поскольку 10 битный он не может быть 5ти вольтам =))) значит

1023*5/1024=4,9951171875

Прибавлять к ADC 1023+1 :))) тогда будит точно ? или что делать ?
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Нужна помощь по работе АЦП

Сообщение a_skr »

а почему не хотите adc*5/1023
1023*5/1023 = 5
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Нужна помощь по работе АЦП

Сообщение a_skr »

хотя по даташиту: The minimum value represents GND and the maximum value represents the voltage on
the AREF pin minus 1 LSB.
т.о. мы не должны получить 5В никогда.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: Нужна помощь по работе АЦП

Сообщение YS »

А отчего бы просто не округлить?

Va=(ADC_VALUE/ADC_MAX)*Vref

Va=(1023/1024)*5=4.995 -> 5
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

Re: Нужна помощь по работе АЦП

Сообщение yaotzin »

a_skr писал(а):хотя по даташиту: The minimum value represents GND and the maximum value represents the voltage on
the AREF pin minus 1 LSB.
т.о. мы не должны получить 5В никогда.
Вы совершенно правы. Вообщем все получилось 5ть вольт каким-то макаром на LCD высветило :))) хотя не должно было согласно спецификации.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: Нужна помощь по работе АЦП

Сообщение YS »

Вообщем все получилось 5ть вольт каким-то макаром на LCD высветило
Округление, округление... :)
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

Re: Нужна помощь по работе АЦП

Сообщение yaotzin »

Изображение

(ATMEGA16)
Вот на ацп подается разница потенциалов, на землю (GND) минус, т.е. потенциал меньше чем на любом из входов ADC0-ADC7, а если потенциалы у меня меняются иногда, на ADC0 -ADC7 потенциал меньше чем на GND, как это можно измерять ? Подскажите пожалуйста. Может быть можно подать на ADC0-ADC1 без GND ? =)
Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

Re: Нужна помощь по работе АЦП

Сообщение yaotzin »

собственно это наверное измерение переменки, получается, если + минус меняются местами. Как это сделать подскажите.
Аватара пользователя
yaotzin
Опытный кот
Сообщения: 782
Зарегистрирован: Вс фев 04, 2007 16:32:06

Re: Нужна помощь по работе АЦП

Сообщение yaotzin »

что нет ни у кого никаких идей ? как же тогда меняя плюс минус на тестере он показывает минус а при другом плюс, мне это как раз и нужно, чтоб я мог вывести два провода с МК и при измерении мог менять провода местами где показывало когда + когда минус.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»