реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Деление на дробь на ассемблере, Поделить число на коэффициент с плавающей запятой
Slavast
сообщение Dec 14 2010, 05:43
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Столкнулся с математической проблемой. Необходимо полученное значение на АЦП поделить на 17.2, чтобы получить реальное входное напряжение.
Но не знаю как разделить число на ассемблере, да еще и на дробное.
Помогите с алгоритмом!
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 14 2010, 06:08
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(Slavast @ Dec 14 2010, 09:43) *
Помогите с алгоритмом!


А вы не делите на дробное. Помножьте числитель и знаменатель на 10 и делите на целое (у Атмела для АВР есть app.note: http://www.atmel.com/dyn/resources/prod_do...ts/doc0936.pdf). Или пишите на Си (и, опять же, не делите на дробное, если нет крайней необходимости). Если нужен именно алгоритм деления на дробное, то см., например, Я.К.Будинский "Логические цепи в цифровой технике". Там этот алгоритм подробно и с примерами расписан.
Go to the top of the page
 
+Quote Post
V_G
сообщение Dec 14 2010, 06:23
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Если имеется в виду деление на константу, до делить ВООБЩЕ не надо! Вычислите число, обратное константе, умножьте его не степень двойки (лучше на 256 или 65536) и используйте умножение на константу с последующим отбрасыванием ненужных байтов
Go to the top of the page
 
+Quote Post
МП41
сообщение Dec 14 2010, 06:45
Сообщение #4


4 синих кубика
****

Группа: Участник
Сообщений: 526
Регистрация: 19-09-08
Из: полупроводника, металла и стекла
Пользователь №: 40 326



Цитата(Slavast @ Dec 14 2010, 07:43) *
Столкнулся с математической проблемой. Необходимо полученное значение на АЦП поделить на 17.2, чтобы получить реальное входное напряжение.

А как насчет более удобного опорного напряжения?


--------------------
p-n-p-p-n-p-n-n-p-n-p структура однако очень эффективна
Go to the top of the page
 
+Quote Post
V_G
сообщение Dec 14 2010, 08:46
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(МП41 @ Dec 14 2010, 16:45) *
А как насчет более удобного опорного напряжения?

Тож вариант: подкрутить опорное, чтобы делить не на 17.2, а на 16. Простой сдвиг вправо на 4 разряда. Но только если опорное можно регулировать
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 14 2010, 09:45
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Slavast @ Dec 14 2010, 09:43) *
Столкнулся с математической проблемой. Необходимо полученное значение на АЦП поделить на 17.2, чтобы получить реальное входное напряжение.
Но не знаю как разделить число на ассемблере, да еще и на дробное.
Помогите с алгоритмом!


Как подсказали перейдите от деления к умножению
Надо разделить на 17,2. Попытаемся представить это число в виде 65536/x
17,2 = 65536/x
x = 65536/17.2 = 3810
Теперь если взять любое входное значение, умножить на 3810 а потом отбросить два старших байта (что эквивалентно сдвигу на 16 вправо или делению на 65536) то получите то что Вам нужно. Не обзязательно брать 65536, можно любое число степень двойки (чем больше число тем выше точность). Суть метода в том чтобы уйти от операции деления к операции умножения с последующим сдвигом результата вправо. Умножение для любого процессора также как и сдвиг довольно простые и быстрые операции. Особенно если писать на ассемблере.

Сообщение отредактировал mempfis_ - Dec 14 2010, 09:53
Go to the top of the page
 
+Quote Post
ae_
сообщение Dec 14 2010, 11:06
Сообщение #7


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(mempfis_ @ Dec 14 2010, 17:45) *
Как подсказали перейдите от деления к умножению
Надо разделить на 17,2. Попытаемся представить это число в виде 65536/x
17,2 = 65536/x
x = 65536/17.2 = 3810
...умножить на 3810 а потом отбросить два старших байта...

отбросить два младших байта... получим целое число в диапазоне 0...59, это из входного диапазона АЦП 0...1023.
[telepat mode] предположу, что ТС нужно получить результат с дробной частью, типа 0...1023 -> 0...59.47 [/telepat mode]
Go to the top of the page
 
+Quote Post
=GM=
сообщение Dec 14 2010, 11:33
Сообщение #8


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Если нужна дробная часть, то надо не отбрасывать два младших байта, а преобразовать их в десятичный вид и приписать к целой части.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 14 2010, 11:49
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(ae_ @ Dec 14 2010, 15:06) *
отбросить два младших байта... получим целое число в диапазоне 0...59, это из входного диапазона АЦП 0...1023.
[telepat mode] предположу, что ТС нужно получить результат с дробной частью, типа 0...1023 -> 0...59.47 [/telepat mode]


АААААА!!!!! Обшибся!!!!
Спасибо за поправку.
Нужно отбросить два младших байта а не старших!!! Точнее сдвинуть результат на 16 бит вправо!!!
Сам часто пользуюсь таким приёмом при работе с аналоговыми датчиками. Избавляет от исполдьзования громоздких П/П деления. IAR умный - сам понимает что при делении на 2**n оптимальным будет сдвиг а не div sm.gif
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение Dec 15 2010, 05:24
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Цитата(=GM= @ Dec 14 2010, 17:33) *
Если нужна дробная часть, то надо не отбрасывать два младших байта, а преобразовать их в десятичный вид и приписать к целой части.

Не уверен, что сработает такой подход. А вот домножив коэффициент на 10^k, где k требуемое число знаков после запятой

На примере, приведённом mempfis_
17,2 = 65536/x
x = 65536/17.2 = 3810
Для получения 3-х знаков после запятой
X = x * 1000 = 3810000

Теперь в цифрах, что получается. Например, число 12345
С помощью обычного деления
12345 / 17.2 = 717.7325581
С помощью умножения на коэффициент
12345 * X = 12345 * 3810000 = 47034450000 = 0xAF378C050
Отбрасываем 2 младших байта 0xAF378C050 >> 16 = 0xAF378 = 717688
Получили число 717688 три младших разряда которого в десятичном представлении есть разряды после запятой, т.е. 717.688
Погрешность получается 0.006%
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 15 2010, 06:07
Сообщение #11


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Sergey_Aleksandrovi4 @ Dec 15 2010, 12:24) *
Погрешность получается 0.006%

lol.gif Это погрешность округления 65536/17,2 = 3810,2325581395348837209302325581 посчитайте сами.
Все остальное (пока что) не влияет.
Go to the top of the page
 
+Quote Post
Slavast
сообщение Dec 15 2010, 08:44
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(_Pasha @ Dec 15 2010, 12:07) *
lol.gif Это погрешность округления 65536/17,2 = 3810,2325581395348837209302325581 посчитайте сами.
Все остальное (пока что) не влияет.

предположу, что ТС нужно получить результат с дробной частью, типа 0...1023 -> 0...59.47


Даа, но не совсем.
Диапазон АЦП На ATMega 2561 - от 0...1023.
Диапазон Vвх - от 0..5V
На входе АЦП (туда я подаю 5V с питания)у меня стоит делитель напряжения на 3(Изначально так получилось, пришлось использовать). Т.о. там где-то 1.6 получается.
Но пока делитель не берем во внимание, т.к. будем оперировать с тем, что мы получаем и как нам отсюда получить значение в вольтах.
На терминале я получаю число 0x56h, или 86 в десятичной.
Соотношение между диапазоном АЦП(0..1023) и числом на экране (0..86) есть 1:12
Соотношение между напряжением (0..5V) и числом на экране (0..86) есть 1:17.2
Если я не ошибаюсь, то мне и нужен этот коэффициент 17.2, на который я делю число на терминале чтоб получить значение по шкале от 0..5.
Go to the top of the page
 
+Quote Post
ae_
сообщение Dec 15 2010, 12:21
Сообщение #13


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(Slavast @ Dec 15 2010, 19:44) *
...Соотношение между напряжением (0..5V) и числом на экране (0..86) есть 1:17.2...

Код
;R16 = десятичное число 0...86
ldi R17, 71
mul R16, R17
lsr R1
lsr R1
;R1 = десятичное число 0...5

вот это надо было получить?
Go to the top of the page
 
+Quote Post
zombi
сообщение Dec 15 2010, 12:51
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(Sergey_Aleksandrovi4 @ Dec 15 2010, 11:24) *
На примере, приведённом mempfis_
17,2 = 65536/x
x = 65536/17.2 = 3810
Для получения 3-х знаков после запятой
X = x * 1000 = 3810000


Мне кажется что умножать на 1000 нужно не округленное X а округлять до целого после умножения:
X = 65536/17.2*1000 = 3810233
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение Dec 15 2010, 17:49
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Цитата(zombi @ Dec 15 2010, 18:51) *
Мне кажется что умножать на 1000 нужно не округленное X а округлять до целого после умножения:
X = 65536/17.2*1000 = 3810233

Да, именно так. Спасибо за правку. _Pasha выше на это уже намекнул. Вот что значит пытаться включить голову во время обеда :-[
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 1st July 2025 - 01:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01453 секунд с 7
ELECTRONIX ©2004-2016