第五篇AVR单片机浮点数运算程序设计Word文件下载.docx
《第五篇AVR单片机浮点数运算程序设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《第五篇AVR单片机浮点数运算程序设计Word文件下载.docx(25页珍藏版)》请在冰豆网上搜索。
注意:
挪用加减乘除子程序前必需将Y寄放器置初值,利用的SRAM五个字节的地址为Y-五、Y-4、Y-3、Y-二、Y-1。
且应使这五个字节与堆栈区和SRAM其它工作区不要重复。
浮点运算子程序库中包括以下八个子程序:
INT2FP—16位整数转换成四字节浮点数运算子程
LONG2FP—32位长整数转换成四字节浮点数运算子程
FP2INT—四字节浮点数转换成16位整数运算子程
FP2LONG—四字节浮点数转换成32位长整数运算子程
ADD32F—四字节浮点加法运算子程
SUB32F—四字节浮点减法运算子程
DIV32F—四字节浮点除法运算子程
MPY32F—四字节浮点乘法运算子程
由于这八个浮点子程序都是常常利用的。
所以将这些子程序编写在一块,各有自己的入口,又有一些一路的程序段。
如此编写能够节省程序存储单元,浮点程序库总共只占353个字,还不到AT90S8535内部Flash的十分之一,一般不至于影响寄存用户程序。
以下简单介绍一下各浮点子程序的程序思想:
1.定点长整数(或整数)转换成浮点数:
若为整数先将其转换成长整数(正数高16位添0,负数高16位添1);
掏出符号位及绝对值(正数绝对值不变,负数绝对值取补);
将31位绝对值左移至最高位为1,其后23位数即为浮点数尾数(不足23位用0补足);
浮点数的阶码为$9d减去左移次数。
2.浮点数取长整(或取整):
先判断阶码是不是小于$7f,若小于$7f则结果为0;
再看阶码是不是大于$9d(或$8d),若大于则溢出,正数取$7fffffff(或$7fff),负数取$(或$8000);
不然尾数最高位补1,右移24位尾数($96-阶码)次,即可求得尾数绝对值;
取补即取得长整数(或整数)。
注:
($96-阶码)为负时为低位补0次数。
3.浮点加减法运算:
减法可对减数改变符号作加法运算;
如一个加数为零或两数的阶码值相差大于尾数长度(24位),则可忽略较小的加数,之和取较大的加数;
作加法运算前先对阶,小阶对大阶,较小的数尾数右移阶码之差次;
尾数作加法运算;
结果再浮点规格化,转化成24位尾数最高位恰好为1,化成规定浮点格式。
4.浮点乘法运算:
不需要对准小数点,只要把阶码相加,再减去$7e;
尾数相乘;
符号相异或;
然后对结果进行必要的规格化。
5.浮点数除法运算:
在执行浮点数除法时,应先调整被除数的阶码,使被除数的尾数小于除数的尾数(使商不大于1),然后把阶码相减,再加上$7e;
尾数相除;
符号相异或。
一般浮点库利用者没必要详细了解浮点子程的编写原理,只要求正确利用这些浮点子程,注意入口、出口、利用的寄放器(必要时这些寄放器应加以保护)和利用的内部SRAM地址(应使这些SRAM不作其他常期保留数据的空间和远离堆栈区)。
浮点子程序库()清单:
入口:
r17:
r16;
出口:
r19:
r18:
r17:
r16
利用的寄放器:
r16,r17,r18,r19,r20,r26。
r19:
r16;
出口:
r18;
r16+r24:
r23:
r22:
r21;
r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r28,r29;
利用的SRAM:
Y-5,Y-4,Y-3,Y-2,Y-1。
r16-r24:
r16/r24:
r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r28,r29;
Y-1。
INT2FP:
;
16位整数转换成四字节浮点数运算子程
CLRR18
SBRCR17,7;
R17:
R16为待转换的整数
COMR18
CLRR19;
16位整数按数符位扩展成32位长整数
SBRCR18,7;
为正,R19,R18清零
COMR19;
为负,R19,R18置为$FFFF
LONG2FP:
;
32位长整数转换成四字节浮点数运算子程
CLRR20;
清符号位R20
ANDR19,R19;
先判+/-
BRPLLONG2FP_1;
为正,跳至LONG2FP_1
RCALLQUBU;
为负,调QUBU子程——取补
COMR20;
符号位R20取反
LONG2FP_1:
MOVR26,R16;
再判R19:
R18:
R17:
R16是不是全零
ORR26,R17
ORR26,R18
ORR26,R19
BRNELONG2FP_2;
不为零跳至LONG2FP_2
RJMPJGW0;
为零跳至JGW0——结果为零
LONG2FP_2:
LDIR26,$16;
令R26=22
RJMPLONG2FP_4
LONG2FP_3:
INCR26
LSRR19
RORR18
RORR17
RORR16
LONG2FP_4:
判高位是不是为零
BRNELONG2FP_3;
不为零,右移一名,阶码加1
LONG2FP_5:
ANDR18,R18;
判次高位是不是为零
BRNELONG2FP_7
SUBIR26,$08;
为零,阶码减8
MOVR18,R17;
数左移8位
MOVR17,R16
LDIR16,$00;
低位以$00填充
RJMPLONG2FP_5
LONG2FP_6:
DECR26
ADDR16,R16
ADCR17,R17
ADCR18,R18
LONG2FP_7:
BRPLLONG2FP_6;
R18第7为0,再左移一名
MOVR19,R26;
阶码减1,直到R18第7位为1
RJMPGGH
FP2INT:
四字节浮点数转换成16位整数运算子程
LDIR26,$0E;
令R26=14
RJMPFP2LONG_1;
跳至FP2LONG_1
FP2LONG:
四字节浮点数转换成32位长整数运算子程
LDIR26,$1E;
令R26=30
FP2LONG_1:
RCALLFP2LONG_11;
调FP2LONG_11子程
BREQFP2LONG_4;
相等,即阶码为0,按0处置
SUBR26,R19;
R26(14)-阶码差值
BREQFP2LONG_2;
为0,则跳至FP2LONG_2
BRPLFP2LONG_5;
为正,则跳至FP2LONG_5——无溢出
FP2LONG_2:
有溢出
ANDR20,R20;
符号为正,
BRMIFP2LONG_3;
符号为负,则跳至FP2LONG_3
LDIR16,$FF
LDIR17,$FF
LDIR18,$FF
LDIR19,$7F
RET;
正向溢出,结果置为$7FFFFFFF
FP2LONG_3:
LDIR16,$00
LDIR17,$00
LDIR18,$00
LDIR19,$80
负向溢出,结果置为$80000000
FP2LONG_4:
LDIR18,$00
LDIR19,$00
结果为0,置为$00000000
FP2LONG_5:
无溢出
INCR19;
阶码差值+1
BRMIFP2LONG_4;
为负,即(阶码<
$7E)按零处置
LDIR19,$00;
清R19
R26(14-阶码差值)-8
BRPLFP2LONG_7;
为正转FP2LONG_7
SUBIR26,$F8;
不够减则加8
MOVR19,R18;
左移8位
MOVR18,R17
LDIR16,$7F;
低位以$7F填充
RJMPFP2LONG_8;
跳至FP2LONG_8
FP2LONG_6:
MOVR16,R17;
右移8位
MOVR17,R18
LDIR18,$00;
高位以$00填充
SUBIR26,$08;
R26-8
FP2LONG_7:
CPIR26,$08;
R26值与8相较较
BRCCFP2LONG_6;
有借位,跳至FP2LONG_6
FP2LONG_8:
无借位
ANDR26,R26
BREQFP2LONG_10
FP2LONG_9:
LSRR19;
右移一名
RORR18
RORR17
RORR16
DECR26;
R26-1,不为0跳至FP2LONG_9
BRNEFP2LONG_9;
直到R26为0为止
FP2LONG_10:
考虑符号位
SBRCR20,7
RJMPQUBU;
为负,则跳至QUBU——取补返回
为正,返回
FP2LONG_11:
MOVR20,R19;
取浮点数数符存于R20最高位
ANDIR20,$80
ADDR18,R18;
将阶码移至R19
ADCR19,R19
SUBIR19,$80;
阶码减$80存于R19
SEC
RORR18;
恢复尾数最高位1
CPIR19,$80;
阶码差值与$80相较较
RET
ADD32F_1:
存储结果
MOVR20,R25
MOVR19,R24
MOVR18,R23
MOVR17,R22
MOVR16,R21
ADD32F_2:
RJMPGGH;
跳至GGH——处置结果
SUB32F:
四字节浮点减法运算子程
SUBIR24,$80;
减数取反,视为浮点加法运算
ADD32F:
四字节浮点加法运算子程
RCALLYCL;
调YCL子程
CPIR24,$80;
先判加数是不是为0
BREQADD32F_2;
为0则和为被加数跳至ADD32F_2
再判被加数是不是为0
BREQADD32F_1;
为0则和为加数跳至ADD32F_1
ADD32F_3:
MOVR26,R19;
转存被加数阶码
SUBR26,R24;
R26=被加数阶码减加数阶码
BRVSADD32F_2;
溢出,跳至ADD32F_2即加数可忽略
BRMIADD32F_4;
为负,跳至ADD32F_4
BRNEADD32F_5;
不等,跳至ADD32F_5
CPR16,R21
CPCR17,R22
CPCR18,R23
BRCCADD32F_5
ADD32F_4:
RCALLADD32F_16;
调ADD32F_16,被加数和加数彼此换
RJMPADD32F_3;
跳至ADD32F_3
ADD32F_5:
CPIR26,$18;
阶码差值与24相较较
BRCSADD32F_6;
C=1,跳至ADD32F_6,即<
24
CLRR21;
>
24加数清0
CLRR22
CLRR23
ADD32F_6:
阶码差值与8相较较
BRCSADD32F_7;
C=1,跳至ADD32F_7(直至<
8)
MOVR21,R22;
加数尾数右移8位
MOVR22,R23;
高8位清0
阶码差值再减8
RJMPADD32F_6;
跳至ADD32F_6
ADD32F_7:
ANDR26,R26
BREQADD32F_9;
直至R26=0,跳至ADD32F_9
ADD32F_8:
LSRR23;
加数尾数右移1位
RORR22
RORR21
阶码差值减1
BRNEADD32F_8;
不为0跳至ADD32F_8
ADD32F_9:
MOVR26,R20;
被加数和加数是不是同号
EORR26,R25
BRMIADD32F_10;
异号,跳至ADD32F_10
RCALLADD32F_13;
同号,调ADD32F_13子程——尾数相加
BRCCADD32F_2;
C=0,无溢出,跳至ADD32F_2
RORR18;
C=1,溢出,尾数右移1位
SUBIR19,$FF;
阶码加1
BRVCADD32F_2;
无溢出,跳至ADD32F_2,处置结果
RJMPJGZD;
溢出,跳至JGZD,出结果
ADD32F_10:
RCALLADD32F_14;
调ADD32F_14子程——尾数相减
BRNEADD32F_11;
不等,跳至ADD32F_11
RJMPJGW0;
跳至JGW0,出结果
ADD32F_11:
BRCCADD32F_12;
C=0,够减,跳至ADD32F_12
RCALLADD32F_15;
C=1,不够减,调ADD32F_15子程——取补
ADD32F_12:
ANDR18,R18;
判R18最高位是不是位1
BRMIADD32F_2;
为1,跳至ADD32F_2,处置结果
ADDR16,R16;
为0,尾数左移一名
ADCR17,R17
ADCR18,R18
SUBIR19,$01;
阶码减1
BRVCADD32F_12;
无溢出,跳至ADD32F_12
RJMPJGZD;
溢出,跳至JGZD,出结果
ADD32F_13:
尾数相加
ADDR16,R21
ADCR17,R22
ADCR18,R23
ADD32F_14:
尾数相减
SUBR16,R21
SBCR17,R22
SBCR18,R23
ADD32F_15:
结果取补
COMR17
NEGR16
SBCIR17,$FF
SBCIR18,$FF
ADD32F_16:
两个数彼此换
ST-Y,R21
ST-Y,R22
ST-Y,R23
ST-Y,R24
ST-Y,R25
MOVR24,R19
MOVR21,R16
MOVR22,R17
MOVR23,R18
MOVR25,R20
LDR20,Y+
LDR19,Y+
LDR18,Y+
LDR17,Y+
LDR16,Y+
RET
YCL:
MOVR20,R19
LDIR26,$80
ADDR18,R18
ADCR19,R19;
EORR19,R26;
阶码减$80存于R19
ADDR26,R26
RORR18;
恢复尾数最高位1
ANDIR20,$80;
取浮点数数符存于R20最高位
MOVR25,R24
LDIR26,$80
ADDR23,R23;
将阶码移至R24
ADCR24,R24
EORR24,R26;
阶码减$80存于R24
ADDR26,R26
RORR23;
ANDIR25,$80;
取浮点数数符存于R25最高位
CPIR19,$80
GGH:
;
规格化
ADDR18,R18;
隐含尾数最高位为1
LDIR26,$80;
考虑符号位
EORR26,R19;
ADDR20,R20
RORR26;
右移R26,R18
MOVR19,R26;
R26移至R19
DIV32F_1:
ST-Y,R26;
转存R26
CLRR13;
清R15:
R14:
R13
CLRR14
CLRR15
LDIR26,$18;
令R26=$18(24)
DIV32F_2:
CPR16,R21;
被除数(余数)与除数两尾数相较
BRCSDIV32F_3;
被除数(余数)<
除数
SUBR16,R21;
余数=被除数-除数
SBCR18,R23
SEC
RJMPDIV32F_4
DIV32F_3:
CLC;
清除进位位
DIV32F_4:
ADCR13,R13;
商左移一名,并加上进位位
ADCR14,R14
ADCR15,R15
余数左移一名
DECR26;
R26-1
BRNEDIV32F_2;
循环24次
MOVR16,R13;
掏出商
MOVR17,R14
MOVR18,R15
LDR26,Y+;
恢复R26
DIV32F:
四字节浮点除法运算子程
ANDR24,R24
BREQDIV32F_7;
跳至DIV32F_7,出结果
ANDR19,R19;
判被除数是不是为0
BREQJGW0;
为0,则结果为0
RCALLYCL;
调YCL子程
跳至JGW0,结果为0
EORR20,R25;
取商的符号位存于R20
SBCR19,R24;
掏出商的阶码
BRVSJGZD;
溢出,跳至JGZD
LSRR23;
RORR22;
将被除数与除数得尾数
RORR21;
右移一名,最高位置0
LSRR18
RCALLDIV32F_1;
调DIV32F_1子程,进行运算
ANDR18,R18;
判R18最高位是不是为0
BRMIDIV32F_5;
为1
ADDR16,R16;
为0,左移被除数