社区
单片机/工控
帖子详情
PIC专业人事进~外行自重
zhoujie19820204
2004-10-28 03:37:39
求PIC的32位乘除法算法,小弟的邮箱是:zhoujie19820204@hotmail.com
工作中郁闷了,想起了大学的好伴侣,希望这次CSDN不要让我失望啊~~~
...全文
393
17
打赏
收藏
PIC专业人事进~外行自重
求PIC的32位乘除法算法,小弟的邮箱是:zhoujie19820204@hotmail.com 工作中郁闷了,想起了大学的好伴侣,希望这次CSDN不要让我失望啊~~~
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
17 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
kite079
2004-12-11
打赏
举报
回复
楼上的都是高手,可否交个朋友,我是PIC初学者,我们现在接触到了18系列的!
我的QQ:79282846
CopperLau
2004-12-07
打赏
举报
回复
强啊。看到头晕啊~!@
ccjlolxl
2004-12-01
打赏
举报
回复
你好象学的和我是一本书啊
FIFO2003
2004-12-01
打赏
举报
回复
up
FWXCY
2004-11-30
打赏
举报
回复
汗^^
晕掉了~~~
ldqmoon
2004-10-30
打赏
举报
回复
楼上的大哥强啊.
www.goldenchip.com一个讨论pic的地方,没仔细看过,感觉不错.
icesnows
2004-10-29
打赏
举报
回复
ok
icesnows
2004-10-29
打赏
举报
回复
4 定点数与浮点数转换程序
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 ;被转换数4C4BH送ACCB
MOVWF ACCBLO
MOVLW 0X4C
MOVWF ACCBHI
CALL DtoF ;调用定点数至浮点数转换子程序
END
icesnows
2004-10-29
打赏
举报
回复
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 NEG_A ;除数还原
RETURN ;浮点数除法完成,返回
;***********双字节纯小数除法子程序***************
DDIV MOVLW 0X0F ;初始化ACCDHI
MOVWF ACCDHI
DV1 BCF STATUS,C
RLF ACCCLO ;左移商
RLF ACCCHI
RLF ACCBLO ;左移余数
RLF ACCBHI
MOVF STATUS,0 ;暂存STATUS寄存器
MOVWF ACCDLO
MOVF ACCBHI,0 ;ACCBHI送TEMP1
MOVWF TEMP1
MOVF ACCALO,0 ;ACCB-ACCA
ADDWF ACCBLO,0
MOVWF TEMP
BTFSC STATUS,C
INCF TEMP1
MOVF ACCAHI,0
ADDWF TEMP1,0
BTFSC ACCDLO,0 ;左移余数时移出来的数为1?
GOTO DV2
TESTC BTFSS STATUS,C ;是,再判断ACCB尾数是否大于ACCA
GOTO DV3
DV2 MOVWF ACCBHI ;是,余数送ACCB
MOVF TEMP,0
MOVWF ACCBLO
INCF ACCCLO ;商加1
DV3 DECFSZ ACCDHI ;商求取完毕?
GOTO DV1
MOVF ACCCHI,0 ;是,将商送ACCB
MOVWF ACCBHI
MOVF ACCCLO,0
MOVWF ACCBLO
RETLW 00
;**********本子程序用于判断比较ACCB与ACCA的大小**********
D_add1 MOVF ACCALO,0 ;加数、被加数低半字节相加
ADDWF ACCBLO,0
BTFSC STATUS,C ;有进位?
INCF ACCDLO ;ACCD低半字节加1
MOVF ACCAHI,0 ;ACCAHI+ACCDLO
ADDWF ACCDLO
RETLW 0 ;子程序返回
;****************************************
SETUP MOVLW .15
MOVWF TEMP
MOVF ACCBHI,0
MOVWF ACCDHI
MOVF ACCBLO,0
MOVWF ACCDLO
CLRF ACCBHI
CLRF ACCBLO
RETLW 0
;*************** ACCA取补子程序*************
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否,ACCAHI直接取反
RETLW 0
;********* ACCB取补子程序*************
NEG_B DECF ACCBLO ;ACCBLO取反加1
COMF ACCBLO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCBHI ;有,ACCBHI减1,再取反
COMF ACCBHI ;否,ACCBHI直接取反
RETLW 0
;*********浮点乘除法运算确定结果符号子程序**********
S_SIGN MOVF ACCAHI,0 ;ACCAHI异或ACCBHI,结果送SIGN单元
XORWF ACCBHI,0
MOVWF SIGN
BTFSS ACCBHI,7 ;ACCB为负?
GOTO CHEK_A ;否,检查ACCA
COMF ACCBLO ;是,ACCB取补
INCF ACCBLO
BTFSC STATUS,Z
DECF ACCBHI
COMF ACCBHI
CHEK_A BTFSC ACCAHI,7 ;ACCA为负?
CALL NEG_A ;ACCA为负,取补
RETLW 0 ;ACCA和ACCB均为负,返回
;************浮点运算结果规格化子程序***************
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】 0.0019531÷(-0.00016594)=-12.7699
化为十六进制数:4000F8÷A900F4
结果:A1D704
【校验举例2】 0.26222÷3.5025=0.074867
化为十六进制数: 4321FF÷701502
结果:4CA9FD
【例程】
MAIN MOVLW 0X21 ;被除数的尾数4321H送ACCB
MOVWF ACCBLO
MOVLW 0X43
MOVWF ACCBHI
MOVLW 0XFF ;被除数的阶码FFH送EXPB
MOVWF EXPB
MOVLW 0X15 ;除数尾数7015H送ACCA
MOVWF ACCALO
MOVLW 0X70
MOVWF ACCAHI
MOVLW 0X02 ;除数阶码送EXPA
MOVWF EXPA
CALL F_div ;调用浮点数除法子程序,求商
END
vataii
2004-10-29
打赏
举报
回复
没发完,我顶一下。
icesnows
2004-10-29
打赏
举报
回复
3.2 浮点数乘法子程序
以下为浮点数乘法的程序清单。
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20 ;存放乘数尾数
ACCAHI EQU 21
EXPA EQU 22 ;存放乘数阶码
ACCBLO EQU 23 ;存放被乘数尾数和乘积高16位
ACCBHI EQU 24
EXPB EQU 25 ;存放被乘数阶码
ACCCLO EQU 26 ;存放乘积低16位
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_mpy CALL S_SIGN ;求取乘积的符号,并对负数取补
CALL SETUP ;调用子程序将ACCB的值送ACCD
CLRF ACCCHI ;清ACCC
CLRF ACCCLO
MLOOP BCF STATUS,C ;清进位位
RRF ACCDHI ;ACCD右移
RRF ACCDLO
BTFSC STATUS,C ;判断是否需要相加
CALL D_add ;加乘数至ACCB
BCF STATUS,C ;清进位位
RRF ACCBHI ;右移部分乘积
RRF ACCBLO
RRF ACCCHI
RRF ACCCLO
DECFSZ TEMP ;乘法完成否?
GOTO MLOOP ;否,继续循环
MOVF EXPA,0 ;是,乘数与被乘数阶码相加,得积的阶码
ADDWF EXPB
MOVF ACCBHI ;ACCBHI=0?
BTFSS STATUS,Z
GOTO FINUP ;否,转FINUP
MOVF ACCBLO ;ACCB=0?
BTFSS STATUS ,Z
GOTO SHFT08 ;否,只有ACCBHI=0,转SHFT08
MOVF ACCCHI,0 ;ACCB=0,将乘积左移15位
MOVWF ACCBHI
MOVF ACCCLO,0
MOVWF ACCBLO
BCF STATUS,C
RRF ACCBHI
RRF ACCBLO
MOVLW .15 ;乘积阶码减15(十进制数)
SUBWF EXPB
GOTO FINUP
SHFT08 MOVF ACCBLO,0 ;只有ACCBHI=0,乘积左移7位
MOVWF ACCBHI
MOVF ACCCHI,0
MOVWF ACCBLO
BCF STATUS,C
RRF ACCBHI
RRF ACCBLO
MOVLW .7 ;乘积阶码减7
SUBWF EXPB
FINUP CALL F_norm ;对乘积进行规格化
BTFSS SIGN,7 ;确定乘积的符号
GOTO OVER ;为正,乘法结束
COMF ACCCLO ;为负,乘积取补
INCF ACCCLO
BTFSC STATUS,Z
DECF ACCCHI
COMF ACCCHI
BTFSC STATUS,Z
NEG_B DECF ACCBLO
COMF ACCBLO
BTFSC STATUS,Z
DECF ACCBHI
COMF ACCBHI
OVER RETURN ;乘法结束,子程序返回
;********浮点乘除法运算确定结果符号子程序***********
S_SIGN MOVF ACCAHI,0 ;ACCAHI异或ACCBHI,结果送SIGN
XORWF ACCBHI,0
MOVWF SIGN
BTFSS ACCBHI,7 ;ACCB为负?
GOTO CHEK_A ;否,检查ACCA
COMF ACCBLO ;是,ACCB取补
INCF ACCBLO
BTFSC STATUS,Z
DECF ACCBHI
COMF ACCBHI
CHEK_A BTFSC ACCAHI,7 ;ACCA为负?
CALL NEG_A ;ACCA取补
RETURN ;返回
;*********浮点运算结果规格化子程序*************
F_norm MOVF ACCBHI ;ACCB=0?
BTFSS STATUS,Z
GOTO C_norm
MOVF ACCBLO
BTFSC STATUS,Z
RETURN ;是,不需规格化,返回
C_norm BTFSC ACCBHI,7 ;否。ACCB为负?
GOTO C_norm2
C_norm1 BTFSC ACCBHI,6 ;为正。规格化完毕?
RETURN ;ACCBHI.6=1,规格化结束
CALL SHFTSL ;否。ACCB左移
DECF EXPB ;EXPB减1
GOTO C_norm1 ;重新判断规格化完毕否?
C_norm2 BTFSS ACCBHI,6 ;ACCB为负。规格化完毕否?
RETURN ;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
RETURN
【校验举例1】 0.0019531×(-0.00016594)=-0.000000324
化为十六进制数:4000F8×A900F4
结果:A900EB
【校验举例2】 0.26222×3.5025=0.91842
化为十六进制数: 4321FF×701502
结果: 758F00
【例程】
MAIN MOVLW 0X21 ;被乘数的尾数4321H送ACCB
MOVWF ACCBLO
MOVLW 0X43
MOVWF ACCBHI
MOVLW 0XFF ;被乘数的阶码FFH送EXPB
MOVWF EXPB
MOVLW 0X15 ;乘数尾数7015H送ACCA
MOVWF ACCALO
MOVLW 0X70
MOVWF ACCAHI
MOVLW 0X02 ;乘数阶码送EXPA
MOVWF EXPA
CALL F_mpy ;调用浮点数乘法子程序,求积
END
icesnows
2004-10-29
打赏
举报
回复
3 3字节浮点四则运算子程序
3.1 浮点数加(减)法子程序
以下为浮点加(减)运算例程:
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 ;临时寄存器
ORG 0X000
START GOTO MAIN
ORG 0X0100
;**************浮点减法子程序****************
F_sub CALL NEG_A ;求ACCA的补码,将减法转换为补码加法
;***********浮点加法子程序**************
F_add CALL SUBADJ ;调子程序判断EXPB和EXPA的大小
BTFSC STATUS,Z ;参与运算的两个数阶码相等?
GOTO PADD ;是,求尾数的和
BTFSC STATUS,C ;EXPB>EXPA?
CALL F_swap ;是,ACCB与ACCA互换
MOVF EXPA,0 ;否,求取两者的差值
SUBWF EXPB
SCLOOP CALL SHFTSR ;ACCB右移规格化
INCFSZ EXPB ;EXPB=EXPA?
GOTO SCLOOP ;否,继续右移
MOVF EXPA,0 ;是,存和(差)的阶码
MOVWF EXPB
PADD MOVF ACCAHI,0 ;ACCAHI或ACCBHI
IORWF ACCBHI,0
MOVWF SIGN ;存于SIGN寄存器
MOVF ACCBHI,0 ;暂存ACCBHI
MOVWF EXPA
CALL D_add ;尾数相加
BTFSS SIGN,7 ;ACCA和ACCB有负数?
BTFSC ACCBHI,7 ;否,把和的最高位和次高位同时进位?
GOTO ADD2 ;否,转ADD2
BTFSS ACCAHI,7 ;ACCA为负吗?
GOTO ADD3 ;ACCA和ACCB不同时为负,转ADD3
BTFSS EXPA,7 ;是,ACCB为负吗?
GOTO ADD3
BSF STATUS,C ;ACCA和ACCB同为负,带负号右移
RRF ACCBHI
RRF ACCBLO
INCF EXPB
ADD3 CLRF ACCCHI ;和(差)规格化
CLRF ACCCLO
CALL F_norm
RETURN ;子程序返回
ADD2 BCF STATUS,C ;最高位次高位不同时进位,ACCB右移
INCF EXPB
GOTO SHFTR
SHFTSR BCF STATUS,C ;ACCB带符号右移子程序
BTFSC ACCBHI,7
BSF STATUS,C
SHFTR RRF ACCBHI
RRF ACCBLO
RETURN ;子程序返回
;********* ACCB、ACCA互换子程序************
F_swap MOVF ACCAHI,0 ;ACCAHI、ACCBHI互换
MOVWF TEMP
MOVF ACCBHI,0
MOVWF ACCAHI
MOVF TEMP,0
MOVWF ACCBHI
MOVF ACCALO,0 ;ACCALO、ACCBLO互换
MOVWF TEMP
MOVF ACCBLO,0
MOVWF ACCALO
MOVF TEMP,0
MOVWF ACCBLO
MOVF EXPA,0 ;EXPA、EXPB互换
MOVWF TEMP
MOVF EXPB,0
MOVWF EXPA
MOVF TEMP,0
MOVWF EXPB
RETURN
;*************比较EXPB、EXPA大小子程序*************
SUBADJ MOVF EXPA,0 ;EXPA异或EXPB,结果送C_DIV
XORWF EXPB,0
MOVWF C_DIV
MOVF EXPA,0 ;EXPB-EXPA
SUBWF EXPB,0
BTFSS C_DIV,7 ;EXPA和EXPB同号?
RETURN ;是,进位位的值真确反映两者的大小,返回
BTFSS STATUS,C ;否,进位位的值取反
GOTO CHANGEC
BCF STATUS,C
RETURN
CHANGEC BSF STATUS,C
RETURN
;***********浮点数规格化子程序****************
F_norm MOVF ACCBHI ;ACCB=0?
BTFSS STATUS,Z
GOTO C_norm
MOVF ACCBLO
BTFSC STATUS,Z
RETURN ;是,不需规格化,返回
C_norm BTFSC ACCBHI,7 ;否。ACCB为负?
GOTO C_norm2
C_norm1 BTFSC ACCBHI,6 ;为正。规格化完毕?
RETURN ;ACCBHI.6=1,规格化结束
CALL SHFTSL ;否。ACCB左移
DECF EXPB ;EXPB减1
GOTO C_norm1 ;重新判断规格化完毕否?
C_norm2 BTFSS ACCBHI,6 ;ACCB为负。规格化完毕否?
RETURN ;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
RETURN
【校验举例1】 0.0019531+(-0.00016594)=0.00178716
化为十六进制数:4000F8+A900F4
结果:7520F7
【校验举例2】 0.26222+3.5025=3.76478
化为十六进制数: 4321FF+701502
结果:787902
【例程】
MAIN MOVLW 0X21 ;被加数的尾数4321H送ACCB
MOVWF ACCBLO
MOVLW 0X43
MOVWF ACCBHI
MOVLW 0XFF ;被加数的阶码FFH送EXPB
MOVWF EXPB
MOVLW 0X15 ;加数尾数7015H送ACCA
MOVWF ACCALO
MOVLW 0X70
MOVWF ACCAHI
MOVLW 0X02 ;加数阶码送EXPA
MOVWF EXPA
CALL F_add ;调用浮点数加法子程序,求和
END
icesnows
2004-10-29
打赏
举报
回复
2.3 16×16位定点数除法子程序
子程序采用反复的减法算法,除数和被除数分别为16位二进制有符号数(均采用补码表示,第16位为符号位),商为16位二进制有符号数,第16位为符号位。子程序的入口条件和出口条件如下:
入口条件:被除数存放在ACCBHI、ACCBLO单元中;
除数存放在ACCAHI、ACCALO单元中。
出口条件:商存放在ACCBHI、ACCBLO单元中;
余数存放在ACCCHI、ACCCLO单元中。
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20 ;存放除数低8位
ACCAHI EQU 21 ;存放除数高8位
ACCBLO EQU 22 ;存放被除数和商的低8位
ACCBHI EQU 23 ;存放被除数和商的高8位
ACCCLO EQU 24 ;存放余数低8位
ACCCHI EQU 25 ;存放余数高8位
ACCDLO EQU 26 ;临时寄存器
ACCDHI EQU 27 ;临时寄存器
TEMP EQU 28 ;临时寄存器
SIGN EQU 29 ;存放商的符号
ORG 0X0000
START GOTO MAIN
;***16×16位数除法子程序,入口地址ACCB /ACCA,出口地址ACCB ***
ORG 0X0100
D_div CALL S_SIGN ;确定商的符号,并将负数取补
CALL SETUP ;初始化TEMP,将被除数移至ACCD,
;(SETUP子程序请参见16×16位定点数
;乘法子程序SETUP)
INCF TEMP
CLRF ACCCHI ;清余数寄存器
CLRF ACCCLO
DLOOP BCF STATUS,C ;清进位位
RLF ACCDLO ;被除数、余数左移1位
RLF ACCDHI
RLF ACCCLO
RLF ACCCHI
MOVF ACCAHI,0 ;ACCCHI-ACCAHI
SUBWF ACCCHI,0
BTFSS STATUS,Z ;ACCCHI=ACCAHI?
GOTO NOCHK
MOVF ACCALO,0 ;是,ACCCLO-ACCALO
SUBWF ACCCLO,0
NOCHK BTFSS STATUS,C ;ACCC>ACCA?
GOTO NOGO
MOVF ACCALO,0 ;是,余数减除数
SUBWF ACCCLO
BTFSS STATUS,C
DECF ACCCHI
MOVF ACCAHI,0
SUBWF ACCCHI
BSF STATUS,C ;置进位位
NOGO RLF ACCBLO ;商左移1位
RLF ACCBHI
DECFSZ TEMP ;循环完毕?
GOTO DLOOP
BTFSS SIGN,7 ;是,确定商的符号
GOTO DIVOVER ;为正,除法结束,跳转到结束行
COMF ACCCLO ;为负,商和余数分别取补
INCF ACCCLO
BTFSC STATUS,Z
DECF ACCCHI
COMF ACCCHI
CALL NEG_B ;见乘法程序中间NEG_B
DIVOVER RETURN ;子程序返回
;************除法运算确定结果符号子程序*******************
S_SIGN MOVF ACCAHI,0 ;ACCAHI异或ACCBHI,结果送SIGN单元
XORWF ACCBHI,0
MOVWF SIGN
BTFSS ACCBHI,7 ;ACCB为负?
GOTO CHEK_A ;否,检查ACCA
COMF ACCBLO ;是,ACCB取补
INCF ACCBLO
BTFSC STATUS,Z
DECF ACCBHI
COMF ACCBHI
CHEK_A BTFSC ACCAHI,7 ;ACCA为负?
CALL NEG_A ;ACCA为负,取补(NEG_A子程序请参见
;16×16位定点数乘法子程序NEG_A)
RETURN ;ACCA和ACCB均为负,返回
【校验举例1】 -23775÷(-240)=99.0625(十进制)
化为十六进制数:A321H÷FF10H;
结果:(商)0063H,(余数)000FH(十六进制)。
【校验举例2】 769÷3856=0.199429(十进制)
化为十六进制数:0301H÷0F10H;
结果:(商)0000H,(余数)0301H(十六进制)。
【例程】
MAIN MOVLW 0X01 ;被除数0301H送ACCB
MOVWF ACCBLO
MOVLW 0X03
MOVWF ACCBHI
MOVLW 0X10 ;除数0F10H送ACCA
MOVWF ACCALO
MOVLW 0X0F
MOVWF ACCAHI
CALL D_div ;调用双字节除法子程序,求商
END
kite079
2004-10-28
打赏
举报
回复
关注之中!
接楼主宝地问一下,PIC16F877与PIC18f6620有何区别?
icesnows
2004-10-28
打赏
举报
回复
2 四则运算子程序
2.1 16×16位定点数加、减法子程序
以下子程序实现2个16×16位有符号数加、减运算,其和或差用一个16位数表示。在子程序中,减法是通过对减数求补后再与被减数相加来实现的。因此,当程序从D_sub进入子程序时为减法,当从D_add进入子程序时为加法。
子程序的入口条件和出口条件如下:
入口条件:16位被加数/被减数存放在ACCBHI、ACCBLO中;
16位加数/减数存放在ACCAHI、ACCALO中;
出口条件:16位和/差存放在ACCBHI和ACCBLO中。
以下为16×16位有符号数加、减法子程序。
注意:在以下注释程序中均以ACCA代替ACCAHI、ACCALO两个字节,以ACCB代替ACCBHI、ACCBLO两个字节。
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20 ;存放加数或减数低8位
ACCAHI EQU 21 ;存放加数或减数高8位
ACCBLO EQU 23 ;存放被加数或被减数低8位
ACCBHI EQU 24 ;存放被加数或被减数高8位
ORG 0X0000
START GOTO MAIN
;***双字节减法子程序,入口地址ACCB-ACCA,出口地址ACCB***
D_sub CALL NEG_A ;求ACCA的补码
;***双字节加法子程序,入口地址ACCB+ACCA,出口地址ACCB***
D_add MOVF ACCALO,0 ;ACCB和ACCA低半字节相加
ADDWF ACCBLO
BTFSC STATUS,C ;有进位否?
INCF ACCBHI ;有,ACCB高字节加1,再加ACCAHI
MOVF ACCAHI,0 ;ACCA、ACCB高半字节相加
ADDWF ACCBHI
RETURN ;子程序返回
;************** ACCA取补子程序*****************
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否则ACCAHI直接取反
RETURN ;子程序返回
【校验举例1】 19531+(-16594)=2937(十进制)
化为十六进制数:4C46H+BF2EH
结果:0B79H(十六进制)
【校验举例2】 26222+3000=29222(十进制)
化为十六进制数: 666EH+0BB8H
结果:7226H(十六进制)
【例程】
MAIN MOVLW 0X6E ;被加数666EH送ACCB
MOVWF ACCBLO
MOVLW 0X66
MOVWF ACCBHI
MOVLW 0XB8 ;加数BB8H送ACCA
MOVWF ACCALO
MOVLW 0X0B
MOVWF ACCAHI
CALL D_add ;调用双字节加法子程序,求和
END
2.2 16×16位定点数乘法子程序
子程序采用部分积右移加法实现乘法运算。乘数和被乘数分别为16位二进制有符号数(均采用补码表示,第16位为符号位),积为32位二进制有符号数,第32位为符号位。子程序的入口条件和出口条件如下:
入口条件:被乘数存放在ACCBHI和ACCBLO单元中,
乘数存放在ACCAHI和ACCALO单元中。
出口条件:积存放在ACCBHI、ACCBLO、ACCCHI和ACCCLO单元中,ACCB为高16位,ACCC为低16位。
以下为本子程序的程序清单:
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20 ;存放乘数低8位
ACCAHI EQU 21 ;存放乘数高8位
ACCBLO EQU 23 ;存放被乘数低8位和乘积第16~23位
ACCBHI EQU 24 ;存放被乘数高8位和乘积第24~31位
ACCCLO EQU 26 ;存放乘积低8位
ACCCHI EQU 27 ;存放乘积高8位
ACCDLO EQU 28 ;临时寄存器
ACCDHI EQU 29 ;临时寄存器
TEMP EQU 2A ;临时寄存器
SIGN EQU 2B ;存放乘积的符号
ORG 0X0000
START GOTO MAIN
;***16×16位乘法子程序,入口地址ACCB×ACCA,出口地址ACCB和ACCC ***
ORG 0X0100
D_mpy CALL S_SIGN ;求取乘积的符号,并对负数取补
CALL SETUP ;调用子程序,将ACCB的值送ACCD
INCF TEMP
CLRF ACCCHI ;清ACCC
CLRF ACCCLO
MLOOP BCF STATUS,C ;清进位位
RRF ACCDHI ;ACCD右移
RRF ACCDLO
BTFSC STATUS,C ;判断是否需要相加
CALL D_add ;加乘数至ACCB,见加法程序
BCF STATUS,C ;清进位位
RRF ACCBHI ;右移部分乘积
RRF ACCBLO
RRF ACCCHI
RRF ACCCLO
DECFSZ TEMP ;乘法完成否?
GOTO MLOOP ;否,继续求乘积
BTFSS SIGN,7 ;是,确定乘积的符号
GOTO OVER ;为正,乘法结束
COMF ACCCLO ;为负,乘积取补
INCF ACCCLO
BTFSC STATUS,Z
DECF ACCCHI
COMF ACCCHI
BTFSC STATUS,Z
NEG_B DECF ACCBLO ;
COMF ACCBLO
BTFSC STATUS,Z
DECF ACCBHI
COMF ACCBHI
OVER RETURN ;子程序返回
;****************************************
SETUP MOVLW .15 ;初始化TEMP寄存器
MOVWF TEMP
MOVF ACCBHI,0 ;ACCB送ACCD
MOVWF ACCDHI
MOVF ACCBLO,0
MOVWF ACCDLO
CLRF ACCBHI ;清ACCB
CLRF ACCBLO
RETURN ;子程序返回
;*******乘法运算确定结果符号判断子程序******
S_SIGN MOVF ACCAHI,0 ;ACCAHI异或ACCBHI,结果送SIGN单元
XORWF ACCBHI,0
MOVWF SIGN
BTFSS ACCBHI,7 ;ACCB为负吗?
GOTO CHEK_A ;否,检查ACCA
CALL NEG_B ;是,求取ACCB绝对值
CHEK_A BTFSC ACCAHI,7 ;ACCA为负吗?
CALL NEG_A ;ACCA为负,求取ACCA绝对值,
;见双字节加法程序
RETURN ;ACCA和ACCB均为正,返回
【校验举例1】:-24555×(-7391)=181486005(十进制)
化为十六进制数:A015H×E321H
结果:0AD141B5H(十六进制)
【校验举例2】 16405×13089=214725045(十进制)
化为十六进制数:4015H×3321H
结果:0CCC71B5H(十六进制)
【例程】
MAIN MOVLW 0X15 ;被乘数4015H送ACCB
MOVWF ACCBLO
MOVLW 0X40
MOVWF ACCBHI
MOVLW 0X21 ;乘数3321H送ACCA
MOVWF ACCALO
MOVLW 0X33
MOVWF ACCAHI
CALL D_mpy ;调用双字节乘法子程序,求积
END
icesnows
2004-10-28
打赏
举报
回复
PIC16F877 运算子程序
1 PIC16F877汇编语言程序主体框架
以下是一个典型的程序结构:
;***************程序说明区*******************
LIST p=16f877 ;指定微控制器型号和文件输出格式
INCLUDE p16f877.inc ;读入MPLAB提供的定义文件P16F877.INC
;***片内RAM常用资源、变量定义和相应的说明*********
ACCALO EQU 20 ;存放加数或减数低8位
ACCAHI EQU 21 ;存放加数或减数高8位
ACCBLO EQU 23 ;存放被加数或被减数低8位
ACCBHI EQU 24 ;存放被加数或被减数高8位
S_W EQU 25 ;栈存W寄存器值
S_STATUS EQU 26 ;栈存STATUS寄存器值
;****************芯片复位矢量*******************
ORG 0X0000 ;由于PIC16F877芯片复位矢量在0000h单
;元,所以常在0000h单元处放置一条跳转
;指令,使单片机复位后能跳过中断矢量,
;直接执行主程序
START GOTO MAIN
;******************中断矢量**********************
ORG 0X0004 ;由于PIC16F877的中断矢量为0004h,所以
;当中断开放时, 需在此处加入中断程序,
;使单片机能在中断到来时及时进入相应的
;中断服务程序。为了可靠起见,如果单片
;机不使用中断,则常常在该中断矢量处放
;置RETFIE指令,可以使单片机不会因
;干扰产生误中断而导致程序跑飞
CALL PUSH ;调用保护现场子程序
BTFSS PIR1,ADIF
CALL AD ;若AD中断到,则执行中断服务程序
…….. ;此处可放多个中断子程序,并以软件安排
;中断优先级
CALL POP ;恢复中断现场
RETFIE ;中断返回
;****************主程序区*****************
ORG 0X0100 ;将主程序、子程序和中断服务程序等存放
;在0100h单元之后,在中断矢量和主程序
;区之间预留一些存储单元,以便写入判
;跳指令和一些必要的现场保护程序。此外
;用户也可以根据实际需要,使主程序从其
;它地址开始存放
MAIN BSF STATUS,RP0 ;选择存储体1
MOVLW 0XFF ;定义RA口为输入端口
MOVWF TRISA
BCF STATUS,RP0 ;选择存储体0
MOVLW 0X04 ;初值化ACCALO
MOVWF ACCALO
CALL DX ;调用DX子程序
LOOP1 …… ;任务1
…… ;任务2
:
:
:
GOTO LOOP1 ;反复执行任务一和任务二等
;***************子程序区*********************
DX MOVF ACCALO,0 ;ACCB和ACCA低半字节相加
ADDWF ACCBLO
RETURN ;子程序返回
;****************************************
PUSH MOVWF S_W ;保护W寄存器
MOVF STATUS,0 ;保护STATUS寄存器
MOVWF S_STATUS
RETURN ;子程序返回
;****************************************
POP MOVF S_STATUS,0 ;恢复STATUS寄存器
MOVWF STATUS
MOVF S_W,0 ;恢复W寄存器
RETURN ;子程序返回
;****************中断服务子程序区************************
AD BCF PIR1,ADIF ;清AD中断标志
…… ;中断服务主体程序
RETURN ;子程序返回
END
icesnows
2004-10-28
打赏
举报
回复
????不会
中国络网全站Ver0203
面预览:http://www.xy20.net/
pic
/home.gif 软件介绍 一套虚拟主机程序,全部由后台程序控制完成更新。适合是做代理而没有程序的人。 其他的可以参考http://www.xy20.net
【转】
PIC
单片机入门笔记(新手学
PIC
必看)——基于
PIC
16F886
学习
PIC
单片机的目的是打算做一款433M无线开关,之前学习过51与AVR单片机,对8位单片机有一些基础,不过
PIC
单片机还是第一次接触,先从入门开始吧!入门实验最经典的是点亮一只LED了,这次也它为例走一遍
PIC
开发的整个流程。虽然C语言已成主流,由于
PIC
单片机汇编指令只有35条,记忆容易,这次就从非主流开始! 一、准备工作 1. 在二手市场买来一本【
PIC
单片机原理与应用】第4版。 2. 在淘宝买来一个
PIC
的下载仿真器【
PIC
kit3】。 3. 从废旧设备上面拆下一片
PIC
16F886的28脚单片机
PIC
单片机入门笔记(新手学
PIC
必看)——基于
PIC
16F886
学习
PIC
单片机的目的是打算做一款433M无线开关,之前学习过51与AVR单片机,对8位单片机有一些基础,不过
PIC
单片机还是第一次接触,先从入门开始吧!入门实验最经典的是点亮一只LED了,这次也它为例走一遍
PIC
开发的整个流程。虽然C语言已成主流,由于
PIC
单片机汇编指令只有35条,记忆容易,这次就从非主流开始!一、准备工作1. 在二手市场买来一本【
PIC
单片机原理与应用】第4版。2. 在淘宝买...
PIC
16F1933 EEPROM操作
PIC
16F1933内部有256Byte大小的数据EEPROM用于存储数据,如图1所示图1 EEPROM大小 通过
PIC
16F1933数据手册可以看到,EEPROM的地址为00H~FFH,如图2所示图2
PIC
16F1933数据手册EEPROM部分 操作步骤举例:1、写操作,使用”
pic
.h”库函数中自带的操作函数对EEPROM
进
行写操作1. eeprom_write(0x81,(...
PIC
单片机入门_
PIC
C头文件介绍
PIC
C支持下的C程序代码中一定要包含
pic
.h头文件,该文件安装在HT-
PIC
\include目录下。它是很多头文件的集合,C编译器在
pic
.h中根据用户选择的芯片自动载入相应的其它头文件,例如用户选择的芯片是
PIC
16F877,则
pic
.h会把
pic
1687x.h载入;例如用户选择的芯片是
PIC
16F877A,则
pic
.h会把
pic
168xa.h载入。载入的头文件中其实是声明芯片的寄存器和一些
单片机/工控
27,510
社区成员
28,796
社区内容
发帖
与我相关
我的任务
单片机/工控
硬件/嵌入开发 单片机/工控
复制链接
扫一扫
分享
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章