C51汇编语言程序设计.ppt

上传人:max****ui 文档编号:3402869 上传时间:2019-12-13 格式:PPT 页数:132 大小:676.81KB
返回 下载 相关 举报
C51汇编语言程序设计.ppt_第1页
第1页 / 共132页
C51汇编语言程序设计.ppt_第2页
第2页 / 共132页
C51汇编语言程序设计.ppt_第3页
第3页 / 共132页
点击查看更多>>
资源描述
第4章89C51汇编语言程序设计汇编语言是面向机器硬件的语言,要求程序设计者对89C51单片机具有很好的“软、硬结合”的功底。介绍程序设计的基本知识及如何使用汇编语言来进行基本的程序设计。4.1汇编语言程序设计概述程序是若干指令的有序集合,单片机的运行就是执行这一指令序列的过程,编写这一指令序列的过程称为程序设计。4.1.1机器语言、汇编语言和高级语言用于程序设计的语言基本上分为3种:机器语言、汇编语言和高级语言。,1.机器语言二进制代码表示的指令、数字和符号简称为机器语言不易懂,难记忆,易出错。2汇编语言英文助记符表示的指令称为符号语言或汇编语言将汇编语言程序转换成为二进制代码表示的机器语言程序称为汇编程序经汇编程序“汇编(翻译)”得到的机器语言程序称为目标程序,原来的汇编语言程序称为源程序。,汇编语言特点:面向机器的语言,程序设计员须对89C51的硬件有相当深入的了解。助记符指令和机器指令一一对应,用汇编语言编写的程序效率高,占用存储空间小,运行速度快,用汇编语言能编写出最优化的程序。能直接管理和控制硬件设备(功能部件),它能处理中断,也能直接访问存储器及I/O接口电路。,汇编语言和机器语言都脱离不开具体机器的硬件,均是面向“机器”的语言,缺乏通用性。3高级语言不受具体机器的限制,使用了许多数学公式和数学计算上的习惯用语,非常擅长于科学计算。常用的如BASIC、FORTRAN以及C语言等。高级语言优点:通用性强,直观、易懂、易学,可读性好。计算机不能直接识别和执行高级语言,需要将其“翻译”成机器语言才能识别和执行,进行“翻译”的专用程序称为编译程序。使用C语言(C51)、BASIC语言来进行AT89C51的应用程序设计。,对于程序的空间和时间要求很高的场合,汇编语言仍是必不可缺的。C语言和汇编语言混合编程在很多需要直接控制硬件的应用场合,则更是非用汇编语言不可。使用汇编语言编程,是单片机程序设计的基本功之一。,4.1.2汇编语言语句的种类和格式两种基本类型:指令语句和伪指令语句(1)指令语句已在第3章介绍每一条指令语句在汇编时都产生一个指令代码机器代码(2)伪指令语句是为汇编(翻译)服务的。在汇编时没有机器代码与之对应。,AT89C51的汇编语言的四分段格式如下:标号字段操作码字段操作数字段注释字段规则:(1)标号字段和操作字码段之间要有冒号“:”相隔;(2)操作码字段和操作数字段间的分界符是空格;(3)双操作数之间用逗号相隔;(4)操作数字段和注释字段之间的分界符用分号“;”相隔。(5)一条语句可以没有标号,标号的有无取决于本程序中的其他语句是否访问该条语句。操作码字段为必选项,其余各段为任选项。例4-1下面是一段汇编语言程序的四分段书写格式,标号字段操作码字段操作数字段注释字段START:MOVA,#00H;0AMOVR1,#10;10R1MOVR2,#00000011B;3R2LOOP:ADDA,R2;(A)+(R2)ADJNZR1,LOOP;R1内容减1不为零,则循环NOPHERE:SJMPHERE基本语法规则:1标号字段是语句所在地址的标志符号,(1)标号后边必须跟以冒号“:”(2)由1-8个ASCII字符组成(3)同一标号在一个程序中只能定义一次(4)不能使用汇编语言已经定义的符号作为标号2操作码字段是汇编语言指令中唯一不能空缺的部分。汇编程序就是根据这一字段来生成机器代码的。,3操作数字段通常有单操作数、双操作数和无操作数三种情况。如果是双操作数,则操作数之间,要以逗号隔开。(1)十六进制、二进制和十进制形式的操作数表示采用十六进制形式来表示,某些特殊场合才采用二进制或十进制的表示形式。十六进制,后缀“H”。二进制,后缀“B”。十进制,后缀“D”,也可省略。,若十六进制的操作数以字符A-F中的某个开头时,则需在它前面加一个“0”,以便在汇编时把它和字符AF区别开来。(2)工作寄存器和特殊功能寄存器的表示采用工作寄存器和特殊功能寄存器的代号来表示,也可用其地址来表示。例如,累加器可用A(或Acc)表示。也可用0E0H来表示,0E0H为累加器A的地址。4注释字段必须以分号“;”开头,换行书写,但必须注意也要以分号“;”开头。汇编时,注释字段不会产生机器代码。,4.1.3伪指令在AT89C51汇编语言源程序中应有向汇编程序发出的指示信息,告诉它如何完成汇编工作,这是通过使用伪指令来实现的。伪指令不属于指令系统中的汇编语言指令,它是程序员发给汇编程序的命令,也称为汇编程序控制命令。只有在汇编前的源程序中才有伪指令。经过汇编得到目标程序(机器代码)后,伪指令已无存在的必要,所以“伪”体现在汇编时,伪指令没有相应的机器代码产生。,。常用的伪指令:1.ORG(ORiGin)汇编起始地址命令在汇编语言源程序的开始,通常都用一条ORG伪指令来实现规定程序的起始地址。如不用ORG规定,则汇编得到的目标程序将从0000H开始。例如:,ORG2000HSTART:MOVA,#00H规定标号START代表地址为2000H开始。在一个源程序中,可多次使用ORG指令,来规定不同的程序段的起始地址。但是,地址必须由小到大排列,地址不能交叉、重叠。例如:ORG2000H,ORG2500HORG3000H以上顺序是正确的。若按下面顺序的排列则是错误的,因为地址出现了交叉。ORG2500HORG2000HORG3000H,2.END(ENDofassembly)汇编终止命令汇编语言源程序的结束标志,用于终止源程序的汇编工作。在整个源程序中只能有一条END命令,且位于程序的最后。3DB(DefineByte)定义字节命令在程序存储器的连续单元中定义字节数据。,ORG2000HDB30H,40H,24,“C”,“B”汇编后:(2000H)=30H(2001H)=40H(2002H)=18H(10进制数24)(2003H)=43H(字符“C”的ASCII码)(2004H)=42H(字符“B”的ASCII码)DB功能是从指定单元开始定义(存储)若干个字节,10进制数自然转换成16进制数,字母按ASCII码存储。,4DW(DefineWord)定义数据字命令从指定的地址开始,在程序存储器的连续单元中定义16位的数据字。例如:ORG2000HDW1246H,7BH,10汇编后:(2000H)=12H;第1个字(2001H)=46H(2002H)=00H;第2个字(2003H)=7BH(2004H)=00H;第3个字(2005H)=0AH(2005H)=0AH,5EQU(EQUate)赋值命令用于给标号赋值。赋值以后,其标号值在整个程序有效。例如:TESTEQU2000H表示标号TEST=2000H,在汇编时,凡是遇到标号TEST时,均以2000H来代替。,4.2汇编语言源程序的汇编汇编语言源程序“翻译”成机器代码(指令代码)的过程称为“汇编”。汇编可分为手工汇编和机器汇编两类:4.2.1手工汇编人工查表翻译指令。但遇到的相对转移指令的偏移量的计算,要根据转移的目标地址计算偏移量,不但麻烦,且容易出错。,4.2.2机器汇编用编辑软件进行源程序的编辑。编辑完成后,生成一个ASCII码文件,扩展名为“.ASM”。然后在微计算机上运行汇编程序,把汇编语言源程序翻译成机器代码。交叉汇编-汇编后的机器代码是在另一台计算机(这里是单片机)上运行。反汇编分析现成产品的程序,要将二进制的机器代码语言程序翻译成汇编语言源程序。例4-2下面是一段源程序的汇编结果,读者可通过查第3章的指令表,进行手工汇编,来验证下面的汇编结果是否正确。见表4-1,汇编语言源程序,汇编后的机器代码,标号,助记符指令,地址(十六进制,机器代码(十六进制),START:,MOVA,#80HMOVB,#76HADDA,AADDA,BLJMPSTART,20002002200520072009,740875F07605F005F0022000,源程序汇编结果,表4-1,4.3AT89C51单片机汇编语言程序设计举例4.3.1子程序的设计在实际的程序设计中,常常将那些需多次应用的、完成相同的某种基本运算或操作的程序段从整个程序中独立出来,单独编成一个程序段,需要时通过子程序调用指令进行调用。这样的程序段称为子程序。采用子程序能使整个程序结构简单,缩短程序的设计时间,减少占用的程序存储空间。调用子程序的程序称为主程序或调用程序。子程序在程序设计中非常重要,读者应熟练掌握子程序的设计方法。,1.子程序设计原则和应注意的问题一种能完成某一特定任务的程序段。其资源要为所有调用程序共享。因此,子程序在结构上应具有独立性和通用性。编写子程序时应注意以下问题:(1)子程序的第一条指令的地址称为子程序的入口地址。该指令前必须有标号。(2)主程序调用子程序两条子程序调用指令:绝对调用指令:ACALLaddr11,长调用指令:LCALLaddr16(3)注意设置堆栈指针和现场保护(4)最后一条指令必须是RET指令(5)子程序可以嵌套,即子程序可以调用子程序2.子程序的基本结构MAIN:;MAIN为主程序或调用程序标号LCALLSUB;调用子程序SUB,SUB:PUSHPSW;现场保护PUSHACC;子程序处理程序段POPACC;现场恢复POPPSW;RET;最后一条指令必须为RET,4.3.2查表程序设计数据补偿、修正、计算、转换等各种功能,具有程序简单、执行速度快等优点。查表就是根据自变量x,在表格中寻找y,使y=f(x)。执行查表指令时,发出读程序存储器选通脉冲PSEN*。指令系统,给用户提供了两条极为有用的查表指令:MOVCA,A+DPTRMOVCA,A+PC,MOVCA,A+DPTR完成把A中的内容作为一个无符号数与DPTR中的内容相加,所得结果为某一程序存储单元的地址,然后把该地址单元中的内容送到累加器A中。MOVCA,A+PC以PC作为基址寄存器,PC的内容和A的内容作为无符号数,相加后所得的数作为某一程序存储器单元的地址,根据地址取出程序存储器相应单元中的内容送到累加器A中。指令执行完,PC的内容不发生变化,仍指向查表指令的下一条指令。,优点:预处理较少且不影响其它特殊功能寄存器的值,所以不必保护其它特殊功能寄存器的原先值缺点:在于该表格只能存放在这条指令的地址X3X2X1X0以下的00FFH之中。表格所在的程序空间受到了限制。,例4-3设计一子程序,功能为:根据累加器A中的数x(09之间)查x的平方表y,根据x的值查出相应的平方y。x和y均为单字节数。地址子程序Y3Y2Y1Y0ADDA,#01HY3Y2Y1Y0+2MOVCA,A+PCY3Y2Y1Y0+3RETY3Y2Y1Y0+4DB00H,01H,04H,09H,10H;数09的平方DB19H,24H,31H,40H,51H第1条指令ADDA,#01H的作用是加上偏移量,可以根据A的内容查出X对应的平方。,MOVCA,A+DPTR这条指令的应用范围较为广泛,一般情况下,大多使用该指令,使用该指令时不必计算偏移量,使用该指令的优点是表格可以设在64K程序存储器空间内的任何地方,而不像MOVCA,A+PC那样只设在PC下面的256个单元中,使用较方便。上面的程序可改成如下形式:PUSHDPH;保存DPHPUSHDPL;保存DPL例4-4设有一个巡回检测报警装置,需对16路输入进行检测,每路有一最大允许值,为双字节数。运行时,需根据测量的路数,找出每路的最大允许值。看输入值是否大于最大允许值,如大于就报警。,根据上述要求,编一个查表程序。取路数为x(0 x15),y为最大允许值,放在表格中。设进入查表程序前,路数x已放于R2中,查表后最大值y放于R3、R4中。本例中的x为单字节数,y为双字节数。查表程序如下:TB3:MOVA,R2ADDA,R2;(R2)*2(A)MOVR3,A;保存指针ADDA,#6;加偏移量MOVCA,A+PC;查第一字节XCHA,R3ADDA,#3MOVCA,A+PC;查第二字节MOVR4,A,RETTAB3:DW1520,3721,42645,7580;最大值表DW3483,32657,883,9943DW10000,40511,6758,8931DW4468,5871,13284,27808表格长度不能超过256个字节,且表格只能存放于MOVCA,A+PC指令以下的256个单元中。如需要把表格放在64KB程序存储器空间的任何地方,此时应使用指令“MOVCA,A+DPTR”,并对DPH、DPL进行运算,求出表格的目的地址。,例4-5在一个以AT89C51单片机为核心的温度控制器中,温度传感器输出的电压与温度为非线性关系,传感器输出的电压已由A/D转换为10位二进制数。测得的不同温度下的电压值数据构成一个表,表中温度值为y(双字节无符号数),x(双字节无符号数)为电压值数据。设测得的电压值x放入R2R3中,根据电压值x,查找对应的温度值y,仍放入R2R3中。,LTB2:MOVDPTR,#TAB2MOVA,R3CLRCRLCAMOVR3,AXCHA,R2RLCAXCHR2,AADDA,DPL;(R2R3)+(DPTR)(DPTR)MOVDPL,AMOVA,DPHADDCA,R2MOVDPH,A,CLRAMOVCA,A+DPTR;查第一字节MOVR2,A;第一字节存入R2中CLRAINCDPTRMOVCA,A+DPTR;查第二字节MOVR3,A;第二字节存入R3中RETTAB2:DW;温度值表由于使用指令“MOVCA,A+DPTR”,表TAB2可放入64KB程序存储器空间的任何位置,此外表格的长度可大于256B。,4.3.3关键字查找程序设计顺序检索和对分检索1.顺序检索从第1项开始逐项顺序查找,判断所取数据是否与关键字相等。例4-6从50个字节的无序表中查找一个关键字XXH。,ORG1000HMOV30H,#XXH;关键字XXH送30H单元MOVR1,#50;查找次数送R1MOVA,#14;修正值送AMOVDPTR,#TAB4;表首地址送DPTRLOOP:PUSHACCMOVCA,A+PC;查表结果送ACJNEA,40H,LOOP1;(40H)不等于关键字则;转LOOP1MOVR2,DPH;已查到关键字,把该字;的地址送R2,R3MOVR3,DPL;,DONE:RETLOOP1:POPACC;修正值弹出INCA;A+1AINCDPTR;修改数据指针DPTRDJNZR1,LOOP;R10,未查完,继续查找MOVR2,#00H;R1=0,清“0”R2和R3MOVR3,#00H;表中50个数已查完AJMPDONE;从子程序返回TAB4:DB,;50个无序数据表,2.对分检索前提:检索的数据表已经排好序,如何进行数据的排序,将在本节稍后介绍。方法:取数据表中间位置的数与关键字进行比较,如相等,则查找到;如果所取的数大于关键字,则下次对分检索的范围是从数据区起点到本次取数。如果取数小于关键字,则下次对分检索的范围是从本次取数数据区起点到数据区终点。依此类推,逐渐缩小检索范围,减少次数,大大提高查找速度。,4.3.4数据极值查找程序设计在指定的数据区中找出最大值(或最小值)。进行数值大小的比较,从这批数据中找出最大值(或最小值)并存于某一单元中。例4-7片内RAM中存放一批数据,查找出最大值并存放于首地址中。设R0中存首地址,R2中存放字节数,程序框图如图4-1所示。程序如下:MOVR2,#n;n为要比较的数据字节数MOVA,R0;存首地址指针,图4-1查找单字节无符号最大数程序框图,MOVR1,ADECR2;MOVA,R1LOOP:MOVR3,ADECR1CLRCSUBBA,R1;两个数比较JNCLOOP1;C=0,A中的数大,跳LOOP1MOVA,R1;C=1,则大数送ASJMPLOOP2LOOP1:MOVA,R3LOOP2:DJNZR2,LOOP;是否比较结束?MOVR0,A;存最大数RET,4.3.5数据排序程序设计升序排,降序排。仅介绍无符号数据升序排。冒泡法:相邻数互换的排序方法,类似水中气泡上浮。排序时从前向后进行相邻两个数的比较,次序与要求的顺序不符时,就将两个数互换;顺序符合要求不互换。,假设有7个原始数据的排列顺序为:6、4、1、2、5、7、3。第一次冒泡的过程是:6、4、1、2、5、7、3;原始数据的排列4、6、1、2、5、7、3;逆序,互换4、1、6、2、5、7、3;逆序,互换4、1、2、6、5、7、3;逆序,互换4、1、2、5、6、7、3;逆序,互换4、1、2、5、6、7、3;正序,不互换4、1、2、5、6、3、7;逆序,互换,第一次冒泡结束,如此进行,各次冒泡的结果如下:第1次冒泡结果:4、1、2、5、6、3、7第2次冒泡结果:1、2、4、5、3、6、7第3次冒泡结果:1、2、4、3、5、6、7第4次冒泡结果:1、2、3、4、5、6、7;已完成排序第5次冒泡结果:1、2、3、4、5、6、7第6次冒泡结果:1、2、3、4、5、6、7对于n个数,理论上应进行(n-1)次冒泡,有时不到(n-1)次就已完成排序。,如何判定排序是否已完成,看各次冒泡中是否有互换发生,如有数据互换,则排序未完成。在程序设计中,常使用设置互换标志的方法,该标志的状态表示在一次冒泡中是否有互换进行。例4-8一批单字节无符号数,以R0为首地址指针,R2中为字节数,将这批数进行升序排列。程序框图如图4-2所示。,图4-2单字节无符号数排序程序框图,SORT:MOVA,R0;MOVR1,AMOVA,R2;字节数送入R5MOVR5,ACLRF0;互换标志位F0清零DECR5;MOVA,R1;LOOP:MOVR3,A;INCR1;CLRC;,MOVA,R1;比较大小SUBBA,R3;JNCLOOP1;SETBF0;互换标志位F0置1MOVA,R3;XCHA,R1;两个数互换DECR1;XCHA,R1;INCR1LOOP1:MOVA,R1DJNZR5,LOOPJBF0,SORTRET,4.3.6分支转移程序设计特点是程序中含有转移指令,转移指令有分为无条件转移和有条件转移,因此分支程序也可分为无条件分支转移程序和有条件分支转移程序。有条件分支转移程序按结构类型来分,又分为单分支转移结构和多分支转移结构。1单分支转移结构仅有两个出口,两者选一。,图4-3求单字节有符号二进制数补码的框图,例4-9求单字节有符号数的二进制补码,程序框图如图4-3所示:参考程序:CMPT:JNBAcc.7,RETURN;(A)0,不需转换MOVC,Acc.7;符号位保存CPLA;(A)求反,加1ADDA,#1;MOVAcc.7,C;符号位存A的最高位RETURN:RET,此外,单分支选择结构还有如图4-4、图4-5等所示的几种形式:,图4-4单分支选择结构2,图4-5单分支选择结构3,2多分支转移结构程序的判别部分有两个以上的出口。常见的两种形式。如图4-6和图4-7。指令系统提供了非常有用的两种多分支选择指令:间接转移指令:JMPA+DPTR;比较转移指令:CJNEA,direct,rel;CJNEA,#data,rel;CJNERn,#data,rel;CJNERi,#data,rel;,图4-6多分支选择结构1,图4-7多分支选择结构2,最简单的分支转移程序的设计,一般常采用逐次比较法,就是把所有不同的情况一个一个的进行比较,发现符合就转向对应的处理程序。这种方法的主要缺点是程序太长,有n种可能的情况,就需有n个判断和转移。例4-10求符号函数的值。符号函数定义(略):X存放在40H单元,Y存放在41H单元,程序框图如图4-6所示。程序如下:SIGNFUC:MOVA,40HCJNEA,#00H,NZEARAJMPNEGTNZEAR:JBAcc.7,POSIMOVA,#01H,AJMPNEGTPOSI:MOVA,#81HNEGT:MOV41H,AEND在实际的应用中,经常遇到的图4-7结构形式的分支转移程序的设计需根据某一单元的内容是0,1,n,来分别转向处理程序0,处理程序1,处理程序n。,一个典型的例子就是当单片机系统中的键盘按下时,就会得到一个键值,根据不同的键值,跳向不同的键处理程序入口。对于这种情况,可用直接转移指令(LJMP或AJMP指令)组成一个转移表,然后把该单元的内容读入累加器A,转移表首地址放入DPTR中,再利用间接转移指令实现分支转移。例4-11根据寄存器R2的内容,转向各个处理程序PRGX(X=0-n)。(R2)=0,转PRG0(R2)=1,转PRG1(R2)=n,转PRGn,4.3.7循环程序设计特点是程序中含有可以反复执行的程序段,该程序段通常称为循环体。例如求100个数的累加和,则没有必要连续安排100条加法指令,可以只用一条加法指令并使其循环执行100次。(1)可大大缩短程序长度。(2)使程序所占的内存单元数量少。(3)使程序结构紧凑和可读性变好。,1.循环程序的结构循环结构程序主要由以下四部分组成。(1)循环初始化循环初始化程序段用于完成循环前的的准备工作。例如,循环控制计数初值的设置、地址指针的起始地址的设置、为变量预置初值等。(2)循环处理循环程序结构的核心部分,完成实际的处理工作,是需反复循环执行的部分,故又称循环体。这部分程序的内容,取决于实际处理问题的本身。,(3)循环控制在重复执行循环体的过程中,不断修改循环控制变量,直到符合结束条件,就结束循环程序的执行。循环结束控制方法分为循环计数控制法和条件控制法(4)循环结束这部分是对循环程序执行的结果进行分析、处理和存放。,2.循环结构的控制图4-8是计数循环控制结构,图4-9是条件控制结构。,图4-8计数循环控制结构,图4-9条件控制结构,(1)计数循环结构计数循环控制结构是依据计数器的值来决定循环次数,一般为减“1”计数器,计数器减到“0”时,结束循环。计数器的初值是在初始化时设定。AT89C51的指令系统提供了功能极强的循环控制指令:DJNZRn,rel;工作寄存器作控制计数器DJNZdirect,rel;以直接寻址单元作控制计数器。计数控制方法只有在循环次数已知的情况下才适用。对循环次数未知的问题,不能用循环次数来控制。往往需要根据某种条件来判断是否应该终止循环。例如,计算n个数据的和。程序框图见图4-10。,图4-10求数据和程序框图,例4-12如果xi均为单字节数,并按i顺序存放在51单片机内部RAM从50H开始的单元中,n放在R2中,现将要求的和(双字节)放在R3R4中,程序如下:ADD1:MOVR2,#n;加法次数n送R2MOVR3,#0MOVR4,#0MOVR0,#50HLOOP:MOVA,R4ADDA,R0MOVR4,AINCR0CLRAADDCA,R3,MOVR3,ADJNZR2,LOOP;判加法循环次数是否已到?END计数控制方法只有在循环次数已知的情况下才适用。对循环次数未知的问题,不能用循环次数来控制,往往需要根据某种条件来判断是否应该终止循环。,(2)条件控制结构例4-13设有一串字符,依次存放在内部RAM从30H单元开始的连续单元中,该字符串以0AH为结束标志,编写测试字符串长度的程序。本例采用逐个字符依次与“0AH”比较的方法。为此设置一个长度计数器和一个字符串指针。长度计数器用来累计字符串的长度,字符串指针用于指定字符。如果指定字符与“0AH”不相等,则长度计数器和字符串指针都加1,以便继续往下比较;如果比较相等,则表示该字符为“0AH”,字符串结束,长度计数器的值就是字符串的长度。程序如下:,MOVR4,#0FFH;长度计数器初值送R4MOVR1,#2FH;字符串指针初值送R1NEXT:INCR4INCR1CJNER1,#0AH,NEXT;比较,不等则进行下一个END;字符比较上面两个例子都是在一个循环程序中不再包含其他循环程序,则称该循环程序为单循环程序。如果一个循环程序中包含了其他循环程序,则称为多重循环程序。这也是经常遇到的实际问题。最常见的多重循环是由DJNZ指令构成的软件延时程序,它是常用的程序之一。,例4-1450ms延时程序。延时程序与指令执行时间有很大的关系。在使用12MHz晶振时,一个机器周期为1s,执行一条DJNZ指令的时间为2s。这时,可用双重循环方法写出延时50ms的程序:DEL:MOVR7,#200;指令执行时间1usDEL1:MOVR6,#125;指令执行时间1usDEL2:DJNZR6,DEL2;125*2=250sDJNZR7,DEL1;0.25ms*200=50msRET以上延时程序不太精确,它没有考虑到除“DJNZR6,DEL2”指令外的其它指令的执行时间,如把其它指令的执行时间计算在内,它的延时时间为:1+(1+250+2)*200+2=50.603ms,如果要求比较精确的延时,应该考虑对上述程序进行修改,才能得到较为精确的延时时间。注意,用软件实现延时程序,不允许有中断,否则将严重影响定时的准确性。对于需延时更长的时间,可采用更多重的循环,如1s延时,可用三重循环。,汇编语言程序设计基础,1.简单程序例1-1将片内RAM的30H和31H的内容相加,结果存入32H。假设整个程序存放在存储器中以2000H为起始地址的单元。程序1:ORG2000H2000E530MOVA,30H;取第一个操作数20022531ADDA,31H;两个操作数相加2004F532MOV32H,A;存放结果END本程序采用直接寻址方式传送数据进行两数相加,程序2:ORG8000H80007830MOVR0,#30H;R030H8002E6MOVA,R0;A(30H)800308INCR0;800426ADDA,R0;两个操作数相加800508INCR08006F6MOVR0,A;存放结果本程序采用寄存器间接寻址方式进行两个操作数相加运算。必须先给地址指针R0赋值。,例1-2拼字:将外部数据存储器3000H和3001H的低4位取出拼成一个字,送3002H单元中。20001ORG2000H20009020002MOVDPTR,#3000H2003E03MOVXA,DPTR2004540F4ANLA,#0FH2006C45SWAPA2007F96MOVR1,A;暂存于R12008A37INCDPTR2009E08MOVXA,DPTR200A540F9ANLA,#0FH200C4910ORLA,R1200DA311INCDPTR,200EF012MOVXDPTR,A200F80FE13SJMP14END2.分支程序例2-1把片外RAM的首地址为10H开始存放的数据块,传送给片内RAM首地址为20H开始的数据块中去,如果数据为”0”,就停止传送。ORG2000HINCR0MOVR0,#10HINCR1MOVR1,#20HSJMPLOOPLOOP:MOVXA,R0;A片外RAM数据ENDHERE:JZHERE;数据=0终止,程序原地踏步MOVR1,A;片内RAMA,3.循环程序例3-1有20个数存放在内部RAM从41H开始的连续单元中,试求其和并将结果存放在40H单元(和是一个8位二进制数,不考虑进位问题)。ORG2000HMOVA,#00HMOVR7,#14H;建循环计数器R7初值MOVR0,#41H;建内存数据指针LOOP:ADDA,R0INCR0DJNZR7,LOOP;判循环结束条件MOV40H,A;存累加结果SJMPEND,例3-2较长时间的延时子程序,可以采用多重循环来实现。利用CPU中每执行一条指令都有固定的时序这一特征,令其重复执行某些指令从而达到延时的目的。源程序机器周期数DELAY:MOVR7,#0FFH1LOOP1:MOVR6,#0FFH1LOOP2:NOP1NOP1DJNZR6,LOOP22DJNZR7,LOOP12RET2,内循环,外循环,程序中:内循环一次所需机器周期数=(1+1+2)个=4个内循环共循环255次的机器周期数=4255个=1020个外循环一次所需机器周期数=(4255+1+2)个=1023个外循环共循环255次,所以该子程序总的机器周期数=(2551023+1+2)个=260868个。因为一个机器周期为12个时钟周期,所以该子程序最长延时时间=26086812/fosc。注意:软件延时不允许有中断,否则影响定时的准确性。如果需要更长时间,可采用多重循环,如延时1min,可采用三重循环。,4.将片内RAM30H单元与40H单元中的内容互换。方法一(直接地址传送法)MOV31H,30HMOV30H,40HMOV40H,31HSJMP$方法二(间接地址传送法)MOVR0,#40HMOVR1,#30HMOVA,RO;A(40H)MOVB,R1;B(30H)MOVR1,A;30H(40H)MOVR0,B;40H(30H)SJMP$,方法三(字节交换传送法)XCHA,30H;(A)(30H)XCHA,40H;(40H)(30H)XCH30H,ASJMP$方法四(堆栈传送法)PUSH30HPUSH40HPOP30HPOP40HSJMP$,1秒延时子程序:ORG2100HDEY1S:MOVR1,#02H;LOOP3:MOVR2,#C8H;LOOP2:MOVR3,#FAH;LOOP1:NOPNOPNOPDJNZR3,LOOP1DJNZR2,LOOP2DJNZR1,LOOP3RET,单片机晶振为12MHZ,编写一段延时程序,延时时间为1S。,MAIN:MOVR3,#64HMOVR4,#0AHDELAY:MOVR2,#0FAHLOOP:NOPNOPDJNZR2,LOOPDJNZR3,DELAYDJNZR4,DELAYRET,编写延时1S的子程序,设晶振频率为12MHZ。,DELAY1S:MOVR6,#4;1TDL1:MOVR5,#251;1TDL2:MOVR4,#248;1TDL3:NOP1TNOP1TDJNZR4,DL3;2TDJNZR5,DL2;2TDJNZR6,DL1;2T延时时间(2484+1+2)251+1+2)4+1+2=998995us1S,DVCC-5286JH实验系统,1.实验系统设置状态(51状态)SK1位1-5置ON,位6-10置OFF;SK2位1-2置ON;SK3置0N;SK4、SK5置OFF;KBB置51位置;DL1DL4连1、2;,2.实验系统的启动接通电源开关(实验系统左侧),系统正常应显示闪动的“P.”为正常。若不显示P.,应按复位键;还不显示,应立即关闭电源。3.实验系统与微机的连接实验系统与微机的COM1或COM2连接,不能带电插拔。在实验系统启动显示P.时,按PCDBG键,显示器无显示,此时单击应用软件的连接,应出现寄存器窗口,说明微机与开发系统连接成功。若提示连接失败,可重复上述操作。,4.实验的一般步骤a:运行DVCC软件。b:编写源程序,汇编排错,形成正确的源文件.ASM,并生成中间文件.OBJ。c:编译连接,形成最终目标文件.ABS(或.EXE)d:装载最终目标文件到实验系统的仿真RAM区。e:调试实验程序,若有错则重复b-d。5.实验过程的几点说明a:运行软件前,查看要做的硬件实验,原理图上粗实线表示用户实验时要用导线连接;b:注意实验操作顺序,连接前要按”PCDBG”;,c:若显示连接失败,要注意:连线(微机与CON1或COM2)串口设置是否按“PCDBG”键注意:编译:生成后缀为.OBJ文件。F11编译连接:生成后缀为.ABS文件,88生成EXE文件。F12编译连接传送:编译当前文件,并传送HEX、ABS、BIN文件(51/96)或EXE文件。(88系统)CTRL+F9,软件程序实验一清零程序一、实验内容把7000H70FFH的内容清零。二、实验框图,开始,R0=00,007000H,DPTR+1,R0+1,R0=FF,结束,N,Y,三、实验程序00301ORG0030H003078002MOVR0,#00H00329070003MOVDPTR,#7000H0035E44CLEAR1:CLRA0036F05MOVXDPTR,A0037A36INCDPTR0038087INCR00039B800F98CJNER0,#00H,CLEAR1003C80F29SJMPCLEAR10END,四、实验操作(脱机操作)拍7000按TV键按F270007001700270FF,1,2,3,4,5,F,0,7,8,00,00,00,00,实验前后,五、修改程序把7000H70FFH单元内容置1。,实验二拆字程序一、实验内容把7000H的内容拆开,高位送7001H低位,低位送7002H低位。7001H、7002H高位清0,一般用于把数据送显示缓冲区时用。二、程序框图,开始,7000内容A,高低位交换屏蔽高位7001H,7000H内容A,屏蔽高位后7002H,结束,三、实验程序00501ORG0050H00509070002LL:MOVDPTR,#7000H;数据指针0053E03MOVXA,DPTR0054F5F04MOVB,A;取7000H内容暂存B0056C45SWAPA;高低4位交换0057540F6ANLA,#0FH;屏蔽高4位0059A37INCDPTR005AF08MOVXDPTR,A;将(7000H)高字005BA39INCDPTR;节存入(7001H)005CE5F010MOVA,B005E540F11ANLA,#0FH,0060F012MOVXDPTR,A;送7002H006180FE13LL1:SJMPLL114END四、实验操作运行前:7000H7001H7002H运行后:7000H7001H7002H,7,8,5,4,4,4,F,F,5,0,0,5,4,5,实验三拼字程序一、实验内容把7000H和7001H的低位相拼后送入7002H,一般用于把显示缓冲区数据取出拼装成一个字节。二、程序框图,开始,(7000H)A,屏弊高位,交换高低位后B,(7001H)A,屏弊高位,A、B相或后7002H,结束,三、实验程序00701ORG0070H00709070002PP:MOVDPTR,#7000H0073E03MOVXA,DPTR0074540F4ANLA,#0FH0076C45SWAPA0077F5F06MOVB,A0079A37INCDPTR007AE08MOVXA,DPTR007B540F9ANLA,#0FH007D45F010ORLA,B007FA311INCDPTR,0080F012MOVXDPTR,A008180FE13PP1:SJMPPP114END四、实验操作运行前:7000H7001H7002H运行后:7000H7001H7002H,4,5,4,5,5,7,7,8,8,F,F,8,实验四数据排序实验一、实验目的熟悉51指令系统,掌握程序设计方法。二、实验内容编写并调试一个子程序,其功能为用冒泡法将内部RAM中几个单元字节无符号的正整数,按从小到大的次序重新排列。三、实验重新框图(略)四、实验步骤把51片内RAM区50H-5AH中放入不等的数据。用连续运行方式从起始地址0100H开始运行程序(输入0100后按EXEC键。,排序结束,显示P.。用寄存器读写方法检查50-5AH中内容应从小到大排列。五、思考修改程序把50H-5AH中内容应从大到小排列。六、实验程序,01001ORG0100H01007581602DORDE:MOVSP,#60H;设栈指针01037B503MOVR3,#50H0105EB4DORDE1:MOVA,R30106F85MOVR0,A;数据指针传送R001077F0A6MOVR7,#0AH;长度送R70109C2007CLR00H;清标志位010BE68MOVA,R0010C089DORDE2:INCR0010DFA10MOVR2,A010EC311CLRC;清进位标志010F862212MOV22H,R00111B5220113CJNEA,22H,DORDE3;相等否0114D314SETBC,0115EA15DORDE3:MOVA,R20116400616JCDORDE4;小于或等于不交换0118D20017SETB00H011AC618XCHA,R0;大于交换位置011B1819DECR0011CC620XCHA,R0011D0821INCR0011EE622DORDE4:MOVA,R0011FDFEB23DJNZR7,DORDE201212000E124JB00H,DORDE1;未完继续0124787E25MOVR0,#7EH;完关显示器前三位012674FF26MOVA,#0FFH01287C0627MOVR4,#06H012AF628DORDE5:MOVR0,A012B1829DECR0,012CDCFC30DJNZR4,DORDE5012E757E8C31MOV7EH,#8CH013112013632DORDE6:LCALLDISPD;循环调显示子程序013480FB33SJMPDORDE60136D2D434DISPD:SETB0D4H;显示子程序0138797E35MOVR1,#7EH013A7A2036MOVR2,#20H013C7B0037MOVR3,#00H013E90FF2138DISPD1:MOVDPTR,#0FF21H0141EA39MOVA,R20142F040MOVXDPTR,A0143E741MOVA,R1014490FF2242MOVDPTR,#0FF22H0147F043MOVXDPTR,A,0148DBFE44DISPD2:DJNZR3,DISPD2014A1945DECR1014BC346CLRC014CEA47MOVA,R2014D1348RRCA014EFA49MOVR2,A014F70ED50JNZDISPD1015174FF51MOVA,#0FFH015390FF2252MOVDPTR,#0FF22H0156F053MOVXDPTR,A0157C2D454CLR0D4H01592255RETEND,实验五查找相同数个数一、实验目的熟悉汇编语言编程。二、实验内容在7000H-700FH中查出有几个字节是零,统计“00”的个数在显示数码管上。三、实验程序框图(略)四、实验步骤在7000H-700FH的单元中放入随机数,其中几个单元中输入0。用连续方式从起始地址0160H开始运行程序,(输入0160后按EXEC键)。观察显示器上的内容,应显示00单元的个数。,实验六多分支程序一、实验目的掌握汇编语言的编程二、实验内容编写散转程序,根据51片内20H中的内容(00或01或02或03)进行散转。三、实验重新框图,A+散转首地址,(20H)A,0字循环,1字循环,2字循环,3字循环,开始,四、实验步骤51片内20H单元用寄存器读写方法写入00或01或02或03。从起始地址0250H开始运行程序(输入0250后按EXEC键)。观察数码管显示的内容(20H)=00时,显示“0”循环,(21H)=01时,显示“1”字循环。,硬件实验,实验一、P1口亮灯实验一、实验内容学习P1口使用方法学习延时子程序编写二、预备知识P1口为准双向口,必需向锁存器写入“1”,该位才能作为输入。延时采用指令循环实现,机器周期(12/6M)*指令所需机器周期数*循环次数,三、实验内容P1口做输出口,接8只LED,编程使LED循环点亮,每个LED停留1秒。四、程序框图,开始,P1口初始化,点亮1个LED,RL左移一位,LED循环,五、实验连线图,LED0,LED2,LED7,LED6,R1,R3,R8,R7,VCC,P1.1,P1.0,P1.2,P1.7,P1.6,8031,ORG07907590FFMOVP1,#0FFH079374FEMOVA,#0FEH0795F590LL:MOVP1,A07971207A0LCALLDELY079A23RLA079B80F8SJMPLLORG07A007A07EA0DELY:MOVR6,#0A0H07A27FFFLO36:MOVR7,#0FFH07A4DFFELO35:DJNZR7,LO3507A6DEFADJNZR6,LO36RETEND,实验二、查询P3.2管脚的输入一、实验目的掌握P3、P1口的使用。二、实验内容在P1口接八个发光二极管,使顺序发光。用P3.2的电平控制顺序发光的方向(查询方式),当P3.2为高电平时,向右顺序发光。当P3.2为低电平时,向左顺序发光。三、实验程序框图(略)四、实验接线图,K1,1K,5V,P3.3或P3.2,五、实验程序ORG8000H8000747FMOVA,#7FH(01H、80H、FEH)8002F590DISP:MOVP1,A8004128200LCALL:DELY800720B203JBP3.2LOP1800A23RLA800B80F5SJMPDISP800D03LOP1:RRA800E80F2SJMPDISPORG8200H82007A64DELY:MOVR2,#10082027B09DE2:MOVR3,#0282047C00DE1:MOVR4,#00H,820600DE0:NOP820700NOP8208DCFCDJNZR4,DE0820ADBFBDJNZR3,DE1820CDAF4DJNZR2,DE2820E22RETEND,实验三、继电器控制一、实验目的掌握用继电器控制的基本方法和编程。二、实验内容利用P1口输出高低电平,控制继电器的开合,以实现对外装置的控制。三、实验步骤在EXEC1上插上07芯片。把8031的P1.0插孔接到07芯片的第一脚,07芯片的第二脚接JIN端,继电器的J2(中心轴头)接地,JK常开开关接L1,JB常闭开关接L2。编制程序:使P1.0电平变化,低电平时继电器吸合,常开触点接上L1点亮,L2熄灭。高电平时继电器不工作,常闭触点闭合,L1熄灭,L2点亮。在P.状态下,从起始地址0C60H开始连续运行程序,L1L2交替亮灭。四、实验原理图由8031、7407、74LS240、继电器、L1L2发光二极管等。原理图如下:,五、实验程序ORG0C60H0C60D290START:SETBP1.00C62120C6CLCALLDELAY0C65C290CLRP1.00C67120C6CLCALLDELAY0C6A80F4SJMPSTART0C6C7FFFDELAY:MOVR7,#0FFH0C6E7EFFDELAY1:MOVR6,#0FFH0C70DEFEDELAY2:DJNZR6,DELAY20C72DFFADJNZR7,DELAY10C7422RETEND,实验四、P3.3口输入、P1口输出一、实验目的掌握P3.3口、P1口简单使用。学习延时程序的编写和使用。二、实验内容P3.3口做输入口,外接一脉冲,每输入一个脉冲,P1口按十六进制加一。P1口做输出口,编写程序,使P1口接的8个发光二极管L1-L8按16进制加一方式点亮发光二极管。三、实验说明,P1口是准双向口,它作为输出口时与一般的双向口使用方法相同,由准双向口结构可知:当P1口作为输入口时,必须先对它置高电平,使内部MOS管截止,因内部上拉电阻是20K-40K,故不会对外部输入产生影响。若不先对它置高,且原来是低电平,则MOS管导通,读入的数据是不正确的。延时子程序的延时计算问题。对于延时子程序DELAY:MOVR6,#00HDELAY1:MOVR7,#80HDZNZR7,DJNZR6,DELAY1,查表指令可知MOV、DJNZ指令均需用两个机器周期,而一个机器周期时间长度为12/6.0MHZ,所以该段指令执行时间为:(80+1)256+1)2(126000000)=132.1ms四、实验程序框图,R6设初值FFH,R7设初值FFH,R7-1=0否?,R6-1=0否?,返回,N,N,Y,延时子程序:,开始,循环,延时,A+1送P1口,P3.3为低吗?,P3.3真的为高吗?,P3.3为高吗?,延时,Y,Y,Y,N,N,N,主程序:,五、实验线路图,六、实验程序ORG0540H054074002HA1S:MOVA,#00H054220B3FD3HA1S1:JBP3.3,HA1S1;判P3.305457A204MOVR2,#10H05471205625LCALLDELAY;调延时子程054A20B3F56JBP3.3,HA1S1;P3.3为低054D7A207HA1S2:JNBP3.3,HA1S205507A208MOVR2,#10H05521205629LCALLDELAY055530B3F510JNBP3.3,HA1S2;判P3.3高05580411INCA0559C0E012PUSHACC,055BF413CPLA055CF59014MOVP1,A055ED0E015POPACC0560A14216AJMPHA1S1;循环0562C00217DELAY:PUSH02H0564C00218DELAY1:PUSH02H0566C00219DELAY2:PUSH02H0568DAFE20DELAY3:DJNZR2,DELAY3056AD00221POP02H056CDAF822DJNZR2,DELAY2056ED00223POP02H0570DAF224DJNZR2,DELAY10572D00225POP02H,0574D00226DJNZR2,DELAY05762227RET28END,实验五、8255控制交通灯,一、实验目的了解8255芯片的结构及编程方法,学习模拟交通灯控制的实现方法。二、实验内容用8255做输出口,控制十二个发光二极管熄灭,模拟交通灯管理。,三、实验说明1.因为本实验是交通灯控制实验,所以要了解实际交通灯的变化情况和规律。假设一个十字路口为东西南北走向。初始状态0为东西红灯,南北红灯。然后转状态1东西绿灯通车,南北红灯。2.过一段时间转状态2,东西绿灯灭,黄灯闪烁几次,南北仍然红灯。3.再转状态3,南北绿灯通车,东西红灯。4.过一段时间转状态4,南北绿灯灭,闪几次黄灯,延时几秒,东西仍然红灯。最后循环至状态1。四、实验程序框图,r,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!