Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
13.08.2010, 18:50
|
|
Вид на жительство
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
|
Умножение 16x16 c 32-х битным результатом для AVR
Никак не могу разобраться с безнаковым умножением 16bit на 16bit с 32-х битным результатом для AVR-ок. Написал в CodeVision:
Код:
|
unsigned int a, b;
unsigned long c;
c=a*b; |
Компилятор матернулся что будет преполнение: Overflow is possible in 16 bit multiplication? casting to 'long' may be required.
И выдал такой код:
Код:
|
MOVW R30,R6
MOVW R26,R4
RCALL __MULW12U
CLR R22
CLR R23
STS _c,R30
STS _c+1,R31
STS _c+2,R22
STS _c+3,R23
__MULW12U:
MUL R31,R26
MOV R31,R0
MUL R30,R27
ADD R31,R0
MUL R30,R26
MOV R30,R0
ADD R31,R1
RET |
Изменил int на long, получив киллометровый код, но без матерщины:
Код:
|
LDS R30,_b
LDS R31,_b+1
LDS R22,_b+2
LDS R23,_b+3
LDS R26,_a
LDS R27,_a+1
LDS R24,_a+2
LDS R25,_a+3
RCALL __MULD12U
STS _c,R30
STS _c+1,R31
STS _c+2,R22
STS _c+3,R23
__MULD12U:
MUL R23,R26
MOV R23,R0
MUL R22,R27
ADD R23,R0
MUL R31,R24
ADD R23,R0
MUL R30,R25
ADD R23,R0
MUL R22,R26
MOV R22,R0
ADD R23,R1
MUL R31,R27
ADD R22,R0
ADC R23,R1
MUL R30,R24
ADD R22,R0
ADC R23,R1
CLR R24
MUL R31,R26
MOV R31,R0
ADD R22,R1
ADC R23,R24
MUL R30,R27
ADD R31,R0
ADC R22,R1
ADC R23,R24
MUL R30,R26
MOV R30,R0
ADD R31,R1
ADC R22,R24
ADC R23,R24
RET |
Знаю что у атмеля есть примеры умножения с FMUL-ом, но я в них не разобрался, так что в ту сторону прошу не пинать. Может кто решал подобную задачу?
__________________
Делая дело нужно в него верить на все 100%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
|
|
|
|
13.08.2010, 19:03
|
|
Супер-модератор
Регистрация: 15.10.2007
Сообщений: 3,537
Сказал спасибо: 172
Сказали Спасибо 1,561 раз(а) в 811 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
Код:
|
unsigned int a, b;
unsigned long c;
c = (unsigned long)a * b; |
|
|
|
Эти 2 пользователя(ей) сказали Спасибо realid за это сообщение:
|
|
|
13.08.2010, 21:23
|
|
Вид на жительство
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
КодеВижн врятли могу назвать качественным компилятором. Аналогично:
Код:
|
__MULD12U:
MUL R23,R26
MOV R23,R0
MUL R22,R27
ADD R23,R0
MUL R31,R24
ADD R23,R0
MUL R30,R25
ADD R23,R0
MUL R22,R26
MOV R22,R0
ADD R23,R1
MUL R31,R27
ADD R22,R0
ADC R23,R1
MUL R30,R24
ADD R22,R0
ADC R23,R1
CLR R24
MUL R31,R26
MOV R31,R0
ADD R22,R1
ADC R23,R24
MUL R30,R27
ADD R31,R0
ADC R22,R1
ADC R23,R24
MUL R30,R26
MOV R30,R0
ADD R31,R1
ADC R22,R24
ADC R23,R24
RET |
Ожидается что то вроде этого:
Код:
|
;************************************************* *****************************
;* ОПИСАНИЕ
;*Знаковое дробное умножение двух 16 битных чисел с 32 битным результатом.
;* Используются:
;*r19:r18:r17:r16 = ( r23:r22 * r21:r20 ) ‹‹ 1
;************************************************* *****************************
fmuls16x16_32:
clr r2
fmuls r23,r21 ;((знаковое)ah * (знаковое)bh) ‹‹ 1
movw r19:r18,r1:r0
fmul r22,r20 ;(al * bl) ‹‹ 1
adc r18,r2
movw r17:r16, r1:r0
fmulsu r23,r20 ;(( знаковое)ah * bl) ‹‹ 1
sbc r19,r2
add r17,r0
adc r18,r1
adc r19,r2
fmulsu r21,r22 ;(( знаковое)bh * al) ‹‹ 1
sbc r19,r2
add r17,r0
adc r18,r1
adc r19,r2 |
Это конечно не то. Знаковое и дробное.
__________________
Делая дело нужно в него верить на все 100%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
|
|
|
|
14.08.2010, 01:29
|
|
Вид на жительство
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
|
Умножение 16x16 c 32-х битным результатом для AVR
Разобрался, множил 65535 на 65535, 10000 на 25000, результаты правильные. Эту процедуру можно встроить в CV в виде функции вместо стандартного кривого умножения. realid, спасибо за участие.
__________________
Делая дело нужно в него верить на все 100%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
|
|
|
Эти 2 пользователя(ей) сказали Спасибо OneTech за это сообщение:
|
|
|
16.08.2010, 13:33
|
|
Вид на жительство
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
|
Умножение 16x16 c 32-х битным результатом для AVR
Для CodeVisionAVR:
Код:
|
#pragma warn-
unsigned long MUL16x16 (unsigned int a, unsigned int b)
{
#asm
ldd r16,Y+2 ;r16:r17=a
ldd r17,Y+3 ;...
ldd r18,Y+0 ;r18:r19=b
ldd r19,Y+1 ;...
;собственно само умножение (17 тактов)
mul r16,r18 ;умножить мл. байт множимого на мл. байт множителя
movw r30,r0 ;скопировать r0:r1 в 1-й, 2-й байты результата
mul r17,r19 ;умножить ст. байт множимого на ст. байт множителя
movw r22,r0 ;скопировать r0:r1 в 3-й, 4-й байты результата
mul r16,r19 ;умножить мл. байт множимого на ст. байт множителя
clr r16 ;очистить ненужный регистр для сложений с флагом "C"
add r31,r0 ;сложить r0:r1:r16 с 2-м, 3-м, 4-м байтами результата
adc r22,r1 ;...
adc r23,r16 ;...
mul r17,r18 ;умножить ст. байт множимого на мл. байт множителя
add r31,r0 ;сложить r0:r1:r16 с 2-м, 3-м, 4-м байтами результата
adc r22,r1 ;...
adc r23,r16 ;...
#endasm
};
#pragma warn+ |
Где:
a, b - unsigned int;
c - unsigned long;
__________________
Делая дело нужно в него верить на все 100%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
Последний раз редактировалось OneTech; 16.08.2010 в 13:36.
|
|
|
Сказали "Спасибо" OneTech
|
|
|
09.01.2012, 15:24
|
|
Заблокирован
Регистрация: 15.04.2010
Адрес: Ижевск
Сообщений: 388
Сказал спасибо: 24
Сказали Спасибо 45 раз(а) в 35 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
а для чего
#pragma warn-+
|
|
|
|
09.01.2012, 17:42
|
|
Почётный гражданин KAZUS.RU
Регистрация: 28.02.2010
Сообщений: 2,297
Сказал спасибо: 53
Сказали Спасибо 461 раз(а) в 392 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
в предположении на ругань ...а чему ругаться-то?(ааа - регистры могут не так сложиться)(просто первое предположение(не проверял- на прогонял))
Последний раз редактировалось OlegNZH; 09.01.2012 в 17:46.
|
|
|
|
25.04.2012, 11:05
|
|
Прописка
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
Хотел бы продолжить тему по умножению.
Код:
|
/************************************************** ***
#include ‹mega8.h›
// Standard Input/Output functions
#include ‹stdio.h›
#include ‹math.h›
unsigned long mul16x16(unsigned int a,unsigned int b);
// Declare your global variables here
unsigned int i1;
unsigned int i2;
unsigned long int mul;
void main(void)
{
// Declare your local variables here
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On a
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x2F;
i1= 0x2ffe; //12286
i2= 0x3ffc; //16380
while (1)
{
// Place your code here
mul= mul16x16(i1,i2);
printf("%lu\r\n",mul);
#asm("nop");
#asm("nop");
}
}
#pragma warn-
unsigned long mul16x16(unsigned int a,unsigned int b)
{
#asm
//---------------------------------------------------------------------------------------------------
.def l1 = r4 ;младший байт множимого
.def h1 = r5 ;старший байт множимого
.def l2 = r2 ;младший байт множителя
.def h2 = r3 ;старший байт множителя
.def res1 = r22 ;result byte 0 (LSD)
.def res2 = r23 ;result byte 1
.def res3 = r30 ;result byte 2 (MSD)
ldd l1,Y+2 ;r16:r17=a
ldd h1,Y+3 ;...
ldd l2,Y+0 ;r18:r19=b
ldd h2,Y+1 ;...
;умножение двух 16-разрядных величин, только для Mega
;исходные величины h1:l1 и h2:l2
;результат 3 байта res3:res2:res1
clr r31
clr res3 ;очистить старший
mul l1,l2 ;умножаем младшие
movw res2:res1,r1:r0
mul h1,l2 ;умножаем старший на младший
add res2,r0 ;в r0 младший результата операции mul
adc res3,r1 ;в r1 старший результата операции mul
mul l1,h2 ;умножаем младший на старший
add res2,r0 ;в r0 младший результата операции mul
adc res3,r1 ;в r1 старший результата операции mul
mul h1,h2 ;умножаем старший на старший
add res3,r0 ;в r0 младший результата операции mul
adc r31,r1 ;в r1 старший результата операции mul
//---------------------------------------------------------------------------------------------------
#endasm
}
#pragma warn+ |
Где я ошибаюсь? Совершенно не ожидаемые результаты.
Из каких соображений выбирается константа в выражении ldd l1,Y+2. И как узнать, к какой переменной они привязываются?
Поправьте меня, пожалуйста.
Последний раз редактировалось hubble; 26.04.2012 в 09:53.
|
|
|
|
26.04.2012, 05:37
|
|
Прописка
Регистрация: 14.04.2009
Сообщений: 103
Сказал спасибо: 17
Сказали Спасибо 11 раз(а) в 10 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
Вот достаточно универсальные подпрограммы деления и умножения 64битных чисел. Как видно можно просто переделать и под 32х32.
Код:
|
#asm
.def var10= r0
.def var11= r1
.def var12= r2
.def var13= r3
.def var14= r4
.def var15= r5
.def var16= r6
.def var17= r7
.def var18= r8
.def var19= r9
.def var110= r10
.def var111= r11
.def var112= r12
.def var113= r13
.def var114= r14
.def var115= r15
.def var20= r16
.def var21= r17
.def var22= r18
.def var23= r19
.def var24= r20
.def var25= r21
.def var26= r22
.def var27= r23
.def lc= r24
.def mod0= r8
.def mod1= r9
.def mod2= r10
.def mod3= r11
.def mod4= r12
.def mod5= r13
.def mod6= r14
.def mod7= r15
;-----------------------------------------------------------------------------;
; 64bit x 64bit unsigned multiply
;
; Register Variables
; Call: var1[7:0] = 64bit multiplicand
; var1[15:8] = ‹don't care›
; var2[7:0] = 64bit multiplier
; lc = ‹don't care› (high register must be allocated)
;
; Result:var1[15:0] = 128bit result of var1[7:0] * var2[7:0]
; var2[7:0] = ‹not changed›
; lc = 0
;
mul64u: clr var18 ;initialize variables
clr var19 ;
clr var110 ;
clr var111 ;
clr var112 ;
clr var113 ;
clr var114 ;
clr var115 ;
ldi lc,65 ; lc = 65;
brcc PC+9 ;---- calcurating loop
add var18,var20 ;
adc var19,var21 ;
adc var110,var22 ;
adc var111,var23 ;
adc var112,var24 ;
adc var113,var25 ;
adc var114,var26 ;
adc var115,var27 ;
ror var115 ;
ror var114 ;
ror var113 ;
ror var112 ;
ror var111 ;
ror var110 ;
ror var19 ;
ror var18 ;
ror var17 ;
ror var16 ;
ror var15 ;
ror var14 ;
ror var13 ;
ror var12 ;
ror var11 ;
ror var10 ;
dec lc ;if (--lc › 0)
brne PC-26 ; continue loop;
ret
;-----------------------------------------------------------------------------:
; 64bit/64bit Unsigned Division
;
; Register Variables
; Call: var1[7:0] = dividend (0x00000000..0xffffffffffffffff)
; var2[7:0] = divisor (0x00000001..0x7fffffffffffffff)
; mod[7:0] = ‹don't care›
; lc = ‹don't care› (high register must be allocated)
;
; Result:var1[7:0] = var1[7:0] / var2[7:0]
; var2[7:0] = ‹not changed›
; mod[7:0] = var1[7:0] % var2[7:0]
; lc = 0
;
div64u: clr mod0 ;initialize variables
clr mod1 ; mod = 0;
clr mod2 ; lc = 32;
clr mod3 ;
clr mod4
clr mod5
clr mod6
clr mod7
ldi lc,64 ;/
;---- calcurating loop
lsl var10 ;var1 = var1 ‹‹ 1;
rol var11 ;
rol var12 ;
rol var13 ;/
rol var14
rol var15
rol var16
rol var17
rol mod0 ;mod = mod ‹‹ 1 + carry;
rol mod1 ;
rol mod2 ;
rol mod3 ;/
rol mod4
rol mod5
rol mod6
rol mod7
cp mod0,var20 ;if (mod =› var2) {
cpc mod1,var21 ; mod -= var2; var1++;
cpc mod2,var22 ; }
cpc mod3,var23 ;
cpc mod4,var24
cpc mod5,var25
cpc mod6,var26
cpc mod7,var27
brcs PC+10 ;
inc var10 ;
sub mod0,var20 ;
sbc mod1,var21 ;
sbc mod2,var22 ;
sbc mod3,var23 ;/
sbc mod4,var24
sbc mod5,var25
sbc mod6,var26
sbc mod7,var27
dec lc ;if (--lc › 0)
brne PC-35 ; continue loop;
ret
#endasm |
|
|
|
|
26.04.2012, 09:50
|
|
Прописка
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
Re: Умножение 16x16 c 32-х битным результатом для AVR
Спасибо за подпрограммы.
Но дело в том, что программа работает, а именно, в r23:r22 числа 0B:FE и в r31:r30 числа C0:08.
В моем примере 2FFE*3FFC=0BFE C008.
Вроде бы все то. Но, только результат на выходе получаю с переставленными словами - C008 0BFE.
Вот и не знаю, как в программе их выдать так, как надо.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 04:34.
|
|