📄 定点数开方子程序.txt
字号:
;****************************************
;【校验举例】 被开方数2910H(十六进制)
; 10512(十进制)
; 求得平方根:66H(十六进制)
; 102(十进制)
; 6 定点数开方子程序
; 从数值计算方法可知,方程G(X)=0可以由牛顿迭代法来求解。牛顿迭代法的
;一个重要应用就是开平方,就是通过对以下方程求解得到M的平方根:
;函数G(X)在X0点用一阶泰勒级数展开可得:
;如果Y是方程G(X)=0的根,那么G(Y)=0,即:
;忽略高阶项,而只取前两项,就可以得到根Y的近似值,即
;把此方程写成离散形式的迭代方程为:
;又因为: ,所以 ,代入迭代方程可得:
;这里M的平方根初值取M/2。如果在此之前知道M的平方根的范围,则可以取一个
;比M/2更好的初值开始迭代,可以减少迭代的次数。
;如果被开方数是定点数格式,代入的迭代初值也是定点数格式,并且用定点除法
;(定点数的除2操作可以由右移一位得到)和定点加法进行迭代运算,则就是
;定点数开方。
;定点数开方只能得到结果的整数部分,如代入FFFFH和FF10H的开方结果都是一样
;的,为FFH。如果想要得到比较精确的结果,可以先对被开方数乘以一个系数,
;待得到结果后,再除以相应的系数。如果被开方数太大,则不能使用此法,
;若想得到比较精确的结果,可以采用后面介绍的“浮点数开方”。
;以下为定点数开方的程序清单(其中包含校验程序部分)。该程序中包含定点数
;加法程序和定点数除法程序。
LIST p=16f877
INCLUDE p16f877.inc
;****************************************
;此子程序是求16位二进制数平方根的子程序,需要调用16/16位除法子程序和
;加法子程序,虽然前面有了,但标号有些不同,为了易于阅读和理解,也把它列在后面。
;入口条件:16位二进制数存放在NUMHI和NUMLO单元中。
;出口条件:8位二进制数存放在SQRTLO单元中。
;迭代次数由LUPCNT的地址值决定。
;用指令CALL SQRT实现定点数开方程序调用
;****************************************
ACCALO EQU 0X20
ACCAHI EQU ACCALO+1
EXPA EQU ACCALO+2
ACCBLO EQU ACCALO+3
ACCBHI EQU ACCALO+4
EXPB EQU ACCALO+5
ACCCLO EQU ACCALO+6
ACCCHI EQU ACCALO+7
ACCDLO EQU ACCALO+8
ACCDHI EQU ACCALO+9
TEMP EQU ACCDHI+1
SIGN EQU ACCDHI+2
SQRTLO EQU ACCALO
SQRTHI EQU ACCAHI
NUMLO EQU ACCDHI+4
NUMHI EQU ACCDHI+5
COUNT EQU ACCDHI+6
;此方法定义的数据块为连续层断,只要
;将第一行改变,就可以将数据整块搬动到
;新的地方,为调试带来方便,是比较推
;崇的一种寄存器定义方法
LUPCNT EQU .10
;****************************************
ORG 0X00
GOTO MAIN
ORG 0X10
;****************************************
INIT MOVLW LUPCNT
MOVWF COUNT
MOVF NUMHI,0
MOVWF SQRTHI
MOVF NUMLO,0
MOVWF SQRTLO
BCF STATUS,C
RRF SQRTHI,1
RRF SQRTLO,1
RETLW 0
;***************16×16位定点数右移子程序***************
DIV2 BCF STATUS,C
RRF ACCBHI,0
MOVWF SQRTHI
RRF ACCBLO,0
MOVWF SQRTLO
RETLW 0
;*********16×16位定点数开方子程序**********
SQRT CALL INIT
SLOOP MOVF NUMLO,0
MOVWF ACCBLO
MOVF NUMHI,0
MOVWF ACCBHI
CALL D_DIVS
CALL D_ADD
CALL DIV2
DECFSZ COUNT,1
GOTO SLOOP
RETURN
;***********16×16位定点整数除法子程序*********
D_DIVS CALL SETUP
CLRF ACCCHI
CLRF ACCCLO
DLOOP BCF STATUS,C
RLF ACCDLO
RLF ACCDHI
RLF ACCCLO
RLF ACCCHI
MOVF ACCAHI,0
SUBWF ACCCHI,0
BTFSS STATUS,Z
GOTO NOCHK
MOVF ACCALO,0
SUBWF ACCCLO,0
NOCHK BTFSS STATUS,C
GOTO NOGO
MOVF ACCALO,0
SUBWF ACCCLO,1
BTFSS STATUS,C
DECF ACCCHI,1
MOVF ACCAHI,0
SUBWF ACCCHI,1
BSF STATUS,C
NOGO RLF ACCBLO
RLF ACCBHI
DECFSZ TEMP
GOTO DLOOP
RETLW 0
;****************************************
SETUP MOVLW .16
MOVWF TEMP
MOVF ACCBHI,0
MOVWF ACCDHI
MOVF ACCBLO,0
MOVWF ACCDLO
CLRF ACCBHI
CLRF ACCBLO
RETLW 0
;**********16×16位定点数取补子程序**************
NEG_A COMF ACCALO,1
INCF ACCALO,1
BTFSC STATUS,Z
DECF ACCAHI,1
COMF ACCAHI,1
RETLW 0
;*************16×16位定点数加法子程序**************
D_ADD MOVF ACCALO,0
ADDWF ACCBLO,1
BTFSC STATUS,C
INCF ACCBHI,1
MOVF ACCAHI,0
ADDWF ACCBHI,1
RETLW 0
MAIN NOP
MOVLW 0X0af
MOVWF NUMHI
MOVLW 0X58
MOVWF NUMLO ;被开方数赋值
CALL SQRT ;调用开方子程序
goto $ ;开方完毕
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -