⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zz51.a51

📁 基于mcs51单片机的四字节浮点数的库程序
💻 A51
📖 第 1 页 / 共 4 页
字号:
	ACALL   LR0             ;否则,整数、小数部分整体左移一位
	DEC     R0              ;阶减1
	CJNE    R0,#60H,LP11
	RET                     ;浮点数为0
NX63:   CALL   EX              ;二进制浮点数转入R4~R7
	MOV     A,R0
	JNB     ACC.7,PP6
	CALL   INC3            ;截去部分四舍五入
	CJNE    R5,#0,PP6
	INC     R4              ;调整
	MOV     R5,#80H
PP6:    JBC	7BH,PPX
	ANL     0DH,#7FH        ;置数符
PPX:    RET
;------------------------------------------------
;标号:BTOD 功能: 二进制浮点数转为十进制浮点数
;入口:二进制浮点数在 R4,R5,R6,R7
;出口:十进制浮点数在 R0=阶;R5=阶符,R6=数符,00H为正,非0为负
;注意:这里所说的'阶'--->指的是整数的位数
;R1,R2,R3,R4内为纯小数尾数,R1为高位字节
;------------------------------------------------
BTOD:	CLR	A	;浮点数x二翻十子程序
	MOV	18H,A		;清阶符单元
	MOV	19H,A		;清数符单元
	MOV	1BH,A		;清阶码单元
	MOV	A,R4
	JZ	PP4		;浮点数为0,转换结果亦为0
	MOV	A,R5
	RLC	A
	JNC	BTA
	DEC	19H		;记数符(0→0FFH)
	ANL	0DH,#7FH	;取绝对值
BTA:	LCALL	DDP		;取1010
	LCALL	FPCP		;|x|与1010比较
	JC	BTC		;|x|<1010转
BTB:	LCALL	INVDP		;取10-10
	LCALL	FPMU		;|x|·10-10→|x|
	MOV	A,1BH
	ADD	A,#10H		;十进制浮点数阶码加10
	MOV	1BH,A
	SJMP	BTA
BTC:	LCALL	INVDP
	LCALL	FPCP		;|x|与10-10比较
	JZ	BTE
	JNC	BT0		;|x|>10-10,转
BTE:	LCALL	DDP
	LCALL	FPMU		;|x|·1010→|x|
	MOV	A,1BH
	ADD	A,#10H		;十进制浮点数阶码加10
	MOV	1BH,A
	DEC	18H		;负阶
	SJMP	BTC
BT0:	LCALL   G1
	LCALL	FPCP		;|x|与1比较
	JC	BT2		;|x|<1,转
BT1:	LCALL	G01
	LCALL	FPMU		;|x|·10-1→|x|
	INC	1BH		;十进制浮点数阶码加1
	SJMP	BT0
BT2:	LCALL	G01
	LCALL	FPCP		;|x|与0.1比较
	JZ	BT4
	JNC	BDS		;|x|≥0.1转出
BT3:	LCALL	G10		;否则|x|·10→|x|
	LCALL	FPMU
	INC	1BH		;十进制浮点数阶码加1
	DEC	18H		;负阶
	SJMP	BT2
PP4:	LJMP	LD0		;取十进制浮点数0
BT4:	MOV	R1,#10H
	CLR	A
	MOV	R2,A
	MOV	R3,A
	MOV	R4,A		;取十进制浮点数尾数0.100 000 00
	SJMP	BT6
BDS:	MOV	A,#98H
	ORL	0DH,#80H	;恢复尾数最高位
	CLR	C
	SUBB	A,R4		;右移位数为98H-阶码
	MOV	B,A
	LCALL	CONV31		;得十进制浮点数尾数
BT6:	MOV	A,1BH
	JNB	ACC.3,BT7
	JNB	ACC.1,BT7	;低位BCD码为1010B?
	ADD	A,#6		;对十进制浮点数的阶检查调整
BT7:	MOV	R0,A		;回送阶
	MOV	R5,18H		;回送阶符
	MOV	R6,19H		;回送数符
	RET	
BB:	JNB	ACC.7,BB1
	ADD	A,#0D0H		;右移后,BCD码最高位为1(代表8)变为5
BB1:	JNB	ACC.3,BB2
	ADD	A,#0FDH
BB2:	RET
;------------------------------------------------ 
;标号: DTOB 功能: 将十进制浮点数转成二进制浮点数
;阶符:正为00H,负为0FFH ;数符:正数为00H,负数为0FFH
;注意阶符是指'阶或指数P的符号'.公式:移码(阶码)=补码(阶)±80H
;或 移码=阶+80H (阶带符号);阶=移码-80H
;阶与尾数均为压缩BCD码,尾数为纯小数
;入口: 十进制浮点数在R1,R2,R3,R4,R5,R6,R7单元内,
;其中R1=阶符,R2=数符,R3=阶-->这里所说的阶是十进制浮点数的阶,即为小数点的位置
;如 0.1的阶为'0';0.01的阶为'-1';1的阶为'+1';22.00的阶为'+2'	
;R4~R7为纯小数尾数,R4为高位字节
;出口:二进制浮点数在R4,R5,R6,R7中
;------------------------------------------------
DTOB:	MOV	30H,R1		;十进制数阶符
	MOV	31H,R2		;十进制数数符
	MOV	32H,R3		;十进制数阶
	CALL	CONV4		;十进制尾数十翻二(定点小数十翻二)
	MOV	R0,#80H		;置阶码(指数的偏移量)
	MOV	A,R4
	ORL	A,R5
	ORL	A,R6
	ORL	A,R7
	JZ	PP8		;二进制小数等于0,结果二进制数为0
	MOV	A,R4    	;尾数高字节
LP14:	JB	ACC.7,NX67      ;左移使 ACC.7=1,向下
	CALL	SHIF    	;尾数算术左移1位子程序
	RLC	A
	DEC	R0		;对二进制小数规格化
	SJMP	LP14
NX67:	XCH	A,R5
	XCH	A,R6
	XCH	A,R7		;尾数从A R5 R6 R7转入R5	R6 R7 A中
	JNB	ACC.7,NX66
	CALL	INC3		;四舍五入
	CJNE	R5,#0,NX66
	INC	R0
	MOV	R5,#80H		;调整尾数,阶码
NX66:	XCH	A,R0
	XCH	A,R4
	MOV	A,31H
	JNZ	NX6A
	ANL	0DH,#7FH	;置数符,得x
NX6A:	MOV	A,30H		;阶符
	JZ	DBL4		;正阶,转
DBL1:	MOV	A,32H		;取阶
	CLR	C
	SUBB	A,#10H
	JC	DBL2
	MOV	32H,A
	LCALL	INVDP		;阶减去10, x·10-1o→x
	LCALL	FPMU
	SJMP	DBL1
DBL2:	ADD	A,#10H		;恢复阶
	JZ	PP8
DBL3:	LCALL	G01		;取0.1
	LCALL	FPMU
	DJNZ	32H,DBL3	;x·10-1→x,阶减1
	RET
DBL4:	MOV	A,32H
	CLR	C  
	SUBB	A,#10H
	JC	DBL5		;阶减去10, x·101o→x
	MOV	32H,A
	LCALL	DDP
	LCALL	FPMU
	SJMP	DBL4
DBL5:	ADD	A,#10H		;恢复阶
	JZ	PP8
DBL6:	LCALL	G10
	LCALL	FPMU		;x·10→x,阶减1
	DJNZ	32H,DBL6
PP8:	RET
INVDP:	MOV	R0,#5FH		;取浮点数10-1o
	MOV	R1,#5BH
	MOV	R2,#0E6H
	MOV	R3,#0FFH
	RET
DDP:	MOV	R0,#0A2H	;取浮点数101o
	MOV	R1,#15H
	MOV	R2,#02H
	MOV	R3,#0F9H
	RET
;------------------------------------------------		
;清单19 标号: STRT 功能: 最小二乘法拟合直线程序
;------------------------------------------------
	ORG     3000H     	;最小二乘法拟合直线程序
	NUMB    EQU 10    	;取10点,即10对浮点数,
	                  ;按增地址存放y1,x1,y2,x2,…,yn,xn皆4字节浮点数
	TABLA   EQU 9000H 	;数据指针,首指向y1
STRT:   PUSH    PSW
	SETB    RS0
	CLR     RS1
	MOV     R0,#18H
LP51:   MOV     @R0,#0    ;清累加和单元,即LD1,LD2,LD3,LD4和LD5所占用的单元
	INC     R0
	CJNE    R0,#1CH,LP51
	MOV     R0,#30H
LP52:   MOV     @R0,#0
	INC     R0
	CJNE    R0,#40H,LP52
	MOV     B,#NUMB         ;总拟和点数
	MOV     DPTR,#TABLA     ;数据指针
LOOP3:  ACALL   GETA    	;取y1,y2,y3,y4(合称yi)占4字节,下同
	LCALL   INVX            ;计算1/yi
	LCALL   LD6             ;暂存
	LCALL   GET1            ;取累加和
	LCALL   FPAD    ;1/yi加入累加和(∑1/yi是 ∑n〖〗i=11/yi 简写形式,下同)
	LCALL   LD1
	ACALL   GET6    	;取1/yi
	PUSH    DPL
	PUSH    DPH     	;保护数据指针
	ACALL   GETA    	;取xi,占4字节(x1,x2,x3,x4),下同
	POP     DPH
	POP     DPL
	LCALL   FPMU    	;计算xi/yi
	ACALL   LD7     	;暂存
	LCALL   GET2
	LCALL   FPAD    	;xi/yi加入累加和∑xi/yi
	LCALL   LD2
	ACALL   GET7    	;取出xi/yi
	LCALL   SAV0
	LCALL   FPMU    	;计算(xi/yi)2
	LCALL   GET3
	LCALL   FPAD    	;(xi/yi)2加入累加和∑(xi/yi)2
	LCALL   LD3
	ACALL   GET6    	;取1/yi
	LCALL   SAV0
	LCALL   FPMU    	;计算1/yi2
	ACALL   LD6     	;暂存
	LCALL   GET4
	LCALL   FPAD    	;1/yi2加入累加和∑ 1/yi2
	LCALL   LD4
	ACALL   GET6    	;取出1/yi2
	ACALL   GETA    	;再取xi
	LCALL   FPMU    	;计算xi/yi2
	ACALL   GET5
	LCALL   FPAD    	;xi/yi2加入累加和∑xi/yi2
	ACALL   LD5
	DJNZ    B,LOOP3		;未到总点数,循环
	LCALL   GET4
	LCALL   SAV0
	LCALL   GET3
	LCALL   FPMU    	;计算∑1/yi2·∑xi/yi2并存入
	ACALL   LD6
	ACALL   GET5    	;取∑xi/yi2 
	LCALL   SAV0
	LCALL   FPMU    	;计算(∑xi/yi2 )2
	ACALL   GET6
	LCALL   FPSU    	;计算A=∑1/yi2·∑xi/yi2-(∑xi/yi2)2
	ACALL   LD6     	;存入
	LCALL   GET2
	LCALL   SAV0
	LCALL   GET4
	LCALL   FPMU    	;计算∑ xi/yi·(∑ 1/yi)2并存入
	ACALL   LD7
	LCALL   GET1
	LCALL   SAV0
	ACALL   GET5
	LCALL   FPMU    	;计算∑ 1/yi·∑ xi/yi2并存入
	ACALL   GET7
	LCALL   FPSU    	;计算B=∑ xi/yi·(∑ 1/yi)2-∑ 1/yi·∑ xi/yi2
	ACALL   GET6    	;取A
	LCALL   EX
	LCALL   FPDI    	;计算b=B/A并存入
	ACALL   LD7
	ACALL   GET5    	;取∑xi/yi2
	LCALL   FPMU    	;计算(∑ xi/yi2 )·b
	LCALL   GET1
	LCALL   FPSU    	;计算∑1/yi-(∑xi/yi2)·b
	LCALL   GET4    	;取∑1/yi2
	LCALL   EX
	LCALL   FPDI    	;计算a=\[∑1/yi-(∑xi/yi2)·b\]/∑1/yi2 
	ACALL   LD6     	;结果a在40H~43H中,b在44H~47H中
	POP     PSW
	RET	
GETA:   PUSH    8       	;保护R0
	MOV     R0,#0CH
GETL:   MOVX    A,@DPTR 	;从外部RAM中取浮点数到R4~R7中
	MOV     @R0,A
	INC     DPTR
	INC     R0
	CJNE    R0,#10H,GETL
	POP     8
	RET
LD5:    MOV	3CH,R4  	;计算 ∑xi/yi2 的存储单元
	MOV     3DH,R5
	MOV     3EH,R6
	MOV     3FH,R7
	RET
LD6:    MOV	40H,R4  	;暂存1/yi等浮点数子程序
	MOV     41H,R5
	MOV     42H,R6
	MOV     43H,R7
	RET
LD7:    MOV	44H,R4  	;暂存xi/yi等浮点数
	MOV     45H,R5
	MOV     46H,R6
	MOV     47H,R7
	RET
GET5:   MOV     R0,3CH  	;取∑ xi/yi2或中间结果
	MOV     R1,3DH
	MOV     R2,3EH
	MOV     R3,3FH
	RET
GET6:   MOV     R0,40H  	;取浮点数1/yi等
	MOV     R1,41H
	MOV     R2,42H
	MOV     R3,43H
	RET
GET7:   MOV     R0,44H  	;取浮点数xi/yi等
	MOV     R1,45H
	MOV     R2,46H
	MOV     R3,47H
	RET
;------------------------------------------------	
;清单20:标号: MUL16 功能:定点16位整数×16位整数→32位整数
;------------------------------------------------
MUL16:  CLR     A       ;定点16位整数×16位整数→32位整数
	MOV     R4,A
	MOV     R5,A
	MOV     A,#11H
	CLR     C
LP15:   JNC     NX70
	ACALL   ADD3
NX70:   XCH     A,R4
	RRC     A
	XCH     A,R4
	LCALL   SRA
	DJNZ    ACC,LP15
	RET
MUL165:	ACALL   MUL16   	;16位整数×16位小数→16位整数
	MOV     A,R6    	;精确到0.5
	JNB     ACC.7,LL1
	INC     R5
	CJNE    R5,#0,LL1
	INC     R4
LL1:    RET
ADD3:   XCH     A,R5
	ADD     A,R3
	XCH     A,R5
	XCH     A,R4
	ADDC    A,R2
	XCH     A,R4
	RET
SUB3:   CLR     C
	XCH     A,R5
	SUBB    A,R3
	XCH     A,R5
	XCH     A,R4
	SUBB    A,R2
	XCH     A,R4
	RET
DIV16:  MOV     A,#16   	;定点32位整数÷16位整数→16位整数
LL0:    LCALL   SHIF    	;精确到1
	XCH     A,R4
	RLC     A
	XCH     A,R4
	JC      D161
	LCALL   SUB3
	JNC     D162
	LCALL   ADD3
	SJMP    D163
D161:   LCALL   SUB3
D162:   INC     R7
D163:   DJNZ    ACC,LL0
	RET
DIV165: ACALL   DIV16   	;32位整数÷16位整数→16位整数
	MOV     A,R5    	;精确到0.5
	ADD     A,R5
	MOV     R5,A
	MOV     A,R4
	ADDC    A,R4
	MOV     R4,A
	JC      D164
	ACALL   SUB3
	JC      D165
D164:   LCALL   INC3
D165:   RET
DIV16F: ACALL   DIV16   ;32位整数÷16位整数→16位整数+16位小数→4字节规格化浮点数
	PUSH    7
	PUSH    6
	MOV     R7,#0
	MOV     R6,#0
	ACALL   DIV16
	MOV     3,R7
	MOV     7,R6
	POP     5
	POP     6       	;整数部分在R5 R6中,小数部分在R7 R3中
	MOV     R4,#90H
	MOV     R2,#32
DIV16L: MOV     A,R5
	JB      ACC.7,NMLDN
	MOV     A,R3
	ADD     A,R3
	MOV     R3,A
	LCALL   H0      	;左移R5	R6 R7 R3
	DEC     R4
	DJNZ    R2,DIV16L
	MOV     R4,#0
	RET
NMLDN:  MOV     A,R3
	JNB     ACC.7,DIVRT
	LCALL   INC3
	MOV     A,R5
	JNZ     DIVRT
	INC     R4
DIVRT:  ANL     5,#7FH  	;结果(正数)在R4 R5 R6	R7中
	RET
DIV24:  CLR     A       	;累加值(被除数)在R4 R5 R6 R7中,除数在R2 R3中
	MOV     B,#24   	;计数器
LXP:    LCALL   SHIF
	XCH     A,R4
	RLC     A
	XCH     A,R4
	RLC     A
	JNC     LXP1
	ACALL   SUB2Y   	;CY=1 够减
	SJMP    DIV0
LXP1:   ACALL   SUB2Y
	JNC     DIV0    	;CY=0 够减
	XCH     A,R4
	ADD     A,R3
	XCH     A,R4
	ADDC    A,R2    	;不够减则恢复被除数,本位商0
	SJMP    DIV1
DIV0:   INC     R7      	;本位商1
DIV1:   DJNZ    B,LXP
	XCH     A,R4
	CLR     C
	RLC     A
	XCH     A,R4
	RLC     A
	JC      GINC
	ACALL   SUB2Y
	JNC     GINC
RET3:   MOV     R4,#0
        RET             	;结果在R4(=0)R5 R6 R7(整数)中
GINC:   MOV     R0,#7   	;四舍五入,商增1
INC3A:  INC     @R0
	CJNE    @R0,#0,RET3
	DEC     R0
	SJMP    INC3A
SUB2Y:  CLR     C       	;减去除数子程序
	XCH     A,R4
	SUBB    A,R3
	XCH     A,R4
	SUBB    A,R2
	RET
;================================================
END	
;================================================	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -