📄 pic16f877.txt
字号:
INCF EXPB
ADD3 CLRF ACCCHI ;和(差)规格化
CLRF ACCCLO
CALL F_norm
RETURN ;子程序返回
ADD2 BCF STATUS,C &n
3楼: 参与讨论
作者: 小村之恋 于 2003-12-30 203800 发布:
--------------------------------------------------------------------------------
浮点数除法子程序
2.3.3 浮点数除法子程序
以下为浮点数除法子程序清单。
LIST p=16F877
INCLUDE p16F877.inc
ACCALO EQU 20 ;存放除数的尾数
ACCAHI EQU 21
EXPA EQU 22 ;存放除数的阶码
ACCBLO EQU 23 ;存放被除数的尾数和商的尾数
ACCBHI EQU 24
EXPB EQU 25 ;存放被除数和商的阶码
ACCCLO EQU 26 ;存放余数
ACCCHI EQU 27
ACCDLO EQU 28 ;临时寄存器
ACCDHI EQU 29 ;临时寄存器
TEMP EQU 2A ;临时寄存器
TEMP1 EQU 30 ;临时寄存器
TIMES EQU 31 ;临时寄存器
SIGN EQU 2B ;存放商的符号
COUNT EQU 2F ;临时寄存器
ACCEHI EQU 30 ;临时寄存器
ACCELO EQU 31 ;临时寄存器
ORG 0X0000
START GOTO MAIN
ORG 0X0100
;浮点数除法子程序,入口地址(ACCB、EXPB)(ACCA、EXPA),出口地址ACCB、EXPB
F_div CALL S_SIGN ;确定商的符号,并将负数取补
CLRF ACCCHI ;初始化ACCC寄存器
CLRF ACCCLO
CALL F_norm ;规格化ACCB
CLRF ACCCLO
CLRF ACCCHI
CLRF TIMES
MOVF ACCAHI ;除数为零?
BTFSS STATUS,Z
GOTO FD0 ;否,求商
MOVF ACCALO
BTFSC STATUS,Z
RETLW 01 ;是,返回
FD0 CALL NEG_A ;除数取补
FD1 MOVF ACCBHI,0 ;ACCBHI送ACCDLO
MOVWF ACCDLO
CALL D_add1 ;被除数尾数大于除数尾数?
BTFSS STATUS,C
GOTO FD2
RRF1 BCF STATUS,C ;是,被除数右移规格化,直到小于除数为止
RRF ACCBHI
RRF ACCBLO
INCF TIMES
RRF ACCCHI
BCF STATUS,C
GOTO FD1
FD2 CALL DDIV ;否,调用双字节除法子程序,求商的尾数
MOVF TIMES,0 ;根据右移规格化次数调整ACCB阶码
ADDWF EXPB
MOVF EXPA,0 ;求商的阶码
SUBWF EXPB
CALL F_norm ;商规格化
BTFSC SIGN,7 ;商为负?
CALL NEG_B ;是,取补
CALL &
4楼: 参与讨论
作者: 小村之恋 于 2003-12-30 203900 发布:
--------------------------------------------------------------------------------
2.4 定点数与浮点数转换程序
2.4.1 定点数转换成浮点数
本子程序的功能是将双字节定点整数(十六进制)转换为3字节浮点数,其转换数值范围:-32768~32767,入口条件和出口条件如下:
入口条件:ACCBHI、ACCBLO
出口条件:ACCBHI、ACCBLO、EXPB
以下为定点整数转换成浮点数的程序清单。
LIST p=16F877
INCLUDE p16F877.inc
ACCBLO EQU 23 ;存放定点整数和转换后浮点数的尾数
ACCBHI EQU 24
EXPB EQU 25 ;存放转换后浮点数的阶码
ACCCLO EQU 26 ;临时寄存器
ACCCHI EQU 27 ;临时寄存器
ACCDLO EQU 28 ;临时寄存器
ACCDHI EQU 29 ;临时寄存器
SIGN EQU 2B ;存放被转换数的符号
ORG 0X0000
START GOTO MAIN
ORG 0X0100
;双字节定点整数到浮点数转换子程序
DtoF CLRF SIGN ;根据被转换数确定结果的符号,对负数取补
BTFSS ACCBHI,7
GOTO INTF1
BSF SIGN,7
CALL NEG_B
INTF1 MOVLW .15 ;初始化EXPB
MOVWF EXPB
CLRF ACCCHI
CLRF ACCCLO
CALL F_norm ;对ACCB进行规格化
BTFSS SIGN,7 ;结果为负?
GOTO DtoF1
CALL NEG_B ;是,求补
DtoF1 RETURN
;浮点数规格化子程序
F_norm MOVF ACCBHI ;ACCB=0?
BTFSS STATUS,Z
GOTO C_norm
MOVF ACCBLO
BTFSC STATUS,Z
RETLW 0 ;是,不需规格化,返回
C_norm BTFSC ACCBHI,7 ;否。ACCB为负?
GOTO C_norm2
C_norm1 BTFSC ACCBHI,6 ;为正。规格化完毕?
RETLW 0 ;ACCBHI.6=1,规格化结束
CALL SHFTSL ;否。ACCB左移
DECF EXPB ;EXPB减1
GOTO C_norm1 ;重新判断规格化完毕否?
C_norm2 BTFSS ACCBHI,6 ;ACCB为负。规格化完毕否?
RETLW 0 ;ACCBHI.6=0,规格化结束
BCF STATUS,C
CALL SHFTSL ;否,ACCB左移
BSF ACCBHI,7 ;加符号
DECF EXPB ;EXPB减1
GOTO C_norm2 ;重新判断规格化完毕否?
SHFTSL BCF STATUS ,C ;ACCB左移子程序
RLF ACCCLO
RLF ACCCHI
RLF ACCBLO
RLF ACCBHI
RETLW 0
【校验举例1】 19531(十进制)
化为十六进制数:4C4BH
结果:4C4B0FH
【校验举例2】 2622(十进制)
化为十六进制数: 0A3EH
结果:51F00CH
【例程】
MAIN MOVLW 0X4B ;被转换数4C
5楼: 参与讨论
作者: 小村之恋 于 2003-12-30 204000 发布:
--------------------------------------------------------------------------------
2.5 码制转换程序设计
2.5.1 双字节定点数至5位BCD码转换程序
入口条件:ACCBHI、ACCBLO
出口条件:ACCCHI低半字节、ACCCLO、ACCDHI
以下为双字节定点数至5位BCD码转换程序清单。
LIST p=16F877
INCLUDE p16F877.inc
ACCBLO EQU 23 ;存放被转换的双字节整数低8位
ACCBHI EQU 24 ;存放被转换的双字节整数高8位
ACCCLO EQU 26 ;存放5位BCD码
ACCCHI EQU 27
ACCDLO EQU 28
ACCDHI EQU 29
TEMP EQU 2A ;临时寄存器
SIGN EQU 2B ;被转换数符号寄存器
ORG 0X0000
START GOTO MAIN
ORG 0X0100
;双字节数至BCD码子程序
BtoBCD CLRF SIGN ;初始化符号寄存器
BTFSS ACCBHI,7 ;被转换数为负?
GOTO LOOP1 ;否,转BtoBCD
BSF SIGN,7 ;是,存符号
CALL NEG_B ;ACCB取补
LOOP1 BCF STATUS,C ;清进位位
MOVLW .16 ;移位计数器赋初值
MOVWF COUNT
CLRF ACCCHI ;初始化出口寄存器
CLRF ACCCLO
CLRF ACCDHI
LOOP16 RLF ACCBLO ;ACCB左移一位至出口寄存器
RLF ACCBHI
RLF ACCDHI
RLF ACCCLO
RLF ACCCHI
DECFSZ COUNT ;移位计数器=0?
GOTO ADJDEC ;否,转ADJDEC
RETLW 0 ;是,返回
ADJDEC MOVLW ACCDHI ;指针指向ACCDHI
MOVWF FSR
CALL ADJBCD ;调用BCD码校正子程序
MOVLW ACCCLO ;指针指向ACCCLO
MOVWF FSR
CALL ADJBCD ;调用BCD码校正子程序
MOVLW ACCCHI ;指针指向ACCCHI
MOVWF FSR
CALL ADJBCD ;调用BCD码校正子程序
GOTO LOOP16 ;ACCB重新左移
; BCD码校正子程序
ADJBCD MOVLW 00X03 ;LSD+37?
ADDWF INDF,0
MOVWF TEMP
BTFSC TEMP,3
MOVWF INDF ;是,LSD=LSD+3
MOVLW 0X30 ;否,MSD+37?
ADDWF INDF,0
MOVWF TEMP
BTFSC TEMP,7
MOVWF INDF ;是,MSD=MSD+3
RETLW 0 ;返回
【校验举例1】 -23808(十进制)
化为十六进制数:A300
结果:023808(BCD),SIGN=80
【校验举例2】 12306(十进制)
化为十六进制数: 3012
结果:012306(BCD),SIGN=00
【例程】
MAIN MOVLW
6楼: 参与讨论
作者: 小村之恋 于 2003-12-30 204100 发布:
--------------------------------------------------------------------------------
2.6 定点数开方子程序
2.6 定点数开方子程序
从数值计算方法可知,方程G(X)=0可以由牛顿迭代法来求解。牛顿迭代法的一个重要应用就是开平方,就是通过对以下方程求解得到M的平方根:
函数G(X)在X0点用一阶泰勒级数展开可得:
如果Y是方程G(X)=0的根,那么G(Y)=0,即:
忽略高阶项,而只取前两项,就可以得到根Y的近似值,即
把此方程写成离散形式的迭代方程为:
又因为: ,所以 ,代入迭代方程可得:
这里M的平方根初值取M2。如果在此之前知道M的平方根的范围,则可以取一个比M2更好的初值开始迭代,可以减少迭代的次数。
如果被开方数是定点数格式,代入的迭代初值也是定点数格式,并且用定点除法(定点数的除2操作可以由右移一位得到)和定点加法进行迭代运算,则就是定点数开方。
定点数开方只能得到结果的整数部分,如代入FFFFH和FF10H的开方结果都是一样的,为FFH。如果想要得到比较精确的结果,可以先对被开方数乘以一个系数,待得到结果后,再除以相应的系数。如果被开方数太大,则不能使用此法,若想得到比较精确的结果,可以采用后面介绍的“浮点数开方”。
以下为定点数开方的程序清单(其中包含校验程序部分)。该程序中包含定点数加法程序和定点数除法程序。
LIST p=16F877
INCLUDE p16F877.inc
;
;此子程序是求16位二进制数平方根的子程序,需要调用1616位除法子程序和
;加法子程序,虽然前面有了,但标号有些不同,为了易于阅读和理解,也把它列在后面。
;入口条件:16位二进制数存放在NUMHI和NUMLO单元中。
;出口条件:8位二进制数存放在SQRTLO单元中。
;迭代次数由LUPCNT的地址值决定。
;用指令CALL SQRT实现定点数开方程序调用
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -