4单片机嵌入式系统原理及应用(贾好来)单片机的程序设计基础.ppt
《4单片机嵌入式系统原理及应用(贾好来)单片机的程序设计基础.ppt》由会员分享,可在线阅读,更多相关《4单片机嵌入式系统原理及应用(贾好来)单片机的程序设计基础.ppt(126页珍藏版)》请在课桌文档上搜索。
1、1,第4章 8051单片机程序设计基础,语言:汇编还是C?,确定了单片机,另一个老生常谈的争论就不得不面对了,学汇编还是C好?现在很多宣传一味鼓吹C语言的好,似乎“万恶的汇编”早就该下地狱了。这种观点是有失偏颇的。客观的讲,汇编语言和C语言各有特点。汇编语言的本质是机器码,是直接和单片机对话的唯一途径。优点是效率高,缺点是难以驾驭。C语言的逻辑性更强,优点是只要掌握了语言本身编程就变得简单,而且移植性好。缺点是即使你写出了程序,完成了功能,但是对单片机本身的了解还是很少。,2,实际开发中大多会使用C语言,汇编语言在较为复杂的工程面前还是显得很无力。但是汇编语言在学习单片机的过程中却很有用,想要
2、真正懂得单片机的内部奥妙,还得借助汇编语言这个窗口。因此,学习的正确流程应该是:先通过汇编语言将单片机硬件资源掌握透彻,C语言仅是一门语言,对硬件了解清楚的基础之上再学习C语言,很容易上手。,3,主要内容,4.1 汇编语言程序结构4.2 算术运算程序设计4.3 C51基础4.4 C51和汇编语言的混合编程,4,4.1 汇编语言程序结构,4.1.1简单程序结构4.1.2分支结构4.1.3循环结构4.1.4子程序及其参数传递方法4.1.5中断服务程序*4.1.6 前后台结构*4.1.7 并行结构,5,4.1.1简单程序结构,简单结构程序执行时,从第一条指令开始顺序执行,直到最后一条指令为止。它是构
3、成较大、较复杂程序的最基本的结构。但它本身只能完成一些简单的任务,所以叫做简单程序。,6,例4.1将单字节BCD码转换成二进制数,ORG 100H MOV R2,#28H;要转换的BCD数送入R2,入口 MOV A,R2 ANL A,#0F0H;屏蔽低4位,取高4位 SWAP A;高低4位交换 MOV B,#10 MUL AB;210 MOV R3,A;乘积送R3保存,7,MOV A,R2ANL A,#0FH;取低4位ADD A,R3;2108送AMOV R3,A;结果1CH送R3 END;程序结束,8,例4.2 双字节移位,将30H、31H单元存放的无符号数除2,商仍在原单元中,余数送入CY
4、中。由于8051指令系统中只有单字节移位指令,故双字节移位需要分步进行,只给出程序段。,9,CLR C MOV A,30H RRC A MOV 30H,A MOV A,31H RRC A MOV 31H,A,10,4.1.2分支结构,在大量的实用程序中,需要对某些指令的执行结果进行判断,根据判断的结果决定程序的走向。判断后有“是”和“非”两种结果,程序也就有两种可能的执行方向,也就是程序产生了分支,形成了分支结构。改变程序的执行顺序有两种方法:一是事先安排好的,程序执行到某条指令后转去执行指定的指令。这是通过无条件转移指令来实现的;第二种就是根据程序执行的结果来决定转移到何处去。这是通过条件转
5、移指令来实现的,分支程序就属这种情况。,11,转移指令都有条件测试功能,根据测试后的结果来确定是否转移,条件成立则转移,否则执行下一条指令。例4.3 给定8位有符号数X,求符号函数Y。所谓符号函数,即当X0时,Y为1,当X0时,Y等于-1,而当X=0时,Y=0。这是一个典型的分支程序。,12,13,图4-1 例4.3程序流程图,ORG 100H START:MOV R0,#30H;存放有符号数的地址指针;30H送R0,而(30H)=X MOV A,R0;(A)X ANL A,R0;做与运算,出标志 JZ ZERO;判(A)=0否?(A)=0,转ZERO,(A)非0,;下一条 JNB ACC.7
6、,NEXT;(A)的最高位不是1,即为正数,转;标号NEXT,如是1,执行下一条 MINUS:MOV R1,#0FFH;(A)的最高位是1,即为负数,;(R1)=-1 SJMP EXIT;转出口 ZERO:MOV R1,#0;(R1)0 SJMP EXIT;转出口 NEXT:MOV R1,#1;(R1)=1,即R1做为出口Y=1 EXIT:SJMP EXIT;原地踏步,14,4.1.3循环结构,一个程序若包含多次重复执行的程序段,则称为循环结构。循环程序和分支程序都是非顺序结构程序,但它们在程序走向和所实现的功能上是不同的。先看实例:,15,例4.4 求存放在片内RAM 20H单元开始的10个
7、无符号数的最小值,ORG 100H MOV R0,20H;置地址指针 MOV R7,10;计数器初值 MOV A,R0;取第一个数 DEC R7;实际的比较次数LOOP:INC R0;修改地址指针 MOV 40H,R0;取后一个数 CJNE A,40H,NEXT;前数与后数比较,16,17,NEXT:JC LOPP1;前一个数小,不交换 MOV A,40H;前一个数大,把后一个数送A LOPP1:DJNZ R7,LOOP;计数器减1,不为0转LOOP MOV 41H,A;循环结束,最小值送;41H单元 HERE:SJMP$;$指HERE标号,踏步 END,18,图42 例4.4程序流程图,19
8、,循环程序的构成,设置初值部分,进入循环之前要给出初始状态,称为初始化,一般包括建立计数器,设置地址指针及其他变量的初值。初值又分为循环工作部分的初值和循环结束条件的初值。循环工作部分,这是循环结构的基本部分,也叫循环体,是为重复执行任务编写的程序段。循环控制部分,控制循环的次数,一般包括修改计数器,修改指针,检测循环结束条件等。结束部分用于分析和存储结果。,20,图4-3 循环程序流程图,如果循环工作部分又包含新的循环程序,称为循环嵌套,如出现多次嵌套,就称为多重嵌套。而循环工作部分不包含另外的循环体就称为单重循环。,21,单重循环和多重循环,单重循环及其控制方法,控制循环的方法有多种,这里
9、只介绍其中的三种。当循环次数已知时,利用计数器控制循环最方便。当循环次数未知时,可采用按实际条件控制循环,或采用逻辑尺的方法。,22,例4.5 求存放于首地址为20H单元的多个学生考试成绩之和。这个问题可利用成绩是正数的特点,在成绩数据区后放一个负数作为结束条件。ORG 1000HSTART:MOV R0,#20H;首地址指针 MOV R1,#0 MOV R2,#0,23,LOOP:MOV A,R0;取第1个数 JB ACC.7,DONE;是负数,结束循环 ADD A,R1 JNC NEXT INC R2NEXT:INC R0 MOV R1,A SJMP LOOPDONE:SJMP$,24,用
10、逻辑尺控制循环,例4.6 若单片机进行8路巡回检测,采集的数据要用不同的函数加以处理。设第0、3、5路用FUNC1处理,而1、2、4、6、7路用FUNC2处理,这样在一个循环中包括两个支路,可使用一个二进制位串来控制程序沿那一个位串来循环,本题的位串设计为11010110,0表示用FUNC1处理,1表示用FUNC2处理,这个二进制位串称为逻辑尺。其长度根据需要可为一字节,或多字节。程序运行时,可将逻辑尺移位,判断是0还是1,以决定对数据如何处理。程序流程如图4-4所示。,25,26,图4-4 用逻辑尺控制循环,多重循环,如果在一个循环体中又包含了其他的循环程序,即循环中还套着循环,这种程序称为
11、多重循环程序。例4.7 10秒延时程序。延时程序与MCS-51执行指令的时间有关,如果使用12MHz晶振,一个机器周期为1s计算出执行一条指令以至一个循环所需要的时间,给出相应的循环次数,便能达到延时的目的。,27,DEL:MOV R5,#100DEL0:MOV R6,#200DEL1:MOV R7,#248;248*2+1=497个机器周期DEL2:DJNZ R7,DEL2;(248*2+1+2)*200+1=99801个机器周期 DJNZ R6,DEL1;(248*2+1+2)*200+2)*100+1+2s DJNZ R5,DEL0 RET,28,4.1.4子程序及其参数传递方法,在实际
12、程序中,常常会多次进行一些相同的计算和操作。如数制转换、函数式计算等等。如果每次都从头开始编制一段程序,不仅麻烦,而且浪费存储空间。因而对一些常用的程序段以子程序的形式,事先存放在存储器的某一个区域。当主程序在运行时,需要用子程序时,只要执行调用子程序的指令,使程序转至子程序。当子程序处理完毕,返回主程序,继续进行以后的操作。,29,30,调用子程序的优点:(1)避免了对相同程序段的重复编制。(2)简化程序的逻辑结构,同时也便于子程序调试。(3)节省存储器空间。,8051指令系统中,提供了两条调用子程序指令ACALL及LCALL,并提供了一条返回主程序的指令RET。ACALL:子程序距离本指令
13、的距离不超过2KLCALL:子程序距离本指令的距离在64K内子程序的调用,包含两个部分:保护现场和恢复现场。,31,参数传递,调用子程序时,主程序应先把有关的参数存放在约定的位置,子程序在执行时,可以从约定的位置取得参数,当子程序执行完,将得到的结果存入约定的位置,返回主程序后,主程序可以从这些约定的位置读取到需要的结果,这就是参数的传递。,32,用累加器或寄存器进行参数的传递,用累加器和寄存器存放输入参数及结果参数,可以提高程序的运算速度,而且程序也很简单。其不足之处是参数不能传递得很多,因为寄存器的数量有限;主程序在调用子程序前必须将参数先送入寄存器;由于子程序参数的个数是固定的,故主程序
14、不能任意设定参数的多少。,33,用指针寄存器进行参数的传递,当程序中所需处理的数据量比较大时,常常用存储器存放数据,而不用寄存器。用指针指示数据在存储器中所处的位置,可以大大节省参数传递中的工作量,使用指针的方法能实现数据长度可变的运算。8051指令系统中提供的由R0、R1作间址寄存器的指令很多,当参数存放在内部RAM时,用R0、R1作指针,使参数的传递十分方便。当参数在外部RAM或在程序存储器时,可用DPTR作指针。对可变长度运算时,数据长度可由寄存器指出,也可采用在数据后设置标志的办法。,34,用堆栈进行参数传递,堆栈可以用于主程序调用子程序时相互之间的参数传递。调用前,主程序用PUSH指
15、令把参数压入堆栈,子程序在执行中按堆栈指针间接访问栈中参数,并且把运算结果送回堆栈。返回主程序后,主程序用POP指令得到堆栈中的结果参数。利用堆栈传递参数的方法比较简单,而且传递参数量比用寄存器来传递参数多得多,也不必为特定的参数分配存储单元。,35,例4.8 一位16进制数转换成ASCII码,HEASC:MOV R0,SP;借用R0,为堆栈指针 DEC R0 DEC R0;R0指向被转换参数地址 XCH A,R0;保护累加器,取被转换参数 ANL A,#0FH ADD A,#2;表首地址 MOVC A,A+PC;查表 XCH A,R0;结果送回堆栈 RETATAB:DB 30H,31H,32
16、H,39H DB 41H,46H,36,例4.9 把内部RAM中40H单元一字节的16进制数转换成两位ASCII码,存放在R1指出的两个单元中,调用HEASC子程序。,程序如下:HEX_TO_ASCII:MOV A,40H;直接寻址,(40H)A SWAP A;两位16进制数半字节交换 PUSH ACC ACALL HEASC POP ACC,37,MOV R1,A;高半字节转换成ASCII码存结果 INC R1 PUSH 40H ACALL HEASC POP ACC MOV R1,A;低半字节转换成ASCII码存结果 RET END,38,4.1.5中断服务程序,中断服务程序对实时事件请求
17、作必要的处理,使系统能实时地并行完成各个操作,中断服务程序必须包括现场保护、中断服务、现场恢复、中断返回4个部分。中断服务程序编写方法与子程序类似,同时应注意以下问题:(1)在中断程序的结尾一定要使用RETI,以便返回到主程序中断处。(2)中断服务程序中要清除中断标志,以免重复进入。具体标志和清除方法参见各中断部分。,39,(3)中断服务程序的长度应尽量短小,以免执行时占用CPU过多时间。所以主程序与中断服务程序之间的数据交换多采用标志位。(4)中断嵌套深度受堆栈区的影响。系统复位后,栈指针SP的初始值为07H,与工作寄存器区重叠,所以程序中一般要重新定义。AT89S52内部虽有256B的RA
18、M,但堆栈需利用低128B开辟,所以其堆栈深度有限。,40,4.1.6 前后台结构,41,4.1.7 并行结构(多任务结构),一个系统可以实现多任务的轮转调度,并允许“准并行”地执行多个循环或任务。任务不是同时执行,而是以时间片(time slice)调度执行。操作系统OS(Operation System)将可用的CPU时间划分成若干时间片,为每个任务指定一个时间片,每个任务允许在预先规定的一段时间内执行。然后,OS切换到另一个就绪的任务,使这个任务也执行一段时间。时间片是很短的,通常是几个毫秒。因此,任务看起来是同时执行的。,42,4.2 算术运算程序设计,4.2.1 不带符号的多字节加法
19、4.2.2 双字节二进制无符号数乘法4.2.3 码制转换程序4.2.4 查表程序,43,4.2.1不带符号的多字节加法,不带符号的多字节二进制数定点加法程序在处理多字节运算时,应注意低字节向高字节的进位(或借位),用进位位CY判别,当CY=0时表示无进位或借位,反之则表示有进位或借位。在进行不带符号的单字节二进制数加减运算时,用进位CY判别和溢出与否。例4.11 两个多字节数P、Q均以低字节在前,高字节在后的次序,分别存放在由R0、R1指出的内部RAM中,相加后存入P数据区。,44,ORG 1000H STAT1:CLR C;清进位 MOV R2,#N;取字节数MADD:MOV A,R0;取加
20、数(一个字节)ADDC A,R1;两数相加(由低字节开始)MOV R0,A INC R0 INC R1 DJNZ R2,MADD;两数加完?JCERR;和字节数大于N,则溢出 RET ERR:N EQU 0AH END,45,4.2.2双字节二进制无符号数乘法,将(R2R3)和(R6R7)中双字节无符号数相乘,结果送R4R5R6R7。本子程序使用累加器A、寄存器R0、R2R7及标志CY。子程序及其框图如图4-5所示。NMUL:MOV R4,#0;0R4R5 MOV R5,#0 MOV R0,#16;16位计数器R0 CLR C NMLP:MOV A,R4;右移一位 RRC A MOV R4,A
21、,46,47,图4-5 NMUL子程序框图,MOV A,R5 RRC A MOV R5,A MOV A,R6 RRC A MOV R6,A MOV A,R7 RRC A MOV R7,A JNC NMLN;C为移出的乘数最低位 MOV A,R5;执行加法 ADD A,R3 MOV R5,A MOV A,R4 ADDC A,R2 MOV R4,ANMLN:DJNZ R0,NMLP;循环16次,MOV A,R4;最后结果再右移位 RRC A MOV R4,A MOV A,R5 RRC A MOV R5,A MOV A,R6RRC AMOV R6,AMOV A,R7RRC AMOV R7,ARET,
22、48,4.2.3 码制转换程序,例4.13 ASCII码到BCD码的转换。设ASCII字符置于工作寄存器R2中,转换结果放在R3中(高4位为0)。为提高程序的容错性,若转换结果9,R3为FFH。例如,ASCII码39H转换为BCD码应为9。,49,ASCII_TO_BCD:MOV A,R2 CLR C SUBB A,30H MOV R3,A JC ERR SUBB A,0AH JC ENNDERR:MOV R3,#0FFH;转换结果0,或;10置出错标志ENND:SJMP$END,50,例4.14 BCD数到二进制数之间的转换。n+1位的BCD数可表示为(AnAn-1A1A0)BCD=An10
23、n+An-110n-1+A1101+A0=(An10+An1)10+An-2)10+A1)10+A0可以根据此式编制转换程序,为方便编程,从BCD数的高位做起。下面是双字节BCD数到二进制数的转换程序。;功能:将4位BCD数转换为二进制数;入口:BCD码为R5(千位,百位),R4(十位,个位)。;出口为R5R4,为16位无符号数二进制整数。;使用资源:累加器ACC、寄存器R5、R4、B、R2、R6、R3、进位标志C,51,BCD4B:MOV A,R5 MOV R2,A ACALL BCD2B MOV B,#64H MUL AB MOV R6,A XCH A,B MOV R5,A MOV A,R
24、4 MOV R2,A ACALL BCD2B ADD A,R6 MOV R4,A MOV A,R5 ADDC A,#00H MOV R5,A RET,52,BCD2B:MOV A,R2ANL A,#0F0H SWAP A MOV B,#0AH MUL AB MOV R3,A MOV A,R2 ANL A,#0FH ADD A,R3 MOV R2,A RET,4.2.4 查表程序,查表是一种常用的非数值操作,利用查表可以使复杂的计算简单化,并能完成如数据补偿、转换、检索、实现程序的多分支转移等多种功能。有简单查表和查表散转两种。,53,简单查表程序,利用指令MOVC A,A+DPTR 查表例如,
25、查表求输入数据X的函数值Y=f(X),假设表在ROM中,首地址为TAB;X的取值为1,2,N-1,N;对应的Y值存放地址为TABX;X,Y均占一个字节,输入数据X(X值在累加器A中),查表结果仍存于A MOV DPTR,TAB MOVC A,ADPTR TAB:DB,54,用MOVC A,APC指令查表,将16进制数0F转换成ASCII码,程序入口在A,出口仍在A中 HASC2:INC A MOVC A,APC HASC22:RET ASCTAB:DB 30H,31H,32H,33H DB 34H,35H,36H,37H,38H DB 39H,41H,42H,43H,44H DB 45H,46
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 嵌入式 系统 原理 应用 贾好来 程序设计 基础
链接地址:https://www.desk33.com/p-236058.html