140 likes | 263 Views
一、 中断主程序初始化 1. 设置堆栈指针 SP 2. 定义中断优先级 3. 定义外中断触发方式 4. 开放中断 5. 安排好等待中断或中断发生前主程序应完成的操作内容。 二、 中断服务子程序. 中断服务子程序内容要求: 1. 在中断服务入口地址设置一条跳转指令,转移到中断服务程序的实际入口处。.
E N D
一、 中断主程序初始化 1.设置堆栈指针SP 2.定义中断优先级 3.定义外中断触发方式 4.开放中断 5.安排好等待中断或中断发生前主程序应完成的操作内容。 二、 中断服务子程序 中断服务子程序内容要求: 1.在中断服务入口地址设置一条跳转指令,转移到中断服务程序的实际入口处。
由于80C51相邻两个中断入口地址间只有8B的空间,8B只能容纳一个有3~8条指令的极短程序,一般情况中断服务程序均大大超出8B长度。因此,必须跳转到其他合适的地址空间。跳转指令可用SJMP、AJMP或LJMP指令,SJMP、AJMP均受跳转范围影响,建议用LJMP指令,则可将真正的中断服务程序不受限制地安排在64KB任何地方。由于80C51相邻两个中断入口地址间只有8B的空间,8B只能容纳一个有3~8条指令的极短程序,一般情况中断服务程序均大大超出8B长度。因此,必须跳转到其他合适的地址空间。跳转指令可用SJMP、AJMP或LJMP指令,SJMP、AJMP均受跳转范围影响,建议用LJMP指令,则可将真正的中断服务程序不受限制地安排在64KB任何地方。
2. 根据需要保护现场。 保护现场不是中断服务程序的必需部分。通常是保护Acc、PSW和DPTR等特殊功能寄存器中的内容。若中断服务程序中不涉及Acc、PSW,DPTR,则不需保护,也不需恢复。例如:累加器A是最常用的特殊功能寄存器,主程序中不可能不用到A。而发生中断又是随机的,可能正好发生在对A进行操作、A中的数据还有用时进入中断,而在中断服务程序中又涉及到A,改变了A中的内容,则在进入中断服务程序对A操作前应对原A中数据进行保护,以便中断返回后恢复A中原来数据 需要指出的是,保护现场数据越少越好,数据保护越多,堆栈负担越重,堆栈深度设置应越深。
3.中断源请求中断服务要求的操作。 4. 恢复现场。与保护现场相对应,注意先进后出、后进先出操作原则。 5.中断返回,最后一条指令必须是RETI。
【例7-1】利用定时器T0定时,在P1.0端输出一方波,方波周期为20ms,已知晶振为12MHZ。【例7-1】利用定时器T0定时,在P1.0端输出一方波,方波周期为20ms,已知晶振为12MHZ。 主程序: ORG 0000H LJMP 2000H T0的中断服务程序 ORG 000BH AJMP 70H
ORG 70H MOV TL0,#0F0H MOV TH0,#0D8H CPL P1.0 RETI ORG 2000H MOV TMOD ,#01H MOV TL0,#0F0H MOV TH0,#0D8H MOV IE,#82H SETB TR0 HERE:SJMP HERE
【例6-2】 出租车计价器计程方法是车轮每运转一圈产生一个负脉冲,从外中断INT0(P3.2)引脚输入,行驶里程为轮胎周长×运转圈数,设轮胎周长为2m,试实时计算出租车行驶里程(单位米),数据存32H、31H、30H。 解:编程如下: ORG 0000H ;复位地址 LJMP STAT ;转初始化 ORG 0003H ;中断入口地址 LJMP INT ;转中断服务程序
MAIN主程序可以处理循环显示等任务。 ORG 0100H ;初始化程序首地址 STAT: MOV SP,#60H ;置堆栈指针 SETB IT0 ;置边沿触发方式 MOV IP,#01H ;置高优先级 MOV IE,#81H ;开中 MOV 30H,#0 ;里程计数器清0 MOV 31H,#0 ; MOV 32H,#0 ; LJMP MAIN ;转主程序,并等待中断 ORG 0200H ;中断服务子程序首地址 INT: PUSH Acc ;保护现场 PUSH PSW ; MOV A,30H ;读低8位计数器 ADD A,#2 ;低8位计数器加2m MOV 30H,A ;回存 CLR A ; ADDC A,31H ;中8位计数器加进位 MOV 31H,A ;回存 CLR A ; ADDC A,32H ;高8位计数器加进位 MOV 32H,A ;回存 PUSH PSW ;恢复现场 PUSH Acc ; RETI ;中断返回
【例6-3】现有5个外中断源EX1、EX20、EX21、EX22和EX23,高电平时表示请求中断,要求执行相应中断服务程序,试编制程序。【例6-3】现有5个外中断源EX1、EX20、EX21、EX22和EX23,高电平时表示请求中断,要求执行相应中断服务程序,试编制程序。 解: ORG 0000H ;复位地址 LJMP MAIN;转主程序 ORG 0003H ;中断入口地址 LJMP PINT0;转中断服务程序 ORG 0013H ;中断入口地址 LJMP PINT1;转中断服务程序
ORG 0100H;主程序首地址 MAIN: MOV SP,#60H ;置堆栈指针 ORL TCON,#05H ;置INT0、INT1为边沿触发方式 SETB PX0 ;置为高优先级 MOV IE,#0FFH ;全部开中 … ;主程序内容 ORG 1000H;中断服务程序首地址 PINT0: PUSH Acc ;中断,保护现场 LCALL WORK1 ;调用EX1服务子程序 POP Acc ;恢复现场 RETI ;中断返回 ORG 2000H;中断服务程序首地址 PINT1: CLR EA ;CPU禁中 PUSH Acc ;中断保护现场 PUSH DPH ; PUSH DPL ; SETB EA ;CPU开中
JB P1.0,LWK20;P1.0=1,EX20请求中断 JB P1.1,LWK21;P1.1=1,EX21请求中断 JB P1.2,LWK22;P1.2=1,EX22请求中断 LCALL WORK23 ;P1.3=1,调用EX23服务子 LRET: CLR EA ;CPU禁中 POP DPL ;恢复现场 POP DPH ; POP Acc ; SETB EA ;CPU开中 RETI ;中断返回 LWK20: LCALL WORK20 ;P1.0 = 1,调用EX20服务子程序 SJMP LRET ;转中断返回 LWK21: LCALL WORK21 ;P1.1 = 1,调用EX21服务子程序 SJMP LRET ;转中断返回 LWK22: LCALL WORK22 ;P1.2 = 1,调用EX22服务子程序 SJMP LRET ;转中断返回
P1.0 P1.7 INT1 300 【例7-4】通过外部中断1,在中断服务中将B寄存器里的内容左环移一位。已知: (B)=01h,要求采用边沿触发,低优先级。 此例的实际意义:在INT1引脚接一个按钮开关到地,每按一下按钮就申请一次中断,中断服务则是:依次点亮八盏灯中的一盏。
ORG 0000H LJMP MAIN ORG 0013H ;中断矢量 LJMP INT MAIN:SETB EA ;开总中断允许“开关” SETB EX1 ;开分中断允许“开关” CLR PX1 ;0 优先级(也可不要此句) SETB IT1 ;边沿触发 MOV B,#01H ;给 B 寄存器赋初值 HERE:SJMP HERE ;原地等待中断申请 INT:MOV A,B ;自B寄存器中取数 RL A ;左环移一次 MOV B,A ;存回B,备下次取用 MOV P1,A ;输出到P1口 RETI ;中断返回 中断服 务程序