第四章单片机的程序设计_第1页
第四章单片机的程序设计_第2页
第四章单片机的程序设计_第3页
第四章单片机的程序设计_第4页
第四章单片机的程序设计_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

第四章单片机的程序设计第一页,共二十五页,2022年,8月28日第04章:MCS51单片机的程序设计主要内容:汇编语句格式与伪指令简单程序与分支程序举例与分析循环程序举例与分析子程序举例(查表)C51初步(程序段例示)第二页,共二十五页,2022年,8月28日3、常用的典型子程序(掌握,能记能背!)顺序(直线)程序分支程序循环程序(单循环、多循环)散转子程序与参数传递查表程序数制转换数学运算程序第三页,共二十五页,2022年,8月28日4)散转程序设计

散转程序是分支程序的一种,它可根据运算结果或输入数据将程序转入不同的分支。

MCS-51指令系统中有一条跳转指令JMP@A+DPTR,用它可以很容易地实现散转功能。该指令把累加器的8位无符号数与16位数据指针的内容相加,并把相加的结果装入程序计数器PC,控制程序转向目标地址去执行。

此指令的特点在于,转移的目标地址不是在编程或汇编时预先确定的,而是在程序运行过程中动态地确定的。目标地址是以数据指针DPTR的内容为起始的256字节范围内的指定地址,即由DPTR的内容决定分支转移程序的首地址,由累加器A的内容来动态选择其中的某一个分支转移程序。第四页,共二十五页,2022年,8月28日例8(同例3):根据工作寄存器R0内容的不同,使程序转入相应的分支:

(R0)=0对应的分支程序标号为PR0;(R0)=1对应的分支程序标号为PR1;.........(R0)=N对应的分支程序标号为PRN。

程序如下:LP0:MOVDPTR,#TAB;取表头地址

MOVA,R0ADDA,R0;R0内容乘以2JNCLP1;无进位转移(可能R0>=128)

INCDPH;加进位位LP1:JMP@A+DPTR;跳至散转表中相应位置TAB:AJMPPR0AJMPPR1......AJMPPRN第五页,共二十五页,2022年,8月28日

本例程序仅适用于散转表首地址TAB和处理程序入口地址PR0,PR1,…,PRN在同一个2KB范围的存储区内的情形。若超出2KB范围可在分支程序入口处安排一条长跳转指令,可采用如下程序:

MOVDPTR,#TABMOVA,R0MOVB,#03H;长跳转指令占3个字节MULABXCHA,B;成绩的高8位送入A中

ADDA,DPH;对分支转移参数高位进行处理,把它加到DPH中去MOVDPH,A;修正DPTRXCHA,BJMP@A+DPTR;跳至散转表中相应的位置TAB:LJMPPR0;跳至不同的分支LJMPPR1……LJMPPRN第六页,共二十五页,2022年,8月28日5)子程序和参数传递

什么是子程序?

通常把一些基本操作功能编制为程序段作为独立的子程序,以供不同程序或同一程序反复调用。在程序中需要执行这种操作的地方放置一条调用指令,当程序执行到调用指令,就转到子程序中完成规定的操作,并返回到原来的程序继续执行下去。第七页,共二十五页,2022年,8月28日子程序是如何调用的?

调用子程序的指令有“ACALL”和“LCALL”,执行调用指令时,先将程序地址指针PC改变(“ACALL”加2,“LCALL”加3),然后PC值压入堆栈,用新的地址值代替。执行返回指令时,再将PC值弹出。子程序调用中,主程序应先把有关的参数存入约定的位置,子程序在执行时,可以从约定的位置取得参数,当子程序执行完,将得到的结果再存入约定的位置,返回主程序后,主程序可以从这些约定的位置上取得需要的结果,这就是参数的传递。第八页,共二十五页,2022年,8月28日

子程序编程与调用例9:试编写多字节加法子程序

分析:设这两个多字节数分别存放在起始地址为FIRST和SECOND的连续区域中(从低位字节开始存放),两个数的字节数存放在NUMBER单元中,最后求得的和存放在FIRST开始的区域中。现采用单字节加法指令进行多字节的加法运算,因此可用循环程序来实现。编写子程序,供其它程序调用:

FIRSTEQU08HSECONDEQU30HNUMBEREQU70HORG3000HAABB:MOVR0,#FIRST;置起始地址

MOVR1,#SECONDMOVR2,NUMBER;置计数初值CLRCLOOP:MOVA,@R0ADDCA,@R1;进行一次加法运算MOV@R0,A;存放结果INCR0;修改地址指针INCR1DJNZR2,LOOP;计数及循环控制

RET;子程序返回END这里使用了存储区域FIRST和SECOND以及存储单元NUMBER作为数据、结果交接区。第九页,共二十五页,2022年,8月28日

子程序编程与调用例9:试编写多字节加法子程序

分析:设这两个多字节数分别存放在起始地址为FIRST和SECOND的连续区域中(从低位字节开始存放),两个数的字节数存放在NUMBER单元中,最后求得的和存放在FIRST开始的区域中。现采用单字节加法指令进行多字节的加法运算,因此可用循环程序来实现。编写子程序,供其它程序调用:

FIRSTEQU08HSECONDEQU30HNUMBEREQU70HORG3000HAABB:MOVR0,#FIRST;置起始地址

MOVR1,#SECONDMOVR2,NUMBER;置计数初值CLRCLOOP:MOVA,@R0ADDCA,@R1;进行一次加法运算MOV@R0,A;存放结果INCR0;修改地址指针INCR1DJNZR2,LOOP;计数及循环控制

RET;子程序返回

END

这里使用了存储区域FIRST和SECOND以及存储单元NUMBER作为数据、结果交接区。子程序名第十页,共二十五页,2022年,8月28日分析:假设一个字节的16进制数在内部RAM的40H和41H单元,查表求得对应的两位ASCII并将结果存入50H、51H单元,可用堆栈进行参数传递1)子程序HEASC的功能:取出堆栈中的数据,查表将低半字节转换成ASCII送累加器A。2)分别将待转换数据入栈,然后调用子程序HEASC,程序如下:MAIN:MOVSP,#30H;设定SP指针PUSH40H;压栈

LCALLHEASC;调用将低半字节的内容;转换成ASCII码子程序HEASC

POPAMOV50H,A;存低半字节转换结果PUSH41H

LCALLHEASCPOPAMOV51H,A;存高半字节转换结果END;位置对吗????HEASC:

DECSPDECSP;SP指向十六进制数参数地址

子程序编程与调用例10:查表求出数据的ASCII码,再以字符形式输出。POPA;取入口参数… ;查表求ASCII码PUSHA;保存出口参数

INCSP;指向返回地址

INCSP RET

TAB:DB‘0’,‘1’,…;ASCII码表

第十一页,共二十五页,2022年,8月28日在编写子程序时,需要注意以下两点

1)保护现场与恢复现场(堆栈的使用)。子程序执行时,可能要使用累加器和某些工作寄存器。在调用子程序之前,这些寄存器中可能存放有主程序的中间结果,这些中间结果在子程序返回后可能仍需要使用。这就需要在子程序使用累加器和这些工作寄存器之前,先将其中的内容转移到安全区域保护起来,即保护现场。当子程序执行完后,即返回主程序之前,再将这些内容取出,送回到累加器和原来的工作寄存器中,这一过程称为恢复现场。2)数据连接点(参数传递)。例如,当要求sin45°时,可用正弦函数子程序。但在调用之前必须把45送到某一交接处,调用子程序后,子程序从交接处取回45,并求它们的正弦值。在正弦函数求出后,返回主程序之前必须把计算结果送到交接处。在返回主程序后,主程序从交接处取得结果。在通常情况下,常以累加器A作为数据交接寄存器,也可使用工作寄存器R0~R7。这在编写和调用子程序时必须统一。第十二页,共二十五页,2022年,8月28日6)查表程序设计

什么是查表程序?

查表程序是一种常用程序,它广泛使用于LED显示控制、打印机打印控制、数据补偿、数值计算、转换等功能程序中,这类程序具有简单、执行速度快等特点。所谓查表法,就是预先将满足一定精度要求的表示变量与函数值之间关系的一张表求出,然后把这张表存于单片机的程序存储器中,这时自变量值为单元地址,相应的函数值为该地址单元中的内容。查表,就是根据变量X在表格中查找对应的函数值Y,使Y=f(X)。

MCS-51指令系统中,有两条查表指令:MOVCA,@A+PCMOVCA,@A+DPTR第十三页,共二十五页,2022年,8月28日如何实现查表操作?

S1:将需要查表的首地址用MOV指令来装入数据指针DPTR,(用PC不需此步!)S2:然后再将需要查访表的项数用MOV指令装入累加器A中,S3:最后用MOVCA,@A+DPTR指令将查表中相应项的内容送累加器A中,这时A中的内容即为需要从表中查访到的内容。对于较短的表数据指针DPTR可装入一个常数。对于较长的表(项数超过256)或较复杂的数据处理,数据指针DPTR中的内容需要进行一些变换,有时需将DPTR拆开成DPH和DPL,用标准算术指令进行运算或修改。

MCS-51指令系统中,有两条查表指令:MOVCA,@A+PC;PC为当前指令的程序地址,不需另外赋值MOVCA,@A+DPTR第十四页,共二十五页,2022年,8月28日

查表子程序的编程例11:试编写:若累加器A中存放的是某一位十进制数的七段码,通过查表程序,将其转换为相应的BCD码,仍存在累加器A中。分析:设由于七段码不是有序码,其间排列没什么规律可循,因此不能用通常的查表程序那样一次查表求得。但仍可以列出一个七段码表,从第一个码开始取出并与A中的代码进行比较,同时记下比较次数,待到取出的代码与A中的代码一致时,停止继续比较。此时所记下的次数就是所要求的BCD码。

MOV R1,#00H;R1为计数器MOV B,AMOV DPTR,#KTAB;取KTAB所在位置的地址LOOP: MOV A,R1;从第零项开始查表

MOVC A,@A+DPTR

CJNE A,B,NEXT;若不等于源代码,则转移SJMP RESV;找到七段码的BCD值,退出LOOP循环NEXT: INC R1;计数器加1 SJMP LOOP;继续查表比较RESV: MOV A,R1;取得的BCD码送到Acc中

SJMP $;在当前指令上打转,while(1)KTAB: DB 40H,79H,24H;对应BCD码0、1、2、 DB 30H,19H,12H;3、4、5、 DB 02H,78H,00H,18H;6、7、8、9第十五页,共二十五页,2022年,8月28日查表子程序的编程例12:温度检测系统中,

温度模拟信号由10位A/D输入。试将A/D结果转换为对应温度值输出。分析:可采用查表方法实现。先由实验测试出整个温度量程范围内的A/D转换结果,把A/D转换结果000H~3FFH所对应的温度值组织为一个表存储在程序存储器中,那么就可以根据检测到的模拟量的A/D转换值查找出相应的温度值。

设测得的A/D转换结果已存入20H#,21H单元中(高位字节在20H中,低位字节在21H中),查表得到的温度值存放在22H#,23H单元(高位字节在22H中,低位字节在23H中)。源程序:FTMP:MOVDPTR,#TAB;DPTR←表首地址

MOVA,21H;(20H)(21H)×2 CLRC RLCA MOV21H,A MOVA,20HRLCA MOV20H,A MOVA,21H;表首地址+偏移量

ADDCA,DPL MOVDPL,AMOVA,20HADDCA,DPHMOVDPH,ACLRAMOVCA,@A+DPTR;查表得温度值高字节MOV22H,ACLRAINCDPTRMOVCA,@A+DPTR;查表得温度值低字节MOV23H,ARETTAB:DW…

第十六页,共二十五页,2022年,8月28日7)

中断服务子程序的编写数制转换编程实例例13:要求用P1口高4位P1.7~P1.4输入4个开关状态,每个开关K闭合用P1.3~P1.0输出驱动点亮指示灯。用INT1的中断程序将开关状态读入单片机内,经过高4位与低4位互换后再向P1.3~P1.0输出,灯发光顺序与开关顺序对应,要求利用INT1控制这个输入开关状态到输出显示过程。分析:在ISR中读入按键状态,用键值去驱动对应的LED发光。中断初始化:选择INT1负跳变触发中断(将TCON中IT1置1);开放中断INT1(使IE中的EX1和EA置1)第十七页,共二十五页,2022年,8月28日

ORG0000H;上电后PC=0000HLJMPSTART;上电后转主程序实际入口ORG0013H;INT1中断矢量地址LJMPISR_1;指向INT1中断程序实际入口地址

ORG1000H;主程序START:

SETBIT1;IT1=1,选INT1负跳变触发中断

SETBPX1;

PX1=1,选取INT1为高优先级

SETBEX1;允许INT1申请中断

SETBEA;允许总中断HERE:AJMPHERE;等待中断

;以下为INT1中断服务程序:ISR_1:MOVA,#0FFH;中断服务子程序MOVP1,A;准备读P1口引脚状态MOVA,P1;读P1口高四位开关状态SWAPA;P1口高、低4位交换MOVP1,A;输出开关状态,点灯RETI;返回断点

END第十八页,共二十五页,2022年,8月28日8)

数制转换程序数制转换编程实例例14:将一个字节二进制数转换成3位非压缩型BCD码HEXBCD:MOVA,40HMOVB,#100;100作为除数送入BDIVABMOV50H,A;A的商作为百位数送(50H)单元,余数在B中MOVA,#10;分离十位和个位数XCHA,B;余数送入A,除数10在B中DIVAB;分离十位在A中,个位在B中MOV51H,AMOV52H,BRET分析:二进制数转换成BCD码一般的方法是把二进制数除以1000、100、10等10的各次幂,所得到的商分别为BCD码的千位数、百位数、十位数,余数为个位数。单字节二进制数在0~255之间,设单字节二进制数在内部RAM40H单元,转换结果放入内部RAM50H,51H,52H单元中(高位在前)

第十九页,共二十五页,2022年,8月28日9)

数学运算程序网上可下载到相关的定点、浮点运算子程序库第二十页,共二十五页,2022年,8月28日本讲小结散转程序(多路分支程序的一种)

JMP@A+DPTR子程序与参数传递查表程序编程及典型应用

MOVCA,@A+PCMOVCA,@A+DPTR中断服务子程序编程数制转换子程序编程C51编程初步第二十一页,共二十五页,2022年,8月28日

2、编写8位十进制(BCD)码数加法子程序,设被加数存放在内部RAM的33H、32H、31H、30H单元,加数存在43H、42H、41H、40H单元,加数存在53H、52H、51H、50H单元,数由高位到低位排列,最高位进位位舍去

1、从20H单元开始存放一组带符号数,其数目已存在1FH单元,要求统计出其中大于0,等于0或小于0的数的数目,并把统计结果分别存放入ONE、TWO、THREE3个单元。第二十二页,共二十五页,2022年,8月28日例4、设在8031内部RAM中存一无符号数的数组,其长度为100,起始地址是30H,要求将它们从大到小排序,排序后仍存放在原区域中,试编者按程。解:先举四个数排序的例子

内RAM

第一次外循环

温馨提示

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

评论

0/150

提交评论