ацп или преобразование в 10 форму

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

Подскажите пожалуйста как после АЦП (AtMega64), полученное значение перевести в 10-ое. Т.е. меняем входное напряжение и в результате должны увидеть это значение на индикаторе (главное получить это значение-а вывести на индикатор я могу).
Исходные данные: величина опорного напряжение - 5В, АЦП 10 разрядный.
Пока никак не получается, читал что нужно сперва умножить на 5, затем разделить полученное число на 10, что-то в этом роде, но у меня никак не получается.
Буду рад если выложите кусок кода и он будет на асме, но можно и на C.
Очень надо.
Реклама
asd
Встал на лапы
Аватара пользователя
Сообщения: 95
Зарегистрирован: Сб янв 20, 2007 22:03:21
Откуда: от верблюда

Сообщение asd »

сергей, тебе надо двоично- двоичнодесятичный преобразователь
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18784
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

ADC = (U*1024)/Uref отсюда легко найти U, зная ADC и Uref
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

собственно говоря, цап аппаратный мне не нужен, а именно нужен программный. Двоично-двоично десятичное преобразование у меня есть (нормально работает), но как известно формула ADC=1024Uип/Uref, где Uref=5В. Голова просто уже не соображает.
Как раз затруднение в преобразовании полученного значения, т.е. вычисления по формуле Uип.
Ага умножить на 5 получилось, ADC*5=1024*Uип, теперь осталось разделить на 1024. Уф, пойду подышу свежим воздухом.
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 4673
Зарегистрирован: Вс июн 01, 2008 00:17:35
Откуда: Я всего лишь плод вашего воображения...

Сообщение Пухич »

А в чем проблема то? Сдвинул на 10 вправо, вот тебе и деление на 1024.
Знание - сила!
Реклама
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

А в чем проблема то? Сдвинул на 10 вправо, вот тебе и деление на 1024.
---------------------------------------------------------------
Вот это как раз и не получается, у меня есть пробелы в самообразовании, я понимаю, что вроде сложного нет, но не получается. Напишите пожалуйста код.
Реклама
Модератор
Аватара пользователя
Сообщения: 4517
Зарегистрирован: Пн апр 03, 2006 11:43:25
Откуда: Санкт - Петербург

Сообщение Aheir »

Если Вы о делении, то, видимо вот так:

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

A = A >> 10;
В результате переменная А будет поделена на 1024. Ежели пишете на Си, так можно в явном виде арифметические действия писать:

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

А = А / 1024;
Оптимизм х (Опыт + Знания) = const
Контактная информация:
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

А насколько точный расчет получается? Вот к примеру возьмем Uпит=2500/1024=2,4414...
Если сдвинут вправо 10 раз и убрать лишние 4 бита, т.е. было 0111 0001 0000 0010 стало 0001 0000 0010 это равно 258, т.е. 2,58 если я правильно понимаю. Это что, такая погрешность будет? Или может есть какой-нибудь способ от нее избавиться?
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

сергей111 писал(а):Как раз затруднение в преобразовании полученного значения, т.е. вычисления по формуле Uип.
Если ресурсов м/к хватит, просто запиши форматированный вывод sprintf() в строковый буфер и выводи эту строку куда потребуется.
А погрешность большая, только если сдвигаемые вправо биты нигде не сохранять и никак не использовать, то есть, при таком раскладе все десять бит канут в лету. Способ избавиться простой - я его уже указал - младшие десять бит не выбрасывать, а выводить как дробную часть результата.
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

Yellow Tiger писал(а):
сергей111 писал(а):Как раз затруднение в преобразовании полученного значения, т.е. вычисления по формуле Uип.
Если ресурсов м/к хватит, просто запиши форматированный вывод sprintf() в строковый буфер и выводи эту строку куда потребуется.
А погрешность большая, только если сдвигаемые вправо биты нигде не сохранять и никак не использовать, то есть, при таком раскладе все десять бит канут в лету. Способ избавиться простой - я его уже указал - младшие десять бит не выбрасывать, а выводить как дробную часть результата.
--------------------------------------------------------
???
Кажется алгоритм я сделал, но время нужно, чтобы его воплотить в ассемблерный код, может у кого есть и кто-нибудь им поделится?
Теперь могу сформулировать задачу немного по-другому: значение напряжения должно быть например 2,14 (или 2,142) - может у кого есть готовая процедура, чтобы свою не писать.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

А чем не нравится ассемблерный код на выходе компилятора Си?
Уж как рыбу-то его всяко можно использовать, если такая безраздельная любовь к асму..?
Модератор
Аватара пользователя
Сообщения: 4673
Зарегистрирован: Вс июн 01, 2008 00:17:35
Откуда: Я всего лишь плод вашего воображения...

Сообщение Пухич »

сергей111 писал(а):А насколько точный расчет получается? Вот к примеру возьмем Uпит=2500/1024=2,4414...
Если сдвинут вправо 10 раз и убрать лишние 4 бита, т.е. было 0111 0001 0000 0010 стало 0001 0000 0010 это равно 258, т.е. 2,58 если я правильно понимаю. Это что, такая погрешность будет? Или может есть какой-нибудь способ от нее избавиться?
2500 в двоичном виде=1001 1100 0100
если сдвинем это вправо на 10 разрядов то получим 10. Т.е. число 2. При целочисленном делении на 1024 вы получили бы то же самое. Посему разницы нет. Вот если числа дробные, тогда другое дело.
Знание - сила!
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Вопрос сформулирован, мягко говоря, нечетко. Нужно бы определиться, что за задача у Сергея111. Решения могут быть очень разные, а он ограничился лишь парой невнятностей...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18784
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

если у вас программа маленькая, а памяти программ достаточно - сделайте массив в памяти из "показаний индикатора" для каждого из 1024 значений АЦП - и не парьтесь с расчетами. т.е. если вы хотите, чтобы при сигнале с АЦП 234 индикатор поазывал 4017 - так и сделайте: в массиве чисел в 234-й элемент вставьте число 4017.

Расчет массива удобно делать в экселе :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

Спасибо ARV за интересный совет, только вот не знаю что будет проще и быстрее: написать самому деление вещественного числа (я надеялся что кто-нибудь поделится процедурой, но похоже увы) или же сделать по совету ARV, наверно по времени написания приблизительно равнозначны.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

сергей111 писал(а):я надеялся что кто-нибудь поделится процедурой, но похоже увы
Я надеялся, Сергей, на, хотя бы немного, детальное описание задачи, но, похоже, увы. Раз так, по принципу "каков вопрос, таков ответ" - могу только посоветовать поискать на электрониксе, например, вот это может помочь.
Родился
Сообщения: 10
Зарегистрирован: Ср июл 16, 2008 12:39:28

Сообщение сергей111 »

Yellow Tiger писал(а):
сергей111 писал(а):я надеялся что кто-нибудь поделится процедурой, но похоже увы
Я надеялся, Сергей, на, хотя бы немного, детальное описание задачи, но, похоже, увы. Раз так, по принципу "каков вопрос, таков ответ" - могу только посоветовать поискать на электрониксе, например, вот это может помочь.
Я надеюсь, Yellow Tiger, не очень на меня обиделся. Могу описать более детальное описание:
изменяем подстроечным резистором напряжение от 0 до 5 В
снимаем показание АЦП (АЦП преобразует значение по формуле ADC = (U*1024)/Uref), где Uref-величина опорного напряжения равная 5В.
Затем значение ADC (хранящееся в регистрах ADCH и ADCL) передается по USART на другую плату (плату управления).
На плате управления результат U=(ADC*5)/1024 надо вывести на 7-ый индикатор, точность либо 2 знака (скорее всего) либо 3, после запятой.
Сложность была (а сперва я как поделить вообще не знал) в делении, чтобы учитывались цифры после запятой.
Сейчас я думаю и сам смогу написать процедуру деления вещественных чисел, т.е. учитывая запятую, но полагаю моя процедура будет достаточно не оптимальной, т.к. я пока еще начинающий, а по этой теме думаю есть много наработок.
И еще, программу я делаю на асме, на C думаю перейти попозже, месяца через 1,5-2. Я знаю C, но для микроконтроллера на нем никогда не писал и не пробовал.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Поскольку времени мало, я сделаю пару предположений о том, что не отражено в условии, и на этом основании предложу один из возможных способов.
Итак, предположим, что процедура не д.б. универсальной, но д.б. как можно проще и занимать как можно меньше места в коде, предположим также, что измеряемое напряжение не будет превышать указанной величины, то есть, что завтра не придется мерять до 7 вольт. Отмечу также, что точность в три знака после запятой с этим АЦПом не получится, значит - только 2 знака, ОК?

Вариант с максимальным упрощением такой:
1. использовать внутренний ИОН с напругой 2.56V, а измеряемое напряжение делить ровно пополам. В этом случае цена деления равна 2.56/1024 = 0.0025 (или 0,005 до входного делителя).
2. Измеренное значение ( ( ADCH << 8 ) | ADCL ) сдвигать на 1 бит вправо - теперь цена одного бита равна точнехонько одной сотой вольта (с учетом того, что напруга на входе в два раза меньше измеряемой - делили же пополам!).
3. Полученное после сдвига 16-битное целое (правда, полезных там только 9 бит) преобразовать в ASCII процедурой itoa, взятой с электроникса или еще откуда-то, и передавать её по USART, на ходу вставляя символ десятичной запятой перед последними двумя символами, ведь мы же подогнали цену младшего бита к одной сотой!

Можно еще взять ИОН на 5,12V, тогда не придется делить измеряемое напряжение пополам перед подачей на АЦП.

Это решение не универсальное, но простое и скорострельное, как в реализации, так и в работе.

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

P.S. Я, кстати, всегда полагал, что неспроста у внутреннего атмеловского ИОНа напруга такая "круглая" - 2,56... 0x100, однако! :lol:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18784
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Yellow Tiger писал(а):P.S. Я, кстати, всегда полагал, что неспроста у внутреннего атмеловского ИОНа напруга такая "круглая" - 2,56... 0x100, однако! :lol:
а у тини13 ИОН совсем не такой удачно-округлый...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

ARV писал(а):а у тини13 ИОН совсем не такой удачно-округлый...
А кто говорил о тринадцатой тиньке? Мне запомнилось такое начало ветки:
Сергей111 писал(а):Подскажите пожалуйста как после АЦП (AtMega64), ...
Закрыто

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