Страница 1 из 1

AVR и бинарный массив

Добавлено: Чт май 06, 2010 13:55:18
warrior2031
Осваиваю микроконтроллеры.

Есть задача, в которой приходит 13-ти битовое число в доп. инверсном коде, его надо преобразовать в значение курсового угла.

1 бит весит примерно 0,05 градуса.

Соответственно, самое простое - это вычилсить угол простым делением.

Или же через веса разрядов, что уже осложняется, как я понимаю, тем, что вес бита - дробное число.

Так же есть возможность использовать заранее созданный массив.

Подскажите, в каком микроконтроллере есть деление и есть ли вообще, как вычислять дробные числа и как мне добавить массив.
Можно ли просто прописать include ***.bin, воспримет ли компилятор двоичный массив?

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 14:12:06
Meteor
В каком виде будут представлены полученные данные? На чем пишете?
По мне, на асме, проще организовать "серию" сдвигов и сложений (13 раз) с прибавлением i-го "веса" чем пыжиться с делением и представлением чисел в формате плавающая запятая.

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 14:39:07
warrior2031
Пишу на асме, представить в конечном итоге надо на семисегментный четырехразрядный индикатор.
Но, сначала, как я понимаю, надо в двоичное число в прямом коде записать.

Т.е. приходить в доп. инв. коде число, у которого одна единица - это 0,05 градуса. Т.е. по сути мне надо всего лишь умножить пришедшее число на 0,05 и будут мне градусы.

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 15:05:18
Meteor
У AVR (не у всех) есть команды FMUL, FMULS, FMULSU, для умножения дробных чисел со знаком/без знака.
Но решение в виде сложений мне лично нравится больше.
Представить результат в виде двоично - десятичного кода, тоже особенных проблем не составит, необходимо 5х4 разряда = 6 байт.

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 15:24:47
warrior2031
А насчет добавления массива - есть такая возможность там?

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 15:32:32
Meteor
Что значит "добавление массива"?
Вся память в Вашем распоряжении, хотите задействуйте ОЗУ, EEPROM, FLash. Делайте в последних двух таблицы. Правда объем не велик особенно у ЭЭПРОМ...

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 15:46:57
Meteor
_noise, я тут вот о чем подумал.
У автора код 13-бит. Т.е. число возможных состояний 8192 (2^13). Цена младшего разряда, около, но не 0,05 (5*10^-2). Следуя арифметике 8192*5=... совсем не 360.

Re: AVR и бинарный массив

Добавлено: Чт май 06, 2010 18:05:22
DrWatson
Ну это при условии, что 8192 соответствует 360 градусам.
В этом случае преобразование можно свести к нескольким сложениям и сдвигам(если десятые доли не нужны):
Угол = 360/8192*n = 45*n/1024=(40*n+5*n)/1024=5*n/128+5*n/1024=(n+4*n)/128+(n+4*n)/1024 = n/32+n/128+n/256+n/1024 = n>>5+n>>7+n>>8+n>>10
арифметика будет 16-разрядная, а результат - 9 бит. ">>" сдвиг вправо на заданное число бит. Причем там где сдвиг больше чем на 7 бит, берем старший байт и сдвигаем на число бит -8, младший при этом отбрасываем. кстати n>>7 можно заменить на n<<1 и в качестве результата взять старший байт.

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 10:22:47
warrior2031
результат должен быть выведен на индикатор в формате 000,0 и после запятой точной 0,5, т.е. шаг 0,5. 000,5;001,0;001,5 и т.д.

Чтобы с достаточной точностью вычислить умножением и сдвигом - это надо умножать два четырехзначных числа (в пределе 8192*4394), я так понимаю, в случае микроконтроллера - это не вариант?

Правильно я понял, noise, что я могу добавить двоичный массив просто командой include? Именно двоичный, а не в текстовом варианте.

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 10:45:49
Meteor
Можно не париться и сделать на сдвиге влево и суммировании констант, помня что старший (13-й) бит = 180 гр, 12-й = 90, 11-й = 45 .... тем более что автор согласен на потерю точности.
Весь алгоритм сводится к простой проверке бита переноса если он равен 1 то прибавляем константу (180;90;...), если бит С=0 не прибавляем, затем просто двигаем влево и смотрим на бит С. Таким образом на перевод в значения потребуется число шагов, равное числу разрядов исходного кода.

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 12:34:31
DrWatson
И все сведется к 16-битной арифметике, что реально на 8-битном МК. Либо, если результат нужен только для вывода на индикатор, сразу считать в "символьном" виде, т.е. константы эти записывать в виде 4 байт-цифр, т.е.: 1,8,0,0 ; 0,9,0,0 ; 0,4,5,0 ; 0,2,2,5 и т.д. складывать цифры начиная с младшей, а там где цифра после сложения превысит 9 вычитать из нее 10 и делать перенос в следующий "разряд".

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 13:51:51
warrior2031
Спасибо большое всем за советы и внимание.

Думаю оптимальным будет проверять каждый бит на 0 и суммировать соответствующую ему константу, но тут у меня возникает ещё один вопрос.

Во-первых, я дезинформировал вас, сказав, что шаг 0.5, на самом деле шаг 0.1 (не моя вина, меня самого дезинформировали).

Т.о. считаем

360,0 градусов с запятой представляем как 3600

1 разряд будет "весить" 0,439
2 разряд будет "весить" 0,807

и т.д. до 13-го разряда, умножая на два.

Поскольку мне надо работать с целыми числами, то эти константы надо округлить до целого числа.

Т.о. 0,439 округлиться до 0; 0,807 до 1 и т.д.

С возрастанием разряда погрешность будет падать.

Если посчитать, то наибольшая погрешность будет на малых углах и составит чуть больше 1, что как мне сказали в принципе допустимо, т.к. главное чтобы точно индицировался 0, 90, 180, 270 градусов. Но если максимальное десятичное число у меня 3600, то это уже надо два регистра под него, два байта. В два байта можно и с большей точностью записать (до 65 535, а у меня максимальное число выходит 36 000), так ведь?

Правильно ли я рассуждаю?

И отсюда вытекает мой вопрос. Как мне это конечное число 16-ти разрядное получить? Т.е. допустим константы до 255 я прибавить могу, а дальше как? Не совсем понятно.

Буду рад, если поможете.

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 14:00:05
Meteor
Есть операции в которых принимает участие бит переноса С (упоминавшийся ранее для проверки).
Сложение выполняется командой add, если надо сложить многобайтные числа то есть еще и команда adc которая прибавит содержимое бита переноса.

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 14:05:50
warrior2031
За ADC спасибо, буду разбираться :-)

Ты и правда метеор :)

Задачу можно считать решенной.

Но всё же так почему-то никто и не сказал, могу я бинарник добавлять или нет?

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 14:11:47
Meteor
Если я правильно помню, то в файле *.bin хранятся коды со всеми переходами и простое подключение (на мой взгляд) ни к чему (хорошему) не приведет.
PS не я так себя назвал, теперь приходится держать "марку" :wink:

Re: AVR и бинарный массив

Добавлено: Пт май 07, 2010 14:41:37
akl
warrior2031 писал(а): 360,0 градусов с запятой представляем как 3600
.
.
Поскольку мне надо работать с целыми числами, то эти константы надо округлить до целого числа.
Здравствуйте. Чтобы не потерять точность, можно сделать так. Выражение для Вашего случая
10*Угол=28800*КОД/65536, т.е. задача сведется к умножению полученного кода на 28800 и отбрасывании двух младших байт
(при усечении) или прибавлении старшего бита этих байт к результату и только затем отбрасывании (при округлении).