#设计原因#
*8位单片机没有16位的乘法和32位的除法,在AD采样数据处理时需要用到
*16位的乘除法需要用到两个16位变量的带c位移位
*C语言操作cpu寄存器很麻烦,嵌入汇编语言更好
*在iar编译环境中如何函数传递数组变量的方式有些特殊
以下代码运行正常,稍微修改一下可以使用。
#include "stm8l15x.h"
int Mul_16Bit(uint16_t,uint16_t,uint16_t * );
int Div_32Bit(uint16_t ,uint16_t,uint16_t,uint16_t * );
uint16_t a1,a2,a3;
uint16_t mul_rs[2];
int main( void )
{
uint16_t x0,x1;
//a1*a2=0x0626 0060
//a2a1/a3=0x0000 8422
a1=0x5678;
a2=0x1234;
a3=0x2345;
while(1){
Mul_16Bit(a1,a2,mul_rs);
x0=mul_rs[0];
x1=mul_rs[1];
Div_32Bit(a2,a1,a3,mul_rs);
x0=mul_rs[0];
x1=mul_rs[1];
}
return 0;
}
//r1*r2=>mul_rs[0]是低16位,mul_rs[1]是高16位
int Mul_16Bit(uint16_t r1,uint16_t r2,uint16_t *mul_r ){
uint16_t x0,x1,y0,y1,z0;
uint8_t i;
x0=0;
x1=0;
y0=r1;
y1=0;
z0=r2;
for(i=0;i<=15;i++){
if(z0&0x1){
x0=x0+y0;
asm("JRNC s0");
x1=x1+1;
asm("s0:");
x1=x1+y1;
}
y1=y1<<1;
y0=y0<<1;
asm("JRNC s1");
y1=y1+1;
asm("s1:");
z0=z0>>1;
}
mul_r[0]=x0;
mul_r[1]=x1;
return 0;
}
//r2r1/r3=>mul_r[0]是低16位,mul_rs[1]是高16位
int Div_32Bit(uint16_t r2,uint16_t r1,uint16_t r3,uint16_t *mul_r ){
uint16_t x0,x1,y1;
uint16_t z;
uint8_t i;
i=0;
x0=0;
x1=r2/r3;//高位商数
y1=r2%r3;//高位余数
if (y1==0){
x0=r1/r3;//低位商数
}
else{
asm("ds1:");
while((y1&0x8000)!=0x8000){
x0=x0<<1;
y1=y1<<1;
r1=r1<<1;
asm("JRNC ds0");
y1=y1+1;
asm("ds0:");
i++;
if(i>15){break;}
}
z=y1/r3;
x0=x0+z;
y1=y1%r3;
if (i<=15){
asm("JP ds1");
}
}
mul_r[0]=x0;
mul_r[1]=x1;
return 0;
}