1、,Microcontrollers Principle and Applications,单片机原理及应用,C,上节内容回顾,MCS51单片机的指令 数据传送类(28条) 算术运算类(24条) 逻辑运算类(25条) 控制转移类(17条) 位操作类(17条),第8-9讲教学目的和要求,【教学目标】通过讲述MCS-51单片机的汇编语言程序设计的基本步骤、基本方法,使学生对指令系统有进一步的认识和理解,同时使得学生掌握使用汇编语言进行程序设计的方法,通过实例加以巩固。 【教学重点】单片机程序设计的基本方法;查表、差值运算、译码等简单程序设计方法; 【教学难点】如何将实际问题转换成单片机能识别和解决的
2、问题,第五章 MCS-51的汇编语言程序设计,5.3.2 分支结构,指令执行时,根据不同的情况执行不同的程序段。,单分支 双分支 多分支,双分支结构,设变量x以补码的形式存放在片内RAM的30H单元,变量y与x的关系是: 当x0时,y=x; 当x=0时,y=20H; 当x0时,y=x+5。 编制程序,根据x的大小求y并送回30H单元。,判断结果为0,可通过执行JZ rel来实现 判断补码的正负,可通过最高位来判断 先与,保留最高位,再判断结果是否为零来实现,双分支结构,设变量x以补码的形式存放在片内RAM的30H单元,变量y与x的关系是: 当x0时,y=x; 当x=0时,y=20H; 当x0时
3、,y=x+5。 编制程序,根据x的大小求y并送回30H单元。,双分支结构,START:MOV A, 30H ;取x至累加器JZ NEXT ;x = 0,转NEXTNEXT:MOV 30H,#20H DONE: SJMP $END,ANL A, #80H ;否,保留符号位 JZ DONE ;x 0,转结束,MOV A, #05H ;x 0处理 ADD A, 30H MOV 30H, A ;X+05H送Y,SJMP DONE,5.3.3 循环结构,按某种控制规律重复执行的程序称为循环程序。循环程序有先执行后判断和先判断后执行两种基本结构。,例1 延时程序,编写一段延时50ms的程序 若晶振频率为1
4、2MHz,则一个机器周期为1s,延时50ms,则程序的执行时间为50000个机器周期。 立即数取指在0255之间,可考虑200*250=50000。 需要用到减1,结果不为0则重复的指令。 执行一条DJNZ指令需要2个机器周期,即 2s。采用循环计数法实现延时,需要用到双重循环。,延时程序,DEL: MOV R7,#200 ;1 s DEL1:NOP ; 1 s DEL1: MOV R6,#? ;1 sNOP ;1 s DEL2:DJNZ R6,DEL2 ;2sDJNZ R7,DEL1 ;2s,DEL1: MOV R6,#123 ;1 s,共计 (21232 2)200+1 s,即50.001
5、ms,例2 未知次数的循环,将内部RAM中起始地址为data的数据串传送到外部RAM中起始地址为buffer的存储区域内,直到发现$ 字符停止传送。,问题 何时终止传送? 对取出的数进行与S进行比较,判断是否相等。 用CJNE,例2 未知次数的循环程序,将内部RAM中起始地址为data的数据串传送到外部RAM中起始地址为buffer的存储区域内,直到发现$ 字符停止传送。,MOV R0,#data MOV DPTR,#buffer LOOP: MOV A,R0 CJNE A,$,继续执行地址结束,LP:MOVX DPTR,AINC R0INC DPTRSJMP LOOP LP2: SJMP $
6、END,SJMP LP2,CJNE A,$,LP,5.4 子程序及其调用,在实际应用中,经常会遇到一些带有通用性的问题,在一个程序中可能要使用多次。这时可以将其设计成通用的子程序供随时调用,减少代码冗余。 一个程序中可以多次调用一个子程序 多个程序可以调用一个子程序 子程序可以调用子程序,最多支持8级 调用子程序时,单片机能自动保存PC内容,遇RET返回时,能自动恢复PC,子程序结构,子程序编写完成后,使用 ACALL 函数名(短距离调用) LCALL 函数名(整个ROM区调用) 此处的函数名,实际上是一个标号,编译后形成具体的地址。 子程序的处理过程中,可能要影响PSW、ACC,以及其他的一
7、些功能寄存器,若这些影响是子程序功能的一部分,则无需保护;否则,一定要保护现场,使得主程序得以正确执行。,通过堆栈进行现场的保护,SUB1:PUSH PSW ;保护现场 PUSH ACC ;PUSH B ; MOV PSW,#10H ;换当前工作寄存器组 POP B ;恢复现场POP ACC ;POP PSW ;RET,注意: 保护和恢复的工作在子程序中进行。 保护与恢复的顺序要对应。,子程序结构,子程序参数的传递。 调用子程序时,语句中无法携带子程序运行所需的参数。 明确子程序的功能后,对子程序使用的参数,应在调用之前完成数据的赋值等工作。 类似乘法指令MUL AB,必须在此指令之前将AB赋
8、值,运算才有意义。,子程序举例,编写程序,实现c=a2+b2 。设a,b,c分别存于内部RAM的30H,31H,32H三个单元中 如何求数的平方 MUL AB 左移 查表,方法1:直接相乘,START:MOV A,30H ;取aACALL SQR ;调用乘法MOV R1,A ;a2 暂存于R1中MOV A,31H ;取bACALL SQR ;调用查平方表ADD A,R1 ;a2+b2 存于A中MOV 32H,A ;存结果SJMP $SQR :PUSH PSWMOV B,AMUL AB;POP PSWRET,方法2:左移1次,START:MOV A,30H ;取aACALL SQR ;调用乘法M
9、OV R1,A ;a2 暂存于R1中MOV A,31H ;取bACALL SQR ;调用查平方表ADD A,R1 ;a2+b2 存于A中MOV 32H,A ;存结果SJMP $SQR :PUSH PSWRL APOP PSWRET,方法3:查表,START:MOV A,30H ;取aACALL SQR ;调用乘法MOV R1,A ;a2 暂存于R1中MOV A,31H ;取bACALL SQR ;调用查平方表ADD A,R1 ;a2+b2 存于A中MOV 32H,A ;存结果SJMP $SQR :MOV DPTR,#TAB ;子程序MOVC A,A+DPTR ;RET TAB :DB 0,1,
10、4,9,16 ,25,36,49,64,81DB ,5.5 综合举例,设有一串字符,依次存放在内部RAM从30H单元开始的连续单元中,该字符串以0AH为结束标识(0AH不计入字符长度),编写程序,统计该字符串个数,将该数放入累加器A中。,MOV R1,#30HMOV R0,#00HLP:CJNE R1,#0AH,NESJMP ED NE:INC R0INC R1SJMP LP ED: MOV A,R0SJMP $END,改进,MOV R1,#30HMOV R0,#00HLP:CJNE R1,#0AH,NESJMP ED NE:INC R0INC R1SJMP LP ED: MOV A,R0SJ
11、MP $END,MOV R1,#2FHMOV R0,#0FFH NE:INC R0INC R1LP:CJNE R1,#0AH,NEMOV A,R0SJMP $END,综合举例,设在30H和31H单元中各有一个8位数据: (30H)=x7x6x5x4x3x2x1x0 (3lH)=y7y6y5y4y3y2y1y0 现在要从30H单元中取出低5位,并从31H单元中取出低3位完成拼装,拼装结果送40H单元保存,即 (40H)=y2y1y0x4x3x2x1x0。,分析: 从最终结果来看,40H单元的数与30H单元的数较为接近,可以30H 单元数据作为初始操作数据。 30H单元最高3位无用,可先去掉。得0
12、00x4x3x2x1x0 将31H单元高低位交换,可得到y3y2y1y0y7y6y5y4 ,左移1位可得y2y1y0y7y6y5y4y3 ,再去掉低5位,即y2y1y000000。再拼装即可。,综合举例,设在30H和31H单元中各有一个8位数据: (30H)=x7x6x5x4x3x2x1x0 (3lH)=y7y6y5y4y3y2y1y0 现在要从30H单元中取出低5位,并从31H单元中取出低3位完成拼装,拼装结果送40H单元保存,即 (40H)=y2y1y0x4x3x2x1x0。,MOV 40H,30H ANL 40H,#00011111B MOV A,31H SWAP A RL A ANL A,#11100000B ORL 40H,A,本章小结,1、伪指令:ORG、DB、DW、EQU、END等。 2、程序设计步骤。 3、常用程序结构:顺序结构、分支结构、循环结构(1)顺序程序:直线程序或简单程序单重分支(2)分支程序(3)循环程序:构成:初始化、循环体、控制变量的修改、循环次数的控制。,本节作业,P79 第7题 P80 第8、10题,