Using more than a 32 bit integer with CW on the S12P MCU

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Using more than a 32 bit integer with CW on the S12P MCU

ソリューションへジャンプ
1,894件の閲覧回数
datamstr
Contributor II

Hi all,

 

I need to multiply a 32 bit integer by a 16 bit integer and divide that result by a 16 bit integer. For the intermediate result I need more than 32 bits. I am programming in C using CW. Any ideas on implementing an unsigned long long variable?

 

Thanks,
David

ラベル(1)
0 件の賞賛
返信
1 解決策
822件の閲覧回数
kef
Specialist I

You didn't say if you tolerate assembler. Here's my code:

 

 

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


typedef struct
{
   unsigned short hibits;
   unsigned long  lobits;
}  u48;


// *product  = m32 * m16
void mul32x16_48(u48 *product, unsigned long m32, unsigned short m16)
{
   asm
   {
      LDX   product
      LDD   m32:2
      LDY   m16
      EMUL
      STD   4,x
      STY   2,x
      LDD   m32
      LDY   m16
      EMUL
      ADDD  2,x
      STD   2,x
      TFR   Y,D
      ADCB  #0
      ADCA  #0
      STD   0,x
   }
}

// *q = *nom / denom
void div48x16(u48 *q, u48 *nom, unsigned short denom)
{
u48 qtmp;

   asm
   {
      LDY   nom
      LDD   0,y
      LDX   denom
      IDIV 
      STX   qtmp:0
      TFR   D,X
      LDD   2,y
      LDY   denom
      EXG   Y,X
      EDIV
      STY   qtmp:2
      LDY   nom
      LDY   4,y
      EXG   D,Y
      EDIV
      STY   qtmp:4
   }
   *q = qtmp;
}

u48 product;
u48 quot;

void main(void) {
  /* put your own code here */
 
   mul32x16_48(&product, 0x9876543F, 0xF765);
   div48x16(&quot, &product, 0xEDAB);

 EnableInterrupts;


  for(;:smileywink: {
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

元の投稿で解決策を見る

0 件の賞賛
返信
5 返答(返信)
823件の閲覧回数
kef
Specialist I

You didn't say if you tolerate assembler. Here's my code:

 

 

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


typedef struct
{
   unsigned short hibits;
   unsigned long  lobits;
}  u48;


// *product  = m32 * m16
void mul32x16_48(u48 *product, unsigned long m32, unsigned short m16)
{
   asm
   {
      LDX   product
      LDD   m32:2
      LDY   m16
      EMUL
      STD   4,x
      STY   2,x
      LDD   m32
      LDY   m16
      EMUL
      ADDD  2,x
      STD   2,x
      TFR   Y,D
      ADCB  #0
      ADCA  #0
      STD   0,x
   }
}

// *q = *nom / denom
void div48x16(u48 *q, u48 *nom, unsigned short denom)
{
u48 qtmp;

   asm
   {
      LDY   nom
      LDD   0,y
      LDX   denom
      IDIV 
      STX   qtmp:0
      TFR   D,X
      LDD   2,y
      LDY   denom
      EXG   Y,X
      EDIV
      STY   qtmp:2
      LDY   nom
      LDY   4,y
      EXG   D,Y
      EDIV
      STY   qtmp:4
   }
   *q = qtmp;
}

u48 product;
u48 quot;

void main(void) {
  /* put your own code here */
 
   mul32x16_48(&product, 0x9876543F, 0xF765);
   div48x16(&quot, &product, 0xEDAB);

 EnableInterrupts;


  for(;:smileywink: {
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

0 件の賞賛
返信
822件の閲覧回数
datamstr
Contributor II

Hey kef,

 

Works great!!!

 

Thanks so much!!

 

David

0 件の賞賛
返信
822件の閲覧回数
datamstr
Contributor II

Hi kef,

 

Do you have a divide routine for 48 bits divided by 24 bits?

 

Thanks,
David

0 件の賞賛
返信
822件の閲覧回数
kef
Specialist I

No, I don't. 24bits divider is well more complicated using S12 division instructions. Shift-subtract loop is the easy way to go. But shift-subtract is slow and new code requires some debugging. Then why not just using double precision floating point arithmetics? Since double mantissa is 52bits wide, double can contain up to 52bits wide integers without any rounding or loss of precision issues.

 

0 件の賞賛
返信
822件の閲覧回数
datamstr
Contributor II

I am avoiding use the floating point math library to keep the code smaller.

 

Thanks,
David

0 件の賞賛
返信