Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

Закрытая тема
Опции темы
Непрочитано 13.08.2010, 18:50   #1
OneTech
Вид на жительство
 
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
OneTech на пути к лучшему
По умолчанию Умножение 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%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
OneTech вне форума  
Непрочитано 13.08.2010, 19:03   #2
realid
Супер-модератор
 
Аватар для realid
 
Регистрация: 15.10.2007
Сообщений: 3,530
Сказал спасибо: 172
Сказали Спасибо 1,560 раз(а) в 810 сообщении(ях)
realid на пути к лучшему
По умолчанию Re: Умножение 16x16 c 32-х битным результатом для AVR

Код:
unsigned int a, b;             
unsigned long c;

c = (unsigned long)a * b;
realid вне форума  
Эти 2 пользователя(ей) сказали Спасибо realid за это сообщение:
dr.doc (07.11.2018), selevo (09.01.2012)
Непрочитано 13.08.2010, 21:23   #3
OneTech
Вид на жительство
 
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
OneTech на пути к лучшему
По умолчанию 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%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
OneTech вне форума  
Непрочитано 14.08.2010, 01:29   #4
OneTech
Вид на жительство
 
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
OneTech на пути к лучшему
По умолчанию Умножение 16x16 c 32-х битным результатом для AVR

Разобрался, множил 65535 на 65535, 10000 на 25000, результаты правильные. Эту процедуру можно встроить в CV в виде функции вместо стандартного кривого умножения. realid, спасибо за участие.
Миниатюры:
Нажмите на изображение для увеличения
Название: MUL_16_x_16_bit_with_32_bit_res.gif
Просмотров: 415
Размер:	9.7 Кб
ID:	10958  
__________________
Делая дело нужно в него верить на все 100%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.
OneTech вне форума  
Эти 2 пользователя(ей) сказали Спасибо OneTech за это сообщение:
alexgap (14.08.2010), selevo (09.01.2012)
Непрочитано 16.08.2010, 13:33   #5
OneTech
Вид на жительство
 
Регистрация: 09.10.2009
Сообщений: 356
Сказал спасибо: 21
Сказали Спасибо 64 раз(а) в 46 сообщении(ях)
OneTech на пути к лучшему
По умолчанию Умножение 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+
Код:
c=MUL16x16(a, b);
Где:
a, b - unsigned int;
c - unsigned long;
__________________
Делая дело нужно в него верить на все 100%, иначе неизбежно будут возникать ошибки подпитывающие подсознательное сомнение.

Последний раз редактировалось OneTech; 16.08.2010 в 13:36.
OneTech вне форума  
Сказали "Спасибо" OneTech
selevo (09.01.2012)
Непрочитано 09.01.2012, 15:24   #6
selevo
Заблокирован
 
Регистрация: 15.04.2010
Адрес: Ижевск
Сообщений: 388
Сказал спасибо: 24
Сказали Спасибо 45 раз(а) в 35 сообщении(ях)
selevo на пути к лучшему
По умолчанию Re: Умножение 16x16 c 32-х битным результатом для AVR

а для чего
#pragma warn-+
selevo вне форума  
Непрочитано 09.01.2012, 17:42   #7
OlegNZH
Почётный гражданин KAZUS.RU
 
Регистрация: 28.02.2010
Сообщений: 2,297
Сказал спасибо: 53
Сказали Спасибо 461 раз(а) в 392 сообщении(ях)
OlegNZH на пути к лучшему
По умолчанию Re: Умножение 16x16 c 32-х битным результатом для AVR

в предположении на ругань ...а чему ругаться-то?(ааа - регистры могут не так сложиться)(просто первое предположение(не проверял- на прогонял))

Последний раз редактировалось OlegNZH; 09.01.2012 в 17:46.
OlegNZH вне форума  
Непрочитано 25.04.2012, 11:05   #8
hubble
Прописка
 
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
hubble на пути к лучшему
По умолчанию 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.
hubble вне форума  
Непрочитано 26.04.2012, 05:37   #9
makser1
Прописка
 
Регистрация: 14.04.2009
Сообщений: 103
Сказал спасибо: 17
Сказали Спасибо 11 раз(а) в 10 сообщении(ях)
makser1 на пути к лучшему
По умолчанию 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
makser1 вне форума  
Непрочитано 26.04.2012, 09:50   #10
hubble
Прописка
 
Регистрация: 04.08.2006
Сообщений: 139
Сказал спасибо: 12
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
hubble на пути к лучшему
По умолчанию Re: Умножение 16x16 c 32-х битным результатом для AVR

Спасибо за подпрограммы.
Но дело в том, что программа работает, а именно, в r23:r22 числа 0B:FE и в r31:r30 числа C0:08.
В моем примере 2FFE*3FFC=0BFE C008.
Вроде бы все то. Но, только результат на выходе получаю с переставленными словами - C008 0BFE.
Вот и не знаю, как в программе их выдать так, как надо.
hubble вне форума  
Закрытая тема

Закладки

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
FAQ (ЧаВО) по PROTEUS для начинающих и не только dosikus Proteus 221 07.03.2024 22:45
LPT программатор для AVR. Выбор skywriter_ufa Микроконтроллеры, АЦП, память и т.д 24 27.10.2010 02:26
Flowcode для AVR vik3213 Микроконтроллеры, АЦП, память и т.д 13 17.07.2010 20:42
Сравнение средств разработки для микроконтроллеров AVR и PIC silic Микроконтроллеры, АЦП, память и т.д 24 04.12.2009 07:36
переносной ISP загрузчик для AVR Ugauga Микроконтроллеры, АЦП, память и т.д 8 07.11.2009 20:47


Часовой пояс GMT +4, время: 20:16.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot