попогите дописать код
попогите дописать код
на com порт подаю 2-а числа, перемножаю и на выход, но подать нужно числа с фиксированной точкой, как это сделать не могу разобраться
вот исходник
;
;
;
;
;
.include "tn2313def.inc"
;инициализация USART
; Set baud rate
ldi r17,0 ;загружаем в регистр r17 ноль
ldi r16,0x33 ;загружаем в регистр r16 число 0b00110011
out UBRRH, r17 ;определяем старший байт скорости по USART
out UBRRL, r16 ;определяем младший байт скорости по USART
; Enable receiver and transmitter
ldi r16, (1<<RXEN)|(1<<TXEN) ;загружаем в r16 число 0b00011000
out UCSRB,r16 ;засылаем его в регистр управления и контроля В.
; Set frame format: 8data, 2stop bit
ldi r16, (1<<USBS)|(3<<UCSZ0) ;загружаем в r16 число 0b00001010
out UCSRC,r16 ;засылаем его в регистр управления и контроля С.
;прием первого числа
USART_Receive_1:
; Wait for data to be received
sbis UCSRA, RXC ;проверяем флаг приема
rjmp USART_Receive_1 ;если не готов, то снова ждем
; Get and return received data from buffer
in r16, UDR ;считываем принятый байт в r16
;прием второго числа
USART_Receive_2:
; Wait for data to be received
sbis UCSRA, RXC
rjmp USART_Receive_2
; Get and return received data from buffer
in r17, UDR ;считываем принятый байт в r17
;итак, получены два числа.
;Первое в r16, второе в r17
;
;перемножаем
MOV R0,R17 ;содержимое r17 посылаем в r0
SUB R17,R17 ;вычитаем из r17 содержимое r17
LDI R27,9 ;загружаем в r27 число 9
RJMP met1 ;переход на met1
met3:
BRCC met2 ;в случае сброшенного флага переноса уходим на met2
ADD R17,R0 ;складываем r17 и r0. Результат помещаетсяв r17.
met2:
LSR R17 ;сдвигаем r17 вправо (логический).
met1:
ROR R16 ;ротация r16 вправо
DEC R27 ;вычитаем из r27 единницу
BRNE met3 ;если результат не равен нулю, то переходим на met3.
;результат перемножения в r16
;отправляем
USART_Transmit:
; Wait for empty transmit buffer
sbis UCSRA,UDRE ;проверяем готовность регистра передачи
rjmp USART_Transmit ;если не готов, то опять ждем
; Put data (r16) into buffer, sends the data
out UDR,r16 ;засылаем содержимое r16 в регистр передачи USART
;
;ALLES IN ORDNUNG!!!
;
вот исходник
;
;
;
;
;
.include "tn2313def.inc"
;инициализация USART
; Set baud rate
ldi r17,0 ;загружаем в регистр r17 ноль
ldi r16,0x33 ;загружаем в регистр r16 число 0b00110011
out UBRRH, r17 ;определяем старший байт скорости по USART
out UBRRL, r16 ;определяем младший байт скорости по USART
; Enable receiver and transmitter
ldi r16, (1<<RXEN)|(1<<TXEN) ;загружаем в r16 число 0b00011000
out UCSRB,r16 ;засылаем его в регистр управления и контроля В.
; Set frame format: 8data, 2stop bit
ldi r16, (1<<USBS)|(3<<UCSZ0) ;загружаем в r16 число 0b00001010
out UCSRC,r16 ;засылаем его в регистр управления и контроля С.
;прием первого числа
USART_Receive_1:
; Wait for data to be received
sbis UCSRA, RXC ;проверяем флаг приема
rjmp USART_Receive_1 ;если не готов, то снова ждем
; Get and return received data from buffer
in r16, UDR ;считываем принятый байт в r16
;прием второго числа
USART_Receive_2:
; Wait for data to be received
sbis UCSRA, RXC
rjmp USART_Receive_2
; Get and return received data from buffer
in r17, UDR ;считываем принятый байт в r17
;итак, получены два числа.
;Первое в r16, второе в r17
;
;перемножаем
MOV R0,R17 ;содержимое r17 посылаем в r0
SUB R17,R17 ;вычитаем из r17 содержимое r17
LDI R27,9 ;загружаем в r27 число 9
RJMP met1 ;переход на met1
met3:
BRCC met2 ;в случае сброшенного флага переноса уходим на met2
ADD R17,R0 ;складываем r17 и r0. Результат помещаетсяв r17.
met2:
LSR R17 ;сдвигаем r17 вправо (логический).
met1:
ROR R16 ;ротация r16 вправо
DEC R27 ;вычитаем из r27 единницу
BRNE met3 ;если результат не равен нулю, то переходим на met3.
;результат перемножения в r16
;отправляем
USART_Transmit:
; Wait for empty transmit buffer
sbis UCSRA,UDRE ;проверяем готовность регистра передачи
rjmp USART_Transmit ;если не готов, то опять ждем
; Put data (r16) into buffer, sends the data
out UDR,r16 ;засылаем содержимое r16 в регистр передачи USART
;
;ALLES IN ORDNUNG!!!
;
Re: попогите дописать код
зайди на сайт atmel.com
http://atmel.com/dyn/resources/prod_doc ... oc0936.pdf
http://atmel.com/dyn/resources/prod_doc ... oc1631.pdf
и прочее по надобности...
http://atmel.com/dyn/resources/prod_doc ... oc0936.pdf
http://atmel.com/dyn/resources/prod_doc ... oc1631.pdf
и прочее по надобности...
Re: попогите дописать код
блин парни время нету, завтра крайний срок сдавать, да и с английским у меня не очень
Re: попогите дописать код
Число с фиксированной точкой отличается от целого числа только тем, что оно хранится в виде, умноженном на основание. То есть число 12,3 при основании 10 будет храниться как 123. А при умножении нужно это учесть: например произведение чисел 1,2 и 1,1 должно быть 1,3(лишний знак отброшен). А хранятся они как 12 и 11 и если просто перемножить их то получится 132(то есть значение 13,2). Так что чтобы получить из 13,2 число 1,3 нужно разделить его на основание(которое в данном случае - 10), не забыв что там может быть округление.
Так что чтобы получить нужный результат дели полученное число на основание чисел. А по остатку от деления определяй нужно ли прибавить 1 из-за округления.
Так что чтобы получить нужный результат дели полученное число на основание чисел. А по остатку от деления определяй нужно ли прибавить 1 из-за округления.
Re: попогите дописать код
Murav писал(а):Число с фиксированной точкой отличается от целого числа только тем, что оно хранится в виде, умноженном на основание.
Василий Теркин предупреждал : а не знаешь - не толкуй.
Вот цитата прямо из Яндекса ( он не только нашел ссылку, но и цитату из нее любезно предоставил ) :
ПРЕДСТАВЛЕНИЕ ЧИСЕЛ С ФИКСИРОВАННОЙ ТОЧКОЙ
При представлении чисел с фиксированной точкой положение точки фиксируется в определенном месте относительно разрядов числа.В современных ЭВМ точку фиксируют справа от самого младшего разряда и поэтому могут быть представленны только целые числа...
А вот числа с плавающей точкой содержат в себе :
- знак числа
- знак порядка
- порядок
- нормализованную мантиссу (0.5 =< X < 1.0) со скрытым разрядом.
Впрочем, наука не стоит на месте, и если автор, кроме своего ошибочного мнения, располагает и ссылкой на источник, пусть будет добр ознакомить публику.
Re: попогите дописать код
а как это выглядит в исходнике? хочу разобраться на примере
Re: попогите дописать код
Jack_A писал(а):Василий Теркин предупреждал : а не знаешь - не толкуй.
И в чём же я ошибся?
Jack_A писал(а):В современных ЭВМ точку фиксируют справа от самого младшего разряда и поэтому могут быть представленны только целые числа...
Это откуда такие сведения? Я не знаю ни одного процессора, где есть аппаратная поддержка чисел с фиксированной запятой, так что как хранить число определяет программист. И ни одного стандарта про эти числа я тоже не видел.
Кстати использование слов "современные ЭВМ" говорит либо о том что эта статья была написана лет двадцать-тридцать назад, либо что человек её писавший, совершенно не знаком с современными технологиями.
Jack_A писал(а):Впрочем, наука не стоит на месте, и если автор, кроме своего ошибочного мнения, располагает и ссылкой на источник, пусть будет добр ознакомить публику.
Я исхожу из того как такую задачу будет решать любой программист. Источников привести не могу, поскольку о таких простых вещах никто не пишет.
lex-108 писал(а):а как это выглядит в исходнике?
Например на C с уже готовыми функциями работы с UART это будет выглядеть примерно так:
Код: Выделить всё
signed char a,b,d;
signed short c;
a = ReadByteFromUART();
b = ReadByteFromUART();
c = ((signed short)a)*b; //преобразование в short нужно чтобы результат умножения был двухбайтным
d = c%основание; //считаем остаток(на самом деле деление и расчёт остатка будет одной операцией)
c = c/основание; //или c = c*основание если запятая стоит справа от числа(при этом с может быть однобайтным)
if (d>=основание/2) c++; //не забываем про то что надо не просто отбросит остаток, а округлить полученное число
if (c>0xFF) //результат не влазит в один байт?
сообщаем об ошибке
else
WriteByteToUART(c&0xFF); //а если влазит - возвращаем только младший байт
a, b и d здесь - однобайтные переменные, а c - двухбайтная. Операции умножения и деления должны учитывать знаки чисел.
Код на ассемблере отличается от кода на C только тем что все умножения и деления надо реализовывать самому. В интернете найти уже готовые функции для умножения и деления целых чисел в дополнительном коде вроде не сложно. А если не найдёшь - можно вытащить их и компилятора C, они практически все поддерживают создание файла листинга в дополнение к бинарнику.
Re: попогите дописать код
Murav писал(а):Это откуда такие сведения? Я не знаю ни одного процессора, где есть аппаратная поддержка чисел с фиксированной запятой, так что как хранить число определяет программист. И ни одного стандарта про эти числа я тоже не видел.
То, что число с фиксированной точкой и целое число - это одно и то же, знает любой второкурсник компьютерной специальности. Программист, конечно, может держать в уме ( или даже в специально выделенном регистре ) масштабный множитель - это его святое право, только если этот множитель не используется - он предполагается равным единице, и целочисленная арифметика поддерживается ВО ВСЕХ архитектурах, начиная от БЭСМ-6 и заканчивая нонешними Intel и AVR. В частности, для этих чисел характерно, что в операции деления остаток отбрасывается.
Вот давал себе зарок - не заниматься ликбезом - и не удержался. Поэтому полемику прекращаю.
Успехов Вам в освоении целых чисел - знаковых и беззнаковых
Re: попогите дописать код
Jack_A писал(а):То, что число с фиксированной точкой и целое число - это одно и то же
Я тоже в этом не сомневаюсь.
Jack_A писал(а):только если этот множитель не используется - он предполагается равным единице, и целочисленная арифметика поддерживается ВО ВСЕХ архитектурах, начиная от БЭСМ-6 и заканчивая нонешними Intel и AVR.
Только в данном случае масштабный множитель как раз используется и вопрос в том как имея целочисленную арифметику получить арифметику с фиксированной запятой. То есть как учесть этом множитель при умножении, да ещё и не получить дополнительное(по сравнению с хранением чисел) ограничение на максимальное число при этом.
Jack_A писал(а):В частности, для этих чисел характерно, что в операции деления остаток отбрасывается.
Что делать с остатком - зависит от цели с которой делается умножение. Можно его отбрасывать, а можно округлять число, чтобы получить меньшую ошибку.
Jack_A писал(а):Успехов Вам в освоении целых чисел - знаковых и беззнаковых
Я их и так знаю. И в отличие от Вас пытаюсь ответить на вопросы про них.
Re: попогите дописать код
Murav писал(а): Я их [целые числа] и так знаю.
Это заметно...
Murav писал(а):Что делать с остатком - зависит от цели с которой делается умножение. Можно его отбрасывать, а можно округлять число, чтобы получить меньшую ошибку.
Остаток - при умножении ? Круто, оригинально. Операция деления выполняется процессором, он не наделен телепатическими способностями, чтобы знать, с какой целью выполняется "умножение", поэтому остаток отбрасывается ВСЕГДА.
Ладно, посмешили людей - и будя. Я для себя эту тему закрыл.
Re: попогите дописать код
Jack_A писал(а):Остаток - при умножении ? Круто, оригинально.
Для тех кто не понимает разницу между целыми числами и числами с фиксированной запятой, напишу ещё раз что в умножении чисел с фиксированной запятой кроме целочисленного умножения есть ещё и деление на базу.
Jack_A писал(а):Операция деления выполняется процессором, он не наделен телепатическими способностями, чтобы знать, с какой целью выполняется "умножение", поэтому остаток отбрасывается ВСЕГДА.
Процессор естественно остаток отбросит, а вот программист, если ему нужно округление, может посмотреть этот остаток(в случае программной операции деления эта операция возвращает как результат деления, так и остаток) и прибавить единицу к результату если нужно.