单片机原理与接口技术课件4_第1页
单片机原理与接口技术课件4_第2页
单片机原理与接口技术课件4_第3页
单片机原理与接口技术课件4_第4页
单片机原理与接口技术课件4_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

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

文档简介

MCS-51系列单片机的程序设计第四章

交叉汇编语言MASM51单片机汇编语言程序设计方法及技巧本章内容了解交叉汇编语言MASM51的特点掌握顺序程序、分支程序、循环程序、查表程序、子程序的基本设计方法和技巧学习目的掌握汇编语言程序设计的一般步骤4.1

交叉汇编语言MASM51

汇编语言源程序是由汇编指令和伪指令组成的文件,其扩展名为“ASM”。

源程序编辑完后只有转换为机器码表示的目标程序计算机才能执行,这个转换的过程称为汇编。

1)人工汇编人工汇编是通过人工查出源程序中所有汇编指令的机器码,并依次将机器码输入单片机中,使之成为单片机能直接执行的目标程序。2)机器汇编

机器汇编是指在计算机上通过汇编程序对源程序进行汇编,即从源程序到目标程序的转换过程是由计算机上的汇编程序自动完成的。3)交叉汇编

是指用一种计算机上的汇编程序去汇编另一种计算机的源程序,为另一种计算机产生目标程序。单片机MCS-51汇编语言程序设计步骤:

1分析问题

2确定算法

3设计程序流程图

4分配内存单元

5编写汇编语言源程序

6调试程序4.2程序设计方法及技巧4.2.1顺序程序设计例4.1请用MCS-51汇编指令编写程序,将片内RAM104、105单元中的内容分别传送到片外RAM104H、105H单元中。分析:应注意片内和片外的寻址指令不同ORG1000HMOVR0,#68HMOVA,@R0 ;片内RAM104单元内容送累加器MOVDPTR,#0104HMOVX@DPTR,A ;完成片内RAM104单元内容送片

;外104H单元中INCR0MOVA,@R0 ;片内RAM105单元内容送累加器INCDPTRMOVX@DPTR,A ;完成片内RAM105单元内容送片

;外105H单元中SJMP$ ;等待END ;结束1.简单分支程序YN

顺序执行条件满足?转向目标程序4.2.2分支程序设计图4.1简单分支程序转移分析:只要将两数进行比较,用比较的结果作为分支转移的条件就很容易地找出其中的大数。

已知片内RAMFIRST开始的两个单元中各存放有一个8位无符号二进制数,要求找出其中的大数并存入片内RAM的SECOND单元中。例4.2

ORG1000H CLRC MOVR0,#FRIST ;第一个数地址送R0中

MOVA,@R0 ;取第一个数

INCR0 ;R0指向第二个数地址

SUBBA,@R0 ;两数比较

JCBIG ;第二个数大转BIG DECR0 ;R0指向第一个数地址BIG: MOVSECOND,@R0;存大数

SJMP$;等待

END;结束参考程序2)多路分支程序(散转程序)K=n

K=n-1

K=2转向分支n-1转向分支2转向分支1转向分支nK=?

K=1

…图4.2多路分支程序转移1)把AJMP或LJMP指令组成一个分支程序的

转移表,表的首地址放入DPTR中;2)调整后的出口信息放入累加器A中;3)执行JMP@A+DPTR转向对应的分支程序。

可通过间接转移指令JMP@A+DPTR和无条件转移指令中的AJMP或LJMP指令来实现多路分支转移:例4.3

已知R0中存放有一数字关键码,要求根据码值的不同,分别转向对应的码值程序段去执行。即当(R0)=K时,便执行CODEK程序。

ORG1000HMOVDPTR,#TAB ;表首址送DPTRMOVA,R0 ;取数字关键码

ADDA,R0 ;每条AJMP指令占用两个字

;节,将出口信息乘2JNCLESS ;关键码小于128转LESSINCDPHLESS:JMP@A+DPTR

TAB:AJMPCODE0 ;关键码为0,转CODE0执行

AJMPCODE1 ;关键码为1,转CODE1执行

……AJMPCODE255 ;关键码为255,转CODE255

;执行

SJMP$ ;等待

END ;结束参考程序

AJMP指令的转移范围不超出所在的2KB字节区间,如各小段程序较长,在2KB字节内无法全部容纳,上面的程序应该怎样修改?思考1)循环初始化

设置循环的初始状态,位于循环程序的开头位置2)循环处理

循环程序的主体部分,是通过反复执行来完成数据的具体处理,它位于循环体内。4.2.3循环程序设计循环程序由4部分组成:3)循环控制

也在循环体内,是用于控制循环的继续与否。4)循环结束

通常位于循环体后,是用来存放循环处理的最终结果及恢复各寄存器与工作单元的原始值。

设MCS-51单片机内部RAM从40H开始的连续16个单元中,每个单元中分别存放有单字节的带符号数。要求将其中的正数存入50H开始的连续单元中,负数存入60H开始的连续单元中,并将正数、负数和零的个数分别存入70H、71H、72H单元中。例4.41) 带符号数的最高位为符号位,可通过 最高位判断正负:“0”表示正数,“1” 表示负数。2) 程序中需要从40H单元开始取源数, 存正数和负数,故需要三个地址指针 来指向对应的内存单元;设对应的地 址指针分别为R0、R1和R2,由于R2

不能用间接寻址方式,故R2需要同R1

或R0进行交换后,才能进行负数的存 放。

分析参考程序:

ORG1000HCLRAMOV70H,A ;存放正数的个数单元清0MOV71H,A ;存放负数的个数单元清0MOV72H,A ;存放零的个数单元清0MOVR3,#10H ;设循环计数器初值

MOVR0,#40H ;设源数地址指针

MOVR1,#50H ;设正数地址指针

MOVR2,#60H ;设负数地址指针LOOP:MOVA,@R0 ;取源数

JZ

ZERO

;源数为0,转ZER0JNBACC.7,POSI

;源数为正,转POSI

INC71H ;负数个数加1MOVR4,A ;暂存原数

MOVA,R2XCHA,R1 ;R1与R2中的内容交换

XCHA,R4MOV@R1,A ;存负数

XCHA,R4XCHA,R1 ;R1与R2中的内容交换

INCR2 ;调整负数地址指针

SJMP

LOOP1

;转循坏控制POSI:INC70H ;正数个数加1MOV@R1,A ;存正数

INCR1 ;调整正数地址指针

SJMPLOOP1ZERO:INC72H ;零的个数加1LOOP1:INCR0 ;调整源数地址指针

DJNZR3,LOOP ;未送完,继续

SJMP$ ;等待

END ;结束查表指令有:

MOVCA,@A+DPTRMOVCA,@A+PC

查表就是把事先计算或测得的数据按照一定的顺序编制成表格存放在存储器中,然后根据输入的数据,从表格中查出所需的结果。4.2.4查表程序设计

当DPTR作基址寄存器时,注意:①基址值(表格首地址)→DPTR;②变址值(表中要查的项与表格首地址之间的间隔字节数)→A;注意:

用查表程序求0~40之间整数的立方。已知该整数存在内RAM30H中,查得立方数存内RAM30H(高8位)31H。已知立方表(双字节)首地址为TAB。例

CUBE: MOVDPTR,#TAB;置立方表首址

MOVA,30H ;读数据

ADDA,30H ;数据×2→A MOV30H,A ;暂存立方表数据序号

MOVCA,@A+DPTR;读立方数据高8位

XCHA,30H;存立方数据高8位,立方表数据序号→A INCA ;指向立方数据低8位

MOVCA,@A+DPTR;读立方数据低8位

MOV31H,A ;存立方数据低8位

RET;TAB:DW0,0,0,1,0,8,0,27,0,64;0~40立方表

DW0,125,0,216,…,0FAH,00H;说明:数据×2→A原因是立方表数据为双字节片内RAM的EGA单元中有一个大写的英文字母,要求将此字母在英文字母表中的位置送入片内的COUNT单元中,如EGA单元中字母为I时,则COUNT单元中需送入数字9。例4.6如果将26个英文字母按照顺序编成一个表,通过查表法得到一个字母与EGA单元中的字母比较,若不相等再查,同时记录查表的次数。查完后,将记录次数送COUNT单元。分析参考程序

ORG1000HEGAEQU50HCOUNTEQU60HMOVCOUNT,#00HMOVA,#16H ;调整地址LOOP:PUSHAMOVCA,@A+PC;查表

CJNZA,EGA,NF ;所查字母与EGA中字母比较

SJMPLAST ;相等转LASTNF:POPAINCA ;调整地址

INCCOUNT ;记数值加1SJMPLOOP ;继续查LAST:INCCOUNT ;记数值加1SJMP$ ;等待ALPT:DB‘A’,‘B’,…,‘Y’,‘Z’END ;结束

求y=n!(n=0,1,…9),已知n的值在片内NUM单元中,y值用BCD码表示且存放在片内GETY开始的单元中。

例4.6

分析:将函数值列成表,采用查表法求y=n!

当n=9时,y=362880H,需要三个单元存放结果。设每个n对应的y值都用3个单元来存放,则y值在表格中的首地址的计算公式为:y地址=函数表首址+n*3参考程序

ORG1000HNUMEQU50HGETYEQU60HMOVR1,#03HMOVR0,#GETYMOVA,NUM;取n值

MOVB,#03HMULAB;n*3MOVR2,A;暂存

MOVDPTR,#TAB;表的首地址送DPTR中LOOP:MOVCA,@A+DPTR ;查表

MOV@R0,A ;存结果

INCR0 ;调整存放结果地址指针

INCDPTR ;修正表地址指针

MOVA,R2 ;恢复n*3DJNZR1,LOOP ;未查完,继续

SJMP$ ;等待

END ;结束TAB:DB01H,00H,00H,01H,00H,00HDB02H,00H,00H,06H,00H,00HDB24H,00H,00H,20H,01H,00HDB20H,07H,00H,40H,50H,00HDB20H,03H,04H,80H,28H,36H编写子程序时应注意:a.子程序的第一条指令之前必须有标号;b.子程序中需要保护现场;c.主程序和子程序之间的参数传递。4.2.5子程序设计1)数码转换子程序

已知R0的低半个字节为一个四位的二进制数,要求将其转换为ASCAII码后送回R0中。例4.7二进制码转换为ASCII码二进制数与ASCII码的对应关系:

四位二进制

ASCII

0000(0)30H0001(1)31H1001(9)39H1010(A)41H

1111(F)46H…………参考程序

ORG1000BTOASC: PUSHA ;保护现场

PUSHPSW ;保护现场

MOVA,R0ANLA,#0FH ;取四位二进制数

MOVR0,A ;暂存

CLRCSUBBA,#0AH;与10比较

MOVA,R0 ;恢复四位二进制数

JCLOOP ;小于10转LOOPADDA,#07H ;大于10先加07HLOOP: ADDA,#30H ;加30HMOVR0,A ;存结果

POPPSW ;恢复现场

POPA ;恢复现场

RET ;返回

已知片内BLOCKB单元开始处有一数据块,块长在R2中,在此数据块的每个单元中存放有一个未组合的BCD码,要求将每个BCD码转换为ASCAII码,并存放在片内BLOCKA开始的连续单元中。例4.8BCD码转换为ASCAII码将一位BCD码转换为ASCAII码的子程序:TRANS: MOVA,@R0 ;取BCD码

ADDA,#30H MOV@R1,A ;送ASCAII码

INCR0 INCR1 RET ;返回分析:将一位BCD码转换为相应的ASCAII码只需加上30H即可。

主程序:

ORG1000HMOVR2,#LMOVR0,#BLOCKB ;设BCD码的地址指针

MOVR1,#BLOCKA ;设ASCAII的地址指针LOOP:ACALLTRANS ;调用TRANS子程序

DJNZR2,LOOP ;未转换完,继续

SJMP$ ;等待

END ;结束

设片内40H单元中有一组合的BCD码,要求将其转换为二进制数存回原处。分析:

1)组合的BCD码为两位十进制数,需将十位 数和个位数分开处理。

2)十位数转换时只要累加0AH就能将其转换 为相应的二进制数,然后再将个位数直接 加到转换后的十位数上就可完成整个数的 转换。例4.9BCD码转换为二进制数参考程序

ORG1000BCDTOB: MOVA,40H ANLA,#F0H ;取十位数

SWAPA ;将十位数换到低4位

JZDONE ;十位数为0,返回

MOVR3,#00H ;累加和寄存器清0LOOP: DECA

ACALLADD0AH ;调用加10子程序

JNZLOOP ;未加完继续

MOVA,40H ANLA,#0FH ;取个位数

ADDA,R3 ;与十位相加

MOV40H,A ;转换完,存结果DONE: RET

;(书上此处有错)

已知片内RAMADR1开始的单元依次从低位到高位存放有L个字节的无符号数,片外RAMADR2开始的单元也依次从低位到高位存放有L个字节的无符号数。请编一个加法程序,将他们的和存放在ADR1开始的连续单元中。2)算术运算子程序例4.11多字节无符号数相加R0:片内RAM地址指针,初值为ADR1DPTR:片外RAM地址指针,初值为ADR2每完成一个字节的加法后,R0、DPTR各自加1,调整为加数、被加数下一待加字节的地址。R2:计数器。存放待加的字节数,每完成一个字节的加法后,内容减1,当R2=0时,程序结束。开始#ADR1→(R0)#ADR2→(DPRTR)#L→(R2)C清零((R0))+((DPTR))→(A)(A)→((R0))(R0)+1→(R0)(R1)+1→(R1)(R2)-1→(R2)(R2)=0?YN出口初始化设初值循环体工作部分修改循环体参数判别程序流程框图:参考程序

ORG1000HNSADD:MOVR0,#ADDR1 ;设被加数的地址指针

MOVDPTR,#ADDR2 ;设加数的地址指针

MOVR2,#L ;设循环计数器初值

CLRCLOOP:MOVXA,@DPTR ;取加数

ADDCA,@R0 ;两数相加

MOV@R0,A ;存和

INCR0 ;调整被加数地址指针

INCDPTR ;调整加数地址指针

DJNZR2,LOOP ;未加完,继续

RET ;返回已知被乘数和乘数分别为双字节的无符号数,被乘数的高字节和低字节分别存放在R7和R6中,乘数的高字节和低字节分别存放在R5和R4中。要求乘积存放在片内RAM以ADR开始的单元中。分析:由于只有单字节乘法指令,双字节的乘法需要分作4次乘法运算才能实现。例4.15两双字节无符号数相乘

a

b

cdbdHbdLadHadLbcHbcLacHacL@R0+3@R0+2@R0+1@R0

×b×da×db×ca×c积+R7R6R5R4ORG1000HMUL1:MOV40H,#00H ;统计bdH+adL+bcL

;的进位单元清0MOV41H,#00H ;统计adH+bcH+acL

;的进位单元清0MOVR0,#50H ;积的首地址送R0中

MOVA,R6 ;b送AMOVB,R4 ;d送BMULAB ;b

dMOV@R0,A ;bdL送50H单元中

MOVR1,B

;bdH送R1中R1参考程序

MOVA,R7 ;a送AMOVB,R4 ;d送BMULAB ;adMOVR2,A ;adL送R2中

MOVR3,B ;adH送R3中

MOVA,R6 ;b送AMOVB,R5 ;c送BMULAB ;bcADDA,R2 ;bcL+adL

JNCNEXT1 ;无进位转NEXT1INC40H ;统计进位NEXT1:ADDA,R1 ;bcL+adL+bdH

JNCNEXT2 ;无进位转NEXT2INC40H ;统计进位NEXT2:INCR0MOV@R0,A;存bcL+adL+bdH结果于51H单元中R3R1R2

MOVR1,B;bcH存R1中

MOVA,R7;a送AMOVB,R5;c送B

MULAB;a

c

ADDA,40H;acL加低位进位

JNCNEXT3;无进位转NEXT3INC41H;统计进位NEXT3:ADDA,

R1

;acL+bcH

JNCNEXT4;无进位转NEXT4INC41H;统计acL+bcH进位NEXT4:ADDA,

R3

;acL+bcH+adH

INCR0MOV@R0,A;存acL+bcH+adH的结果于52H单元中

MOVA,BADDCA,41H;acH加低位进位

INCR0MOV@R0,A;积最高位存53H单元中

RET;返回R1R3

1.用硬件电路实现2.定时器实现3.软件延时定时(或延时)方法:3)延时程序不需另添硬件,且变化灵活。软件延时:利用计算机执行程序耗用的时间来实现延时,又称“延时程序”。优点:延时过程中占用CPU,所以不宜设计太长的延时程序。缺点:

DELAY1:MOVR1,#0AH;1DL2:MOVR2,#18H;1DL1:NOP;1NOP;1DJNZR2,DL1;2DJNZR1,DL2;2RET;2

机器周期内循环外循环例:设计一延时程序,延时时间为1ms。若MCS-51单片机系统采用12M晶振,则Tcy=1us内循环一次需要4个机器周期,共循环18H=24次延时时间:

[1+(1+4×24+2)×10+2]Tcy=993us1ms延时程序常设计为子程序,以便频繁调用。【例】编写延时10ms子程序,fosc=12MHz。

解:fosc=12MHz,一个机器周期为1s。DY10ms:MOVR6,#20;置外循环次数DLP1:MOVR7,#250;置内循环次数DLP2:DJNZR7,DLP2;2机周×250=500机周

DJNZR6,DLP1;500机周×20=10000机周

RET;说明:MOVRn指令为1个机器周期;DJNZ指令为2个机器周期;RET指令为2个机器周期;{[(2机周×250)+1+2]×20+1+2}×1s/机周=10063

s≈10ms【课堂练习题】

按下列要求编写延时子程序:⑴延时2ms,fosc=6MHz;⑵延时5ms,fosc=12MHz;⑶延时10s,fosc=12MHz;4.2汇编语言程序设计复习课堂练习1:

两个无符号双字节数相加。

设被加数存放于内部RAM的40H(高位字节),41H(低位字节),加数存放于50H(高位字节),51H(低位字节),和数存入40H和41H单元中。

程序如下:START:CLRC;将Cy清零

MOVR0,#41H;将被加数地址送数据指针R0MOVR1,#51H;将加数地址送数据指针R1AD1:MOVA,@R0;被加数低字节的内容送入AADDA,@R1;两个低字节相加MOV@R0,A;低字节的和存入被加数低字节中

DECR0;指向被加数高位字节

DECR1;指向加数高位字节

MOVA,@R0;被加数高位字节送入AADDCA,@R1;两个高位字节带Cy相加

MOV@R0,A;高位字节的和送被加数高位字节

RET课堂练习2

将两个半字节数合并成一个一字节数。设内部RAM40H,41H单元中分别存放着8位二进制数,要求取出两个单元中的低半字节,并成一个字节后,存入50H单元中START:MOVR1,#40H;设置R1为数据指针MOVA,@R1;取出第一个单元中的内容ANLA,#0FH;取第一个数的低半字节SWAPA ;移至高半字节INCR1 ;修改数据指针XCHA,@R1 ;取第二个单元中的内容ANLA,#0FH;取第二个数的低半字节ORLA,@R1 ;拼字MOV50H,A ;存放结果RET课堂练习3x#,y均为8位二进制数,设x存入R0,y存入R1,求解:程序如下:START:CJNER0,#00H,SUL1;R0中的数与00比较不等转移

MOVR1,#00H;相等,R1←0SJMPSUL2SUL1:JCNEG;两数不等,若(R0)<0,转向

温馨提示

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

评论

0/150

提交评论