вторник, 7 декабря 2021 г.

Умножение чисел на ассемблере на микроконтроллерах ATtiny

 Несмотря на то что в интернете можно найти команду MUL для умножения на микроконтроллерах AVR. В документациях на ATtiny2313 и ATtiny13 такой команды нет. Микроконтроллеры семейства "Tiny" имеют сокращенный набор команд. Но умножение может понадобиться даже на таких микроконтроллерах. Несмотря на скромные, относительно других современных микроконтроллеров вроде STM32, возможности, микроконтроллеры семейства Tiny всё равно могут выполнять сложные операции если бережно распоряжаться их ресурсами создавая программы для них на ассемблере. В среде WinAVR или AVR Studio на языке си можно использовать знак умножения но компилятор наверняка превратит конструкцию с умножением в большой кусок машинного кода. Который для какой нибудь ATtiny будет гораздо больше чем для какой нибудь ATmega. Одним из выходов может быть - стараться не использовать умножение там где без него можно обойтись. Если нужно умножить на 2,4,8,16,... и т.д. то умножение можно заменить побитовым сдвигом влево. Эта операция выполняется быстро однако подходит только для частных случаев. Самый простой и, при этом, являющийся определением умножения способ перемножить два числа между собой - это сложить первое число с самим собой столько раз сколько указывает второе число (далее первое число - это множимое, второе число - множитель). Например чтобы умножить 10 на 2 нужно 10 сложить с самим собой 2 раза т.е.

10*2=10+10=20

Операция умножения простых чисел обладает свойством коммутативности т.е. "от перемены мест множителей произведение (результат умножения) не меняется". Однако если сделать это в предыдущем примере то процессору будет нужно выполнить гораздо больше действий:

2*10=2+2+2+2+2+2+2+2+2+2=20

Отсюда видно что на производительность сильно влияет множитель а не множимое. Если множитель будет велик то будет велика и задержка на выполнение этой операции что может негативно сказаться на работе устройства. Например если микроконтроллер планируется использовать для векторного управления электродвигателем то этот микроконтроллер может не успевать умножать числа. Для ускорения можно использовать например таблицу умножения но для её хранения нужно некоторое количество памяти а например на ATtiny2313 flash памяти всего 2кб. Существует способ умножения не требующий большого количества памяти. Он известен как "умножение в столбик". Умножать этим способом учат в школах и, на листке бумаге, он выполняется (в большинстве случаев (если не надо умножать например на 2)) явно быстрее способа с использованием одного только сложения. Однако для данного способа необходимо знать таблицу умножения что может привести к мысли о том что микроконтроллер тоже должен её "знать" т.е. хранить во flash памяти. Однако, к счастью, таблица умножения в двоичном виде полностью совпадает с таблицей истинности логического "И". Ещё одним немаловажным упрощением является то что при применении логического "И" между 0 и множимым, по всем разрядам, получится 0. При применении логического "И" между 1 и множимым, по всем разрядам, получится множимое. Это упрощает написание кода т.к. с учетом этого нет необходимости проходиться по всем разрядам множимого во вложенном цикле. Однако по всем разрядам множителя всё рано придется пройтись. Отсутствие вложенного цикла также уменьшит количество операций для выполнения процессором что ускорит операцию умножения в целом. Чтобы проверить "такой облегченный алгоритм умножения столбиком" на микроконтроллере, можно например использовать UART. Т.к. произведение двух чисел имеет разрядов больше чем множитель то желательно не делать его большим чтобы произведение не вышло за пределы одного байта. Для этого можно послать по UARTу два числа в одном символе, после чего микроконтроллер их выделит, перемножит и пришлет результат. Так можно проверить работает ли алгоритм прежде чем начать использовать его для умножения. При проверке, указанным способом, микроконтроллер должен будет выдать символ '8' (без кавычек) при отправке ему символа 'x' (тоже без кавычек). Код программы для ATtiny2313:


К пину 4 порта D надо приделать кнопку которая делает 0В на этом пине при её нажатии. При нажатии на эту кнопку микроконтроллер присылает произведение по UARTу. Программа не идеальная но она нужна только для проверки алгоритма умножения. Вложенный цикл всё таки есть но он нужен для побитового сдвига на некоторое количество разрядов. Также можно заметить что 0 также будет сдвигаться в чем нет необходимости. Данную проблему можно решить перенеся цикл сдвига в пропускаемый участок кода перед меткой "L2". Возможно существуют и более быстрые и экономные способы умножения (о них можно написать в комментариях внизу или в комментариях к видео) однако данный тоже не плох по сравнению со способом на одном сложении.

Видео по данной теме:



КАРТА БЛОГА (содержание)

Комментариев нет:

Отправить комментарий