【精华】PIC16F877单片机运算子程序

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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 ACCA L O,0 ;ACCB和ACCA低半字节相加

ADDWF ACCB L O

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.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

相关文档
最新文档