PIC16F877单片机运算子程序.doc_第1页
PIC16F877单片机运算子程序.doc_第2页
PIC16F877单片机运算子程序.doc_第3页
PIC16F877单片机运算子程序.doc_第4页
PIC16F877单片机运算子程序.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PIC16F877单片机运算子程序1PIC16F877汇编语言程序主体框架以下是一个典型的程序结构:;*程序说明区*LISTp=16f877;指定微控制器型号和文件输出格式INCLUDEp16f877.inc;读入MPLAB提供的定义文件P16F877.INC;*片内RAM常用资源、变量定义和相应的说明*ACCALOEQU20;存放加数或减数低8位ACCAHIEQU21;存放加数或减数高8位ACCBLOEQU23;存放被加数或被减数低8位ACCBHIEQU24;存放被加数或被减数高8位S_WEQU25;栈存W寄存器值S_STATUSEQU26;栈存STATUS寄存器值;*芯片复位矢量*ORG0X0000;由于PIC16F877芯片复位矢量在0000h单;元,所以常在0000h单元处放置一条跳转;指令,使单片机复位后能跳过中断矢量,;直接执行主程序STARTGOTOMAIN;*中断矢量*ORG0X0004;由于PIC16F877的中断矢量为0004h,所以;当中断开放时,需在此处加入中断程序,;使单片机能在中断到来时及时进入相应的;中断服务程序。为了可靠起见,如果单片;机不使用中断,则常常在该中断矢量处放;置RETFIE指令,可以使单片机不会因;干扰产生误中断而导致程序跑飞CALLPUSH;调用保护现场子程序BTFSSPIR1,ADIFCALLAD;若AD中断到,则执行中断服务程序.;此处可放多个中断子程序,并以软件安排;中断优先级CALLPOP;恢复中断现场RETFIE;中断返回;*主程序区*ORG0X0100;将主程序、子程序和中断服务程序等存放;在0100h单元之后,在中断矢量和主程序;区之间预留一些存储单元,以便写入判;跳指令和一些必要的现场保护程序。此外;用户也可以根据实际需要,使主程序从其;它地址开始存放MAINBSFSTATUS,RP0;选择存储体1MOVLW0XFF;定义RA口为输入端口MOVWFTRISABCFSTATUS,RP0;选择存储体0MOVLW0X04;初值化ACCALOMOVWFACCALOCALLDX;调用DX子程序LOOP1;任务1;任务2:GOTOLOOP1;反复执行任务一和任务二等;*子程序区*DXMOVFACCALO,0;ACCB和ACCA低半字节相加ADDWFACCBLORETURN;子程序返回;*PUSHMOVWFS_W;保护W寄存器MOVFSTATUS,0;保护STATUS寄存器MOVWFS_STATUSRETURN;子程序返回;*POPMOVFS_STATUS,0;恢复STATUS寄存器MOVWFSTATUSMOVFS_W,0;恢复W寄存器RETURN;子程序返回;*中断服务子程序区*ADBCFPIR1,ADIF;清AD中断标志;中断服务主体程序RETURN;子程序返回END2四则运算子程序2.11616位定点数加、减法子程序以下子程序实现2个1616位有符号数加、减运算,其和或差用一个16位数表示。在子程序中,减法是通过对减数求补后再与被减数相加来实现的。因此,当程序从D_sub进入子程序时为减法,当从D_add进入子程序时为加法。子程序的入口条件和出口条件如下:入口条件:16位被加数/被减数存放在ACCBHI、ACCBLO中;16位加数/减数存放在ACCAHI、ACCALO中;出口条件:16位和/差存放在ACCBHI和ACCBLO中。以下为1616位有符号数加、减法子程序。注意:在以下注释程序中均以ACCA代替ACCAHI、ACCALO两个字节,以ACCB代替ACCBHI、ACCBLO两个字节。LISTp=16f877INCLUDEp16f877.incACCALOEQU20;存放加数或减数低8位ACCAHIEQU21;存放加数或减数高8位ACCBLOEQU23;存放被加数或被减数低8位ACCBHIEQU24;存放被加数或被减数高8位ORG0X0000STARTGOTOMAIN;*双字节减法子程序,入口地址ACCB-ACCA,出口地址ACCB*D_subCALLNEG_A;求ACCA的补码;*双字节加法子程序,入口地址ACCB+ACCA,出口地址ACCB*D_addMOVFACCALO,0;ACCB和ACCA低半字节相加ADDWFACCBLOBTFSCSTATUS,C;有进位否?INCFACCBHI;有,ACCB高字节加1,再加ACCAHIMOVFACCAHI,0;ACCA、ACCB高半字节相加ADDWFACCBHIRETURN;子程序返回;*ACCA取补子程序*NEG_ACOMFACCALO;ACCALO取反加1INCFACCALOBTFSCSTATUS,Z;低8位有进位吗?DECFACCAHI;有,ACCAHI减1,再取反COMFACCAHI;否则ACCAHI直接取反RETURN;子程序返回【校验举例1】19531+(-16594)=2937(十进制)化为十六进制数:4C46H+BF2EH结果:0B79H(十六进制)【校验举例2】26222+3000=29222(十进制)化为十六进制数:666EH+0BB8H结果:7226H(十六进制)【例程】MAINMOVLW0X6E;被加数666EH送ACCBMOVWFACCBLOMOVLW0X66MOVWFACCBHIMOVLW0XB8;加数BB8H送ACCAMOVWFACCALOMOVLW0X0BMOVWFACCAHICALLD_add;调用双字节加法子程序,求和END2.21616位定点数乘法子程序子程序采用部分积右移加法实现乘法运算。乘数和被乘数分别为16位二进制有符号数(均采用补码表示,第16位为符号位),积为32位二进制有符号数,第32位为符号位。子程序的入口条件和出口条件如下:入口条件:被乘数存放在ACCBHI和ACCBLO单元中,乘数存放在ACCAHI和ACCALO单元中。出口条件:积存放在ACCBHI、ACCBLO、ACCCHI和ACCCLO单元中,ACCB为高16位,ACCC为低16位。以下为本子程序的程序清单:LISTp=16f877INCLUDEp16f877.incACCALOEQU20;存放乘数低8位ACCAHIEQU21;存放乘数高8位ACCBLOEQU23;存放被乘数低8位和乘积第1623位ACCBHIEQU24;存放被乘数高8位和乘积第2431位ACCCLOEQU26;存放乘积低8位ACCCHIEQU27;存放乘积高8位ACCDLOEQU28;临时寄存器ACCDHIEQU29;临时寄存器TEMPEQU2A;临时寄存器SIGNEQU2B;存放乘积的符号ORG0X0000STARTGOTOMAIN;*1616位乘法子程序,入口地址ACCBACCA,出口地址ACCB和ACCC*ORG0X0100D_mpyCALLS_SIGN;求取乘积的符号,并对负数取补CALLSETUP;调用子程序,将ACCB的值送ACCDINCFTEMPCLRFACCCHI;清ACCCCLRFACCCLOMLOOPBCFSTATUS,C;清进位位RRFACCDHI;ACCD右移RRFACCDLOBTFSCSTATUS,C;判断是否需要相加CALLD_add;加乘数至ACCB,见加法程序BCFSTATUS,C;清进位位RRFACCBHI;右移部分乘积RRFACCBLORRFACCCHIRRFACCCLODECFSZTEMP;乘法完成否?GOTOMLOOP;否,继续求乘积BTFSSSIGN,7;是,确定乘积的符号GOTOOVER;为正,乘法结束COMFACCCLO;为负,乘积取补INCFACCCLOBTFSCSTATUS,ZDECFACCCHICOMFACCCHIBTFSCSTATUS,ZNEG_BDECFACCBLO;COMFACCBLOBTFSCSTATUS,ZDECFACCBHICOMFACCBHIOVERRETURN;子程序返回;*SETUPMOVLW.15;初始化TEMP寄存器MOVWFTEMPMOVFACCBHI,0;ACCB送ACCDMOVWFACCDHIMOVFACCBLO,0MOVWFACCDLOCLRFACCBHI;清ACCBCLRFACCBLORETURN;子程序返回;*乘法运算确定结果符号判断子程序*S_SIGNMOVFACCAHI,0;ACCAHI异或ACCBHI,结果送SIGN单元XORWFACCBHI,0MOVWFSIGNBTFSSACCBHI,7;ACCB为负吗?GOTOCHEK_A;否,检查ACCACALLNEG_B;是,求取ACCB绝对值CHEK_ABTFSCACCAHI,7;ACCA为负吗?CALLNEG_A;ACCA为负,求取ACCA绝对值,;见双字节加法程序RETURN;ACCA和ACCB均为正,返回【校验举例1】:-24555(-7391)=181486005(十进制)化为十六进制数:A015HE321H结果:0AD141B5H(十六进制)【校验举例2】1640513089=214725045(十进制)化为十六进制数:4015H3321H结果:0CCC71B5H(十六进制)【例程】MAINMOVLW0X15;被乘数4015H送ACCBMOVWFACCBLOMOVLW0X40MOVWFACCBHIMOVLW0X21;乘数3321H送ACCAMOVWFACCALOMOVLW0X33MOVWFACCAHICALLD_mpy;调用双字节乘法子程序,求积END2.31616位定点数除法子程序子程序采用反复的减法算法,除数和被除数分别为16位二进制有符号数(均采用补码表示,第16位为符号位),商为16位二进制有符号数,第16位为符号位。子程序的入口条件和出口条件如下:入口条件:被除数存放在ACCBHI、ACCBLO单元中;除数存放在ACCAHI、ACCALO单元中。出口条件:商存放在ACCBHI、ACCBLO单元中;余数存放在ACCCHI、ACCCLO单元中。LISTp=16f877INCLUDEp16f877.incACCALOEQU20;存放除数低8位ACCAHIEQU21;存放除数高8位ACCBLOEQU22;存放被除数和商的低8位ACCBHIEQU23;存放被除数和商的高8位ACCCLOEQU24;存放余数低8位ACCCHIEQU25;存放余数高8位ACCDLOEQU26;临时寄存器ACCDHIEQU27;临时寄存器TEMPEQU28;临时寄存器SIGNEQU29;存放商的符号ORG0X0000STARTGOTOMAIN;*1616位数除法子程序,入口地址ACCB/ACCA,出口地址ACCB*ORG0X0100D_divCALLS_SIGN;确定商的符号,并将负数取补CALLSETUP;初始化TEMP,将被除数移至ACCD,;(SETUP子程序请参见1616位定点数;乘法子程序SETUP)INCFTEMPCLRFACCCHI;清余数寄存器CLRFACCCLODLOOPBCFSTATUS,C;清进位位RLFACCDLO;被除数、余数左移1位RLFACCDHIRLFACCCLORLFACCCHIMOVFACCAHI,0;ACCCHI-ACCAHISUBWFACCCHI,0BTFSSSTATUS,Z;ACCCHI=ACCAHI?GOTONOCHKMOVFACCALO,0;是,ACCCLO-ACCALOSUBWFACCCLO,0NOCHKBTFSSSTATUS,C;ACCCACCA?GOTONOGOMOVFACCALO,0;是,余数减除数SUBWFACCCLOBTFSSSTATUS,CDECFACCCHIMOVFACCAHI,0SUBWFACCCHIBSFSTATUS,C;置进位位NOGORLFACCBLO;商左移1位RLFACCBHIDECFSZTEMP;循环完毕?GOTODLOOPBTFSSSIGN,7;是,确定商的符号GOTODIVOVER;为正,除法结束,跳转到结束行COMFACCCLO;为负,商和余数分别取补INCFACCCLOBTFSCSTATUS,ZDECFACCCHICOMFACCCHICALLNEG_B;见乘法程序中间NEG_BDIVOVERRETURN;子程序返回;*除法运算确定结果符号子程序*S_SIGNMOVFACCAHI,0;ACCAHI异或ACCBHI,结果送SIGN单元XORWFACCBHI,0MOVWFSIGNBTFSSACCBHI,7;ACCB为负?GOTOCHEK_A;否,检查ACCACOMFACCBLO;是,ACCB取补INCFACCBLOBTFSCSTATUS,ZDECFACCBHICOMFACCBHICHEK_ABTFSCACCAHI,7;ACCA为负?CALLNEG_A;ACCA为负,取补(NEG_A子程序请参见;1616位定点数乘法子程序NEG_A)RETURN;ACCA和ACCB均为负,返回【校验举例1】-23775(-240)=99.0625(十进制)化为十六进制数:A321HFF10H;结果:(商)0063H,(余数)000FH(十六进制)。【校验举例2】7693856=0.199429(十进制)化为十六进制数:0301H0F10H;结果:(商)0000H,(余数)0301H(十六进制)。【例程】MAINMOVLW0X01;被除数0301H送ACCBMOVWFACCBLOMOVLW0X03MOVWFACCBHIMOVLW0X10;除数0F10H送ACCAMOVWFACCALOMOVLW0X0FMOVWFACCAHICALLD_div;调用双字节除法子程序,求商END33字节浮点四则运算子程序3.1浮点数加(减)法子程序以下为浮点加(减)运算例程:LISTp=16f877INCLUDEp16f877.incACCALOEQU20;存放加数或减数的尾数ACCAHIEQU21EXPAEQU22;存放加数或减数阶码ACCBLOEQU23;存放被加数或被减数尾数以及和或差ACCBHIEQU24EXPBEQU25;存放被加数或被减数阶码ACCCLOEQU26;临时寄存器ACCCHIEQU27;临时寄存器ACCDLOEQU28;临时寄存器ACCDHIEQU29;临时寄存器TEMPEQU2A;临时寄存器TEMP1EQU30;临时寄存器TIMESEQU31;临时寄存器ORG0X000STARTGOTOMAINORG0X0100;*浮点减法子程序*F_subCALLNEG_A;求ACCA的补码,将减法转换为补码加法;*浮点加法子程序*F_addCALLSUBADJ;调子程序判断EXPB和EXPA的大小BTFSCSTATUS,Z;参与运算的两个数阶码相等?GOTOPADD;是,求尾数的和BTFSCSTATUS,C;EXPBEXPA?CALLF_swap;是,ACCB与ACCA互换MOVFEXPA,0;否,求取两者的差值SUBWFEXPBSCLOOPCALLSHFTSR;ACCB右移规格化INCFSZEXPB;EXPBEXPA?GOTOSCLOOP;否,继续右移MOVFEXPA,0;是,存和(差)的阶码MOVWFEXPBPADDMOVFACCAHI,0;ACCAHI或ACCBHIIORWFACCBHI,0MOVWFSIGN;存于SIGN寄存器MOVFACCBHI,0;暂存ACCBHIMOVWFEXPACALLD_add;尾数相加BTFSSSIGN,7;ACCA和ACCB有负数?BTFSCACCBHI,7;否,把和的最高位和次高位同时进位?GOTOADD2;否,转ADD2BTFSSACCAHI,7;ACCA为负吗?GOTOADD3;ACCA和ACCB不同时为负,转ADD3BTFSSEXPA,7;是,ACCB为负吗?GOTOADD3BSFSTATUS,C;ACCA和ACCB同为负,带负号右移RRFACCBHIRRFACCBLOINCFEXPBADD3CLRFACCCHI;和(差)规格化CLRFACCCLOCALLF_normRETURN;子程序返回ADD2BCFSTATUS,C;最高位次高位不同时进位,ACCB右移INCFEXPBGOTOSHFTRSHFTSRBCFSTATUS,C;ACCB带符号右移子程序BTFSCACCBHI,7BSFSTATUS,CSHFTRRRFACCBHIRRFACCBLORETURN;子程序返回;*ACCB、ACCA互换子程序*F_swapMOVFACCAHI,0;ACCAHI、ACCBHI互换MOVWFTEMPMOVFACCBHI,0MOVWFACCAHIMOVFTEMP,0MOVWFACCBHIMOVFACCALO,0;ACCALO、ACCBLO互换MOVWFTEMPMOVFACCBLO,0MOVWFACCALOMOVFTEMP,0MOVWFACCBLOMOVFEXPA,0;EXPA、EXPB互换MOVWFTEMPMOVFEXPB,0MOVWFEXPAMOVFTEMP,0MOVWFEXPBRETURN;*比较EXPB、EXPA大小子程序*SUBADJMOVFEXPA,0;EXPA异或EXPB,结果送C_DIVXORWFEXPB,0MOVWFC_DIVMOVFEXPA,0;EXPB-EXPASUBWFEXPB,0BTFSSC_DIV,7;EXPA和EXPB同号?RETURN;是,进位位的值真确反映两者的大小,返回BTFSSSTATUS,C;否,进位位的值取反GOTOCHANGECBCFSTATUS,CRETURNCHANGECBSFSTATUS,CRETURN;*浮点数规格化子程序*F_normMOVFACCBHI;ACCB0?BTFSSSTATUS,ZGOTOC_normMOVFACCBLOBTFSCSTATUS,ZRETURN;是,不需规格化,返回C_normBTFSCACCBHI,7;否。ACCB为负?GOTOC_norm2C_norm1BTFSCACCBHI,6;为正。规格化完毕?RETURN;ACCBHI.6=1,规格化结束CALLSHFTSL;否。ACCB左移DECFEXPB;EXPB减1GOTOC_norm1;重新判断规格化完毕否?C_norm2BTFSSACCBHI,6;ACCB为负。规格化完毕否?RETURN;ACCBHI.6=0,规格化结束BCFSTATUS,CCALLSHFTSL;否,ACCB左移BSFACCBHI,7;加符号DECFEXPB;EXPB减1GOTOC_norm2;重新判断规格化完毕否?SHFTSLBCFSTATUS,C;ACCB左移子程序RLFACCCLORLFACCCHIRLFACCBLORLFACCBHIRETURN【校验举例1】0.0019531+(-0.00016594)=0.00178716化为十六进制数:4000F8+A900F4结果:7520F7【校验举例2】0.26222+3.5025=3.76478化为十六进制数:4321FF+701502结果:787902【例程】MAINMOVLW0X21;被加数的尾数4321H送ACCBMOVWFACCBLOMOVLW0X43MOVWFACCBHIMOVLW0XFF;被加数的阶码FFH送EXPBMOVWFEXPBMOVLW0X15;加数尾数7015H送ACCAMOVWFACCALOMOVLW0X70MOVWFACCAHIMOVLW0X02;加数阶码送EXPAMOVWFEXPACALLF_add;调用浮点数加法子程序,求和END3.2浮点数乘法子程序以下为浮点数乘法的程序清单。LISTp=16f877INCLUDEp16f877.incACCALOEQU20;存放乘数尾数ACCAHIEQU21EXPAEQU22;存放乘数阶码ACCBLOEQU23;存放被乘数尾数和乘积高16位ACCBHIEQU24EXPBEQU25;存放被乘数阶码ACCCLOEQU26;存放乘积低16位ACCCHIEQU27ACCDLOEQU28;临时寄存器ACCDHIEQU29;临时寄存器TEMPEQU2A;临时寄存器TEMP1EQU30;临时寄存器TIMESEQU31;临时寄存器SIGNEQU2B;存放乘积符号COUNTEQU2F;临时寄存器ACCEHIEQU30;临时寄存器ACCELOEQU31;临时寄存器ORG0X0000STARTGOTOMAINORG0X0100;*浮点乘法子程序,入口地址(ACCB、EXPB)(ACCA、EXPA),出口地址ACCB、EXPB*F_mpyCALLS_SIGN;求取乘积的符号,并对负数取补CALLSETUP;调用子程序将ACCB的值送ACCDCLRFACCCHI;清ACCCCLRFACCCLOMLOOPBCFSTATUS,C;清进位位RRFACCDHI;ACCD右移RRFACCDLOBTFSCSTATUS,C;判断是否需要相加CALLD_add;加乘数至ACCBBCFSTATUS,C;清进位位RRFACCBHI;右移部分乘积RRFACCBLORRFACCCHIRRFACCCLODECFSZTEMP;乘法完成否?GOTOMLOOP;否,继续循环MOVFEXPA,0;是,乘数与被乘数阶码相加,得积的阶码ADDWFEXPBMOVFACCBHI;ACCBHI=0?BTFSSSTATUS,ZGOTOFINUP;否,转FINUPMOVFACCBLO;ACCB0?BTFSSSTATUS,ZGOTOSHFT08;否,只有ACCBHI=0,转SHFT08MOVFACCCHI,0;ACCB=0,将乘积左移15位MOVWFACCBHIMOVFACCCLO,0MOVWFACCBLOBCFSTATUS,CRRFACCBHIRRFACCBLOMOVLW.15;乘积阶码减15(十进制数)SUBWFEXPBGOTOFINUPSHFT08MOVFACCBLO,0;只有ACCBHI0,乘积左移7位MOVWFACCBHIMOVFACCCHI,0MOVWFACCBLOBCFSTATUS,CRRFACCBHIRRFACCBLOMOVLW.7;乘积阶码减7SUBWFEXPBFINUPCALLF_norm;对乘积进行规格化BTFSSSIGN,7;确定乘积的符号GOTOOVER;为正,乘法结束COMFACCCLO;为负,乘积取补INCFACCCLOBTFSCSTATUS,ZDECFACCCHICOMFACCCHIBTFSCSTATUS,ZNEG_BDECFACCBLOCOMFACCBLOBTFSCSTATUS,ZDECFACCBHICOMFACCBHIOVERRETURN;乘法结束

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论