📄 pic16f877.txt
字号:
PIC16f87x 各种子程序
来源:21ic 作者:小村之恋 栏目:单片机
PIC16f87x 各种子程序
各位,我刚买了一本书,内有很多子程序,特贴出来大家分想
PIC16F877 运算子程序
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
2.2 四则运算子程序
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 ;存
1楼: 参与讨论
作者: 小村之恋 于 2003-12-30 203600 发布:
--------------------------------------------------------------------------------
16×16位定点数除法子程序
2.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 ;ACCCACCA?
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
MOV
2楼: 参与讨论
作者: 小村之恋 于 2003-12-30 203700 发布:
--------------------------------------------------------------------------------
3字节浮点四则运算子程序
2.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 ;EXPBEXPA?
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -