《第四章单片机的程序设计.ppt》由会员分享,可在线阅读,更多相关《第四章单片机的程序设计.ppt(25页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第四章单片机的程序设计现在学习的是第1页,共25页第第04章:章:MCS51单片机的程序设计单片机的程序设计主要内容:l汇编语句格式与伪指令l简单程序与分支程序举例与分析l循环程序举例与分析l子程序举例(查表)lC51初步(程序段例示)现在学习的是第2页,共25页3、常用的典型子程序(掌握,能记能背!)l顺序(直线)程序l分支程序l循环程序(单循环、多循环)l散转l子程序与参数传递l查表程序l数制转换l数学运算程序现在学习的是第3页,共25页4)散转程序设计散转程序设计 散散转转程程序序是是分分支支程程序序的的一一种种,它它可可根根据据运运算算结结果果或或输输入入数数据据将将程程序序转转入入不
2、同的分支。不同的分支。MCS MCS-51 51 指指令令系系统统中中有有一一条条跳跳转转指指令令JMP JMP A+DPTRA+DPTR,用用它它可可以以很很容容易易地地实实现现散散转转功功能能。该该指指令令把把累累加加器器的的8 8 位位无无符符号号数数与与 16 16 位位数数据据指指针针的的内内容容相相加加,并并把把相相加加的的结结果装入程序计数器果装入程序计数器PC,PC,控制程序转向目标地址去执行。控制程序转向目标地址去执行。此此指指令令的的特特点点在在于于,转转移移的的目目标标地地址址不不是是在在编编程程或或汇汇编编时时预预先先确确定定的的,而而是是在在程程序序运运行行过过程程中
3、中动动态态地地确确定定的的。目目标标地地址址是是以以数数据据指指针针 DPTRDPTR的的内内容容为为起起始始的的 256 256 字字节节范范围围内内的的指指定定地地址址,即即由由 DPTRDPTR的的内内容容决决定定分分支支转转移移程程序序的的首首地地址址,由由累累加加器器A A的内容来动态选择其中的某一个分支转移程序。的内容来动态选择其中的某一个分支转移程序。现在学习的是第4页,共25页例例8(8(同例同例3)3):根据工作寄存器根据工作寄存器R0 内容的不同内容的不同,使程序转入相应的分支:使程序转入相应的分支:(R0)=0 对应的分支程序标号为对应的分支程序标号为PR0;(R0)=1
4、 对应的分支程序标号为对应的分支程序标号为PR1;.(R0)=N 对应的分支程序标号为对应的分支程序标号为PRN。程序如下程序如下:LP0:LP0:MOV DPTR,MOV DPTR,TAB ;TAB ;取表头地址取表头地址 MOV A,R0 MOV A,R0 ADD A,R0 ;R0 ADD A,R0 ;R0内容乘以内容乘以2 2 JNC LP1 ;JNC LP1 ;无进位转移无进位转移 (可能可能R0=128)R0=128)INC DPH ;INC DPH ;加进位位加进位位LP1:LP1:JMP A+DPTR;JMP A+DPTR;跳至散转表中相应位置跳至散转表中相应位置TAB:AJMP
5、 PR0TAB:AJMP PR0 AJMP PR1 AJMP PR1 .AJMP PRN AJMP PRN 现在学习的是第5页,共25页 本本例例程程序序仅仅适适用用于于散散转转表表首首地地址址TAB和和处处理理程程序序入入口口地地址址 PR0,PR1,PRN在在同同一一个个 2 KB范范围围的的存存储储区区内内的的情情形形。若若超超出出 2 KB范范围围可可在在分分支支程程序序入入口口处处安安排一条长跳转指令排一条长跳转指令,可采用如下程序可采用如下程序:MOV DPTR,TABMOV A,R0 MOV B,03H ;长跳转指令占长跳转指令占 3 个字节个字节MUL ABXCH A,B;成绩
6、的高成绩的高8位送入位送入A中中 ADD A,DPH;对分支转移参数高位进行处理,把它对分支转移参数高位进行处理,把它加到加到DPH中去中去MOV DPH,A;修正修正DPTRXCH A,BJMP A+DPTR;跳至散转表中相应的位置跳至散转表中相应的位置TAB:LJMP PR0;TAB:LJMP PR0;跳至不同的分支跳至不同的分支 LJMP PR1LJMP PR1 LJMP PRN LJMP PRN 现在学习的是第6页,共25页5)5)子程序和参数传递子程序和参数传递 什么是子程序?什么是子程序?通通常常把把一一些些基基本本操操作作功功能能编编制制为为程程序序段段作作为为独独立立的的子子程
7、程序序,以以供供不不同同程程序序或或同同一一程程序序反反复复调调用用。在在程程序序中中需需要要执执行行这这种种操操作作的的地地方方放放置置一一条条调调用用指指令令,当当程程序序执执行行到到调调用用指指令令,就就转转到到子子程程序序中中完完成成规规定定的的操操作作,并返回到原来的程序继续执行下去。并返回到原来的程序继续执行下去。现在学习的是第7页,共25页子程序是如何调用的?子程序是如何调用的?调调用用子子程程序序的的指指令令有有“ACALLACALL”和和“LCALLLCALL”,执执行行调调用用指指令令时时,先先将将程程序序地地址址指指针针PCPC改改变变(“ACALLACALL”加加2,2
8、,“LCALLLCALL”加加3 3),然然后后 PCPC值值压压入入堆堆栈栈,用用新新的的地地址址值代替。执行返回指令时值代替。执行返回指令时,再将再将 PCPC值弹出。值弹出。子子程程序序调调用用中中,主主程程序序应应先先把把有有关关的的参参数数存存入入约约定定的的位位置置,子子程程序序在在执执行行时时,可可以以从从约约定定的的位位置置取取得得参参数数,当当子子程程序序执执行行完完,将将得得到到的的结结果果再再存存入入约约定定的的位位置置,返返回回主主程程序序后后,主主程程序序可可以以从从这这些些约约定定的的位位置置上上取取得得需要的结果需要的结果,这就是这就是参数的传递。参数的传递。现在
9、学习的是第8页,共25页 子程序编程与调用子程序编程与调用 例例9:试编写多字节加法子程序试编写多字节加法子程序 分析:设这两个多字节数分别存放在起始地址为分析:设这两个多字节数分别存放在起始地址为FIRST和和SECOND的连续区域中(从低位字节开始的连续区域中(从低位字节开始存放),两个数的字节数存放在存放),两个数的字节数存放在NUMBER单元中,最后求得的和存放在单元中,最后求得的和存放在FIRST开始的区域中。现采用开始的区域中。现采用单字节加法指令进行多字节的加法运算,因此可用循环程序来实现。单字节加法指令进行多字节的加法运算,因此可用循环程序来实现。编写子程序,供其它程序调用编写
10、子程序,供其它程序调用:FIRST EQU 08H SECOND EQU 30H NUMBER EQU 70H ORG 3000HAABB:MOV R0,#FIRST ;置起始地址置起始地址 MOV R1,#SECOND MOV R2,NUMBER;置计数初值置计数初值 CLR C LOOP:MOV A,R0 ADDC A,R1 ;进行一次加法运算进行一次加法运算 MOV R0,A ;存放结果存放结果 INC R0 ;修改地址指针修改地址指针 INC R1 DJNZ R2,LOOP ;计数及循环控制计数及循环控制 RET ;子程序返回子程序返回 END 这里使用了存储区域这里使用了存储区域FI
11、RST 和和SECOND以及存储单元以及存储单元NUMBER作为数据、结果交接区。作为数据、结果交接区。现在学习的是第9页,共25页 子程序编程与调用子程序编程与调用 例例9:试编写多字节加法子程序试编写多字节加法子程序 分析:设这两个多字节数分别存放在起始地址为分析:设这两个多字节数分别存放在起始地址为FIRST和和SECOND的连续区域中(从低位字节开始存的连续区域中(从低位字节开始存放),两个数的字节数存放在放),两个数的字节数存放在NUMBER单元中,最后求得的和存放在单元中,最后求得的和存放在FIRST开始的区域中。现采用开始的区域中。现采用单字节加法指令进行多字节的加法运算,因此可
12、用循环程序来实现。单字节加法指令进行多字节的加法运算,因此可用循环程序来实现。编写子程序,供其它程序调用编写子程序,供其它程序调用:FIRST EQU 08H SECOND EQU 30H NUMBER EQU 70H ORG 3000HAABB:MOV R0,#FIRST ;置起始地址置起始地址 MOV R1,#SECOND MOV R2,NUMBER;置计数初值置计数初值 CLR C LOOP:MOV A,R0 ADDC A,R1 ;进行一次加法运算进行一次加法运算 MOV R0,A ;存放结果存放结果 INC R0 ;修改地址指针修改地址指针 INC R1 DJNZ R2,LOOP ;计
13、数及循环控制计数及循环控制 RET ;子程序返回子程序返回 END 这里使用了存储区域这里使用了存储区域FIRST 和和SECOND以及存储单元以及存储单元NUMBER作为数据、结果交接区。作为数据、结果交接区。子程序名现在学习的是第10页,共25页分分析析:假假设设一一个个字字节节的的1616进进制制数数在在内内部部RAMRAM的的40H40H和和41H41H单单元元,查查表表求求得得对对应应的的两两位位ASCIIASCII并并将将结结果果存入存入50H50H、51H51H单元,可用堆栈进行参数传递单元,可用堆栈进行参数传递 1 1)子子程程序序HEASCHEASC的的功功能能:取取出出堆堆
14、栈栈中中的的数数据据,查查表表将将低低半半字字节节转转换换成成ASCIIASCII送送累累加加器器A A。2 2)分别将待转换数据入栈)分别将待转换数据入栈,然后调用子程序然后调用子程序HEASC,HEASC,程序如下程序如下:MAIN:MOV SP,30H;设定设定SP指针指针 PUSH 40H ;压栈压栈 LCALL HEASC ;调用将低半调用将低半字节的内容字节的内容 ;转换转换成成ASCII码子程序码子程序HEASC POP A MOV 50H,A ;存低半字节转换结果存低半字节转换结果 PUSH 41H LCALL HEASC POP A MOV 51H,A ;存高半字节转换结果存
15、高半字节转换结果END;位置对吗?位置对吗?HEASC:DEC SP DEC SP ;SP 指向十六进制数参数地址 子程序编程与调用子程序编程与调用 例例10:查表求出数据的查表求出数据的ASCII码码,再以字符形式输出。再以字符形式输出。POP A ;取入口参数取入口参数 ;查表求ASCII码 PUSH A;保存出口参数 INC SP;指向返回地址 INC SP RET TAB:DB 0,1,;ASCII码表 现在学习的是第11页,共25页在编写子程序时,需要注意以下两点在编写子程序时,需要注意以下两点 1)保护现场与恢复现场(堆栈的使用)保护现场与恢复现场(堆栈的使用)。子程序执行时,可能
16、要使用累加器和某些。子程序执行时,可能要使用累加器和某些工作寄存器。在调用子程序之前,这些寄存器中可能存放有主程序的中间结工作寄存器。在调用子程序之前,这些寄存器中可能存放有主程序的中间结果,这些中间结果在子程序返回后可能仍需要使用。这就需要在子程序使用果,这些中间结果在子程序返回后可能仍需要使用。这就需要在子程序使用累加器和这些工作寄存器之前,先将其中的内容转移到安全区域保护起来,累加器和这些工作寄存器之前,先将其中的内容转移到安全区域保护起来,即保护现场。当子程序执行完后,即返回主程序之前,再将这些内容取出,即保护现场。当子程序执行完后,即返回主程序之前,再将这些内容取出,送回到累加器和原
17、来的工作寄存器中,这一过程称为恢复现场。送回到累加器和原来的工作寄存器中,这一过程称为恢复现场。2)数据连接点(参数传递)数据连接点(参数传递)。例如,当要求。例如,当要求sin45时,可用正弦函数子程序。但时,可用正弦函数子程序。但在调用之前必须把在调用之前必须把45送到某一交接处,调用子程序后,子程序从交接处取回送到某一交接处,调用子程序后,子程序从交接处取回45,并求它们的正弦值。在正弦函数求出后,返回主程序之前必须把计算结,并求它们的正弦值。在正弦函数求出后,返回主程序之前必须把计算结果送到交接处。在返回主程序后,主程序从交接处取得结果。在通常情况下,果送到交接处。在返回主程序后,主程
18、序从交接处取得结果。在通常情况下,常以累加器常以累加器A作为数据交接寄存器,也可使用工作寄存器作为数据交接寄存器,也可使用工作寄存器R0R7。这在编写和这在编写和调用子程序时必须统一。调用子程序时必须统一。现在学习的是第12页,共25页6)6)查表程序设计查表程序设计 什么是查表程序?什么是查表程序?查表程序是一种常用程序查表程序是一种常用程序,它广泛使用于它广泛使用于 LED显示控制、显示控制、打印机打印控打印机打印控制、数据补偿、数值计算、转换等功能程序中制、数据补偿、数值计算、转换等功能程序中,这类程序具有简单、执行速度快等这类程序具有简单、执行速度快等特点。特点。所谓查表法所谓查表法,
19、就是预先将满足一定精度要求的表示变量与函数值之间关就是预先将满足一定精度要求的表示变量与函数值之间关系的一张表求出系的一张表求出,然后把这张表存于单片机的程序存储器中然后把这张表存于单片机的程序存储器中,这时自变量值为单元地这时自变量值为单元地址址,相应的函数值为该地址单元中的内容。查表相应的函数值为该地址单元中的内容。查表,就是根据变量就是根据变量 X在表格中查找对应的在表格中查找对应的函数值函数值 Y,使使 Y=f(X)。MCS-51指令系统中指令系统中,有两条查表指令有两条查表指令:MOVC A,A+PC MOVC A,A+DPTR现在学习的是第13页,共25页如何实现查表操作?如何实现
20、查表操作?S1:将需要查表的首地址用:将需要查表的首地址用MOV指令来装入数据指针指令来装入数据指针DPTR,(用(用PC不需此步!)不需此步!)S2:然后再将需要查访表的项数用:然后再将需要查访表的项数用MOV指令装入累加器指令装入累加器A中,中,S3:最后用:最后用MOVC A,A+DPTR指令将查表中相应项的内容送累加器指令将查表中相应项的内容送累加器A中,中,这时这时A中的内容即为需要从表中查访到的内容。中的内容即为需要从表中查访到的内容。对于较短的表数据指针对于较短的表数据指针DPTR可装入一个常数。对于较长的表(项数超过可装入一个常数。对于较长的表(项数超过256)或)或较复杂的数
21、据处理,数据指针较复杂的数据处理,数据指针DPTR中的内容需要进行一些变换,有时需将中的内容需要进行一些变换,有时需将DPTR拆开成拆开成DPH和和DPL,用标准算术指令进行运算或修改。用标准算术指令进行运算或修改。MCS-51指令系统中指令系统中,有两条查表指令有两条查表指令:MOVC A,A+PC;PC为当前指令的程序地址,不需另外赋值为当前指令的程序地址,不需另外赋值 MOVC A,A+DPTR现在学习的是第14页,共25页 查表子程序的编程查表子程序的编程 例例11:试编:试编写写:若累加器若累加器A中存放的是某一位十进制数的七段码,中存放的是某一位十进制数的七段码,通过查表程序,将其
22、转换为相应的通过查表程序,将其转换为相应的BCD码,仍存在累加器码,仍存在累加器A中。中。分析:设由于七段码不是有序码,其间排列没什么规律可循,因此不能用通常的查表程分析:设由于七段码不是有序码,其间排列没什么规律可循,因此不能用通常的查表程序那样一次查表求得。但仍可以列出一个七段码表,从第一个码开始取出并与序那样一次查表求得。但仍可以列出一个七段码表,从第一个码开始取出并与A中的代中的代码进行比较,同时记下比较次数,待到取出的代码与码进行比较,同时记下比较次数,待到取出的代码与A中的代码一致时,停止继续比较。此时所记中的代码一致时,停止继续比较。此时所记下的次数就是所要求的下的次数就是所要求
23、的BCD码。码。MOVR1,#00H;R1为计数器为计数器 MOVB,A MOVDPTR,#KTAB ;取取KTAB所在位置的地址所在位置的地址LOOP:MOVA,R1;从第零项开始查表;从第零项开始查表 MOVCA,A+DPTR CJNEA,B,NEXT;若不等于源代码,则转移;若不等于源代码,则转移 SJMP RESV ;找到七段码的找到七段码的BCD值,退出值,退出LOOP循环循环NEXT:INCR1;计数器加;计数器加1SJMPLOOP;继续查表比较;继续查表比较RESV:MOVA,R1 ;取得的取得的BCD码送到码送到Acc中中SJMP$;在当前指令上打转,在当前指令上打转,whil
24、e(1)KTAB:DB40H,79H,24H ;对应对应BCD码码0、1、2、DB30H,19H,12H ;3、4、5、DB02H,78H,00H,18H;6、7、8、9现在学习的是第15页,共25页 查表子程序的编程查表子程序的编程 例例12:温度检测系统中:温度检测系统中,温度模拟信号由温度模拟信号由 10 10 位位A/DA/D输入。输入。试将试将A/DA/D结果转换为对应温度值输出。结果转换为对应温度值输出。分析:分析:可采用查表方法实现。可采用查表方法实现。先由实验测试出整个温度量程范围内的先由实验测试出整个温度量程范围内的A/D转换结果转换结果,把把A/D转换转换结果结果000H3
25、FFH所对应的温度值组织为一个表存储在程序存储器中所对应的温度值组织为一个表存储在程序存储器中,那么就可以根据检测到那么就可以根据检测到的模拟量的的模拟量的 A/D转换值查找出相应的温度值。转换值查找出相应的温度值。设测得的设测得的A/DA/D转换结果已存入转换结果已存入20H#,21H20H#,21H单元中(高位字节在单元中(高位字节在20H20H中中,低位字节在低位字节在21H21H中)中),查表得到查表得到的温度值存放在的温度值存放在22H#,23H22H#,23H单元(高位字节在单元(高位字节在 22H22H中中,低位字节在低位字节在23H23H中)中)。源程序源程序:FTMP:MOV
26、 DPTR,TAB;DPTR表首地址表首地址 MOV A,21H;(20H)()(21H)2 CLR C RLC A MOV 21H,A MOV A,20H RLC A MOV 20H,A MOV A,21H ;表首地址表首地址+偏移量偏移量 ADDC A,DPL MOV DPL,AMOV A,20HADDC A,DPHMOV DPH,ACLR AMOVC A,A+DPTR;查表得温度值高字节查表得温度值高字节 MOV 22H,A CLR A INC DPTR MOVC A,A+DPTR;查表得温度值低字查表得温度值低字节节MOV 23H,A RETTAB:DW 现在学习的是第16页,共25页
27、7)7)中断服务子程序的编写中断服务子程序的编写数制转换编程实例数制转换编程实例 例例13:要求用要求用P1口高口高4位位P1.7P1.4输入输入4个开关状态,每个开个开关状态,每个开关关K闭合用闭合用P1.3P1.0输出驱动点亮指示灯。输出驱动点亮指示灯。用用INT1的中断程序将开关状态读入单片机的中断程序将开关状态读入单片机内,经内,经过高过高4位与低位与低4位互换后再向位互换后再向P1.3P1.0输出,输出,灯发光顺序与开关顺序对应,要求利用灯发光顺序与开关顺序对应,要求利用INT1控制这个输入开关状态到输出显示过程。控制这个输入开关状态到输出显示过程。分析:在分析:在ISR中读入按键状
28、态,用键值去驱动对中读入按键状态,用键值去驱动对应的应的LED发光。发光。中断初始化:中断初始化:选择选择INT1负跳变触发中断负跳变触发中断(将(将TCON中中IT1置置1);开放中断);开放中断INT1(使(使IE中的中的EX1 和和EA置置1)现在学习的是第17页,共25页 ORG 0000H;上电后;上电后PC=0000H LJMP START;上电后转主程序实际入口;上电后转主程序实际入口 ORG 0013H;INT1中断矢量地址中断矢量地址 LJMP ISR_1;指向;指向INT1中断程序实际入口地址中断程序实际入口地址 ORG 1000H;主程序;主程序 START:SETB I
29、T1;IT1=1,选,选INT1负跳变触发中断负跳变触发中断 SETB PX1;PX1=1,选取,选取INT1为高优先级为高优先级 SETB EX1;允许允许INT1申请中断申请中断 SETB EA;允许总中断允许总中断HERE:AJMP HERE;等待中断等待中断 ;以下为以下为INT1中断服务程序:中断服务程序:ISR_1:MOV A,#0FFH;中断服务子程序中断服务子程序 MOV P1,A;准备读;准备读P1口引脚状态口引脚状态 MOV A,P1;读;读P1口高四位口高四位P1.7P1.4开关状态开关状态 SWAP A;P1口高、低口高、低4位交换位交换 MOV P1,A;输出开关状态
30、,点灯;输出开关状态,点灯 RETI ;返回断点;返回断点 END现在学习的是第18页,共25页8)8)数制转换数制转换程序程序数制转换编程实例数制转换编程实例 例例14:将一个字节二进制数转换成将一个字节二进制数转换成 3 位非压缩型位非压缩型BCD码码HEXBCD:MOV A,40H MOV B,100;100作为除数送入作为除数送入B DIV AB MOV 50H,A;A的商作为百位数送(的商作为百位数送(50H)单元,)单元,余数在余数在B中中 MOV A,10;分离十位和个位数分离十位和个位数 XCH A,B;余数送入余数送入A,除数,除数10在在B中中 DIV AB;分离十位在分离
31、十位在A中,个位在中,个位在B中中 MOV 51H,A MOV 52H,B RET 分分析析:二二进进制制数数转转换换成成BCDBCD码码一一般般的的方方法法是是把把二二进进制制数数除除以以10001000、100100、1010等等1010的的各各次次幂幂,所所得得到到的的商商分分别别为为BCDBCD码码的的千千位位数数、百百位位数数、十十位位数,余数为个位数。数,余数为个位数。单单字字节节二二进进制制数数在在0255之之间间,设设单单字字节节二二进进制制数数在在内内部部RAM 40H单单元元,转转换换结结果果放放入入内内部部RAM 50H,51H,52H单单元元中中(高高位位在前)在前)现
32、在学习的是第19页,共25页9)9)数学运算数学运算程序程序网上可下载到相关的定点、浮点运算子程序库现在学习的是第20页,共25页本讲小结本讲小结l散转程序(多路分支程序的一种)JMP A+DPTRl子程序与参数传递l查表程序编程及典型应用 MOVC A,A+PC MOVC A,ADPTRl中断服务子程序编程l数制转换子程序编程lC51编程初步现在学习的是第21页,共25页 2、编写8位十进制(BCD)码数加法子程序,设被加数存放在内部RAM的33H、32H、31H、30H单元,加数存在43H、42H、41H、40H单元,加数存在53H、52H、51H、50H单元,数由高位到低位排列,最高位进
33、位位舍去 1、从20H单元开始存放一组带符号数,其数目已存在1FH单元,要求统计出其中大于0,等于0或小于0的数的数目,并把统计结果分别存放入ONE、TWO、THREE3个单元。现在学习的是第22页,共25页例4、设在8031内部RAM中存一无符号数的数组,其长度为100,起始地址是30H,要求将它们从大到小排序,排序后仍存放在原区域中,试编者按程。解:先举四个数排序的例子 内RAM 第一次外循环 第二次外循环 第三次外循环 30H 0 0 0 3 0 3 0 6 31H 0 3 0 2 0 6 0 3 32H 0 2 0 6 0 2 0 2 33H 0 6 0 0 0 0 0 0共4 1=3
34、 次外循环现在学习的是第23页,共25页这就是所谓的“冒泡法”。4个数排序最多经过 3 次外循环就可排出,每次外循环都包含3次内循环。实际上大多情况不用 3 次外循环就可排完。对于100个数排序也是如此,用不到99次循环,排序就结束。为了提高排序速度,程序中可设一交换标志位,如10H位,每次循环中:若有交换则 SETB 10H 若无交换则 CLR 10H 每次循环结束时,测10H位,判断排序是否结束。现在学习的是第24页,共25页 ORG 1000HBUBBLE:MOV R0,#30H MOV B,#64H CLR 10H DEC B ;长度计数 LOOP:MOV A,R0 ;内循环的入口 MOV 20H,A ;暂存,为交换作准备 INC R0 MOV 21H,R0 CJNE A,21H,BUEU ;若(20H)(21H)转移 现在学习的是第25页,共25页