查看: 1573|回复: 0
打印 上一主题 下一主题

程序设计的魅力——中断控制

[复制链接]
跳转到指定楼层
沙发
发表于 2015-9-27 23:52:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
NT0,INT1,TF0,TF1,RI/TI这5个中断源在单片机中称为:外部中断0,外部中断1,Timer0中断,Timer1中断,串行通信中断。

一、中断实例和中断的控制者


例:什么是中断
    开关中断产生后,出现绿灯闪一下,红灯闪一下。

程序:

ORG 00H;               起始行号00H

MAIN:                 ; MAIN以下是主程序段,点亮绿色LED——D1
          MOV IE, #84H;使能外部中断1,
GREEN:
          CLR P0.0;     点亮绿色LED——D1
          JMP GREEN;    循环
ORG 13H;                中断服务子程序起始地址为13H

EXT1_RED:              
           SETB P0.0;    熄灭绿色LED——D1
           CLR  P0.1;    点亮红色LED——D2

D1:  MOV R4, #200;       延时程序100ms
D2:  MOV R5, #248;
     DJNZ R5,$;          R5的值减少1,等于0就往下执行,否则反复执行本行
     DJNZ R4,D2;         R4的值减少1,等于0就往下执行,否则跳转到D2标号处执行
     SETB P0.1;          熄灭红色LED——D2
     RETI;               中断服务子程序结束
     END;                程序结束

二、中断服务的指挥官--中断向量表(AT89S51)

    中断向量表,向量即“取向”的意思 ,例如外部中断0发生时,单片机会到程序存储器的003H中寻找中断服务子程序来执行。
   
         中断源            向量地址     中断标志位    对应管脚   
   
    外部中断(INT0)管脚    0003H          IE0           P3.2

    Timer0中断              000BH          TF0           P3.4

    外部中断(INT1)管脚    0013H          IE1           P3.3

    Timer1中断              001BH          TF1           P3.5

    串行通信中断            0023H          TI/RI         TI(P3.1)
                                                         RI(P3.0)
三、中断响应和处理过程
  
    1)立即暂停正在执行的任何程序,并把下一条要执行的指令地址压入堆栈中。

    2)保存所有中断状态(但不在堆栈中)

    3)根据中断向量表找到中断对应的地址。

    4)单片机到该地址上开始执行中断服务子程序,直到遇到指令RETI为止。

    5)遇到RETI指令后,从堆栈中弹出在中断产生时保存的将要执行的下一条指令的地址到程序计数器PC中,单片机开始执行从PC指示的地址继续执行程序。

     6)问题:每一个中断服务子程序的存放空间都很有限,例如,外部中断0的中断向量为0003H,而Timer0中断量地址为000BH,可见外部中断0的中断服务子程序只有0003H~000AH这8个字节的空间来存放,这8个字节的空间实在也放不了几条指令。
              如果单片机使能了多个中断,并且每一个中断服务子程序都按中断向量表中的地址开始存放,就很有可能出现一个中断服务子程序占据其他服务子程序空间的问题。   
解决问题办法:用JMP指令跳转到别处开始执行。
     例:
        ORG  00H;  起始地址00H
        JMP  MAIN; 跳转到MAIN
      
        ORG 03H;   外部中断0的起地址03H
        JMP EXT0;  跳转到EXT0
      
        ORG 0BH;   Timer0中断0的起地址0BH
        JMP TIM0;  跳转到TIM0

        ORG 013H;  外部中断1的起地址013H
        JMP LOOP;  跳转到LOOP
      
        ORG 01BH;  Timer1中断0的起地址0BH
        JMP LOAD;  跳转到LOAD
        
        ORG 023H;  串行口通信中断RI/TI的起地址023H
        JMP START; 跳转到START

四、中断的控制者--中断使能寄存器IE
   
       单片机上电复位之后,默认所有中断都被关闭。为了使单片机能对中断进行响应,需要对中断使能寄存器IE进行操作。
       IE的初始化过程即是使用MOV指令向其载入控制字。

    7       6      5      4     3      2      1       0

   EA     保留    保留    ES   ET1    EX1    ET0     EX0


     EA中断使能;             ET1  Timer1中断使能;

     保留(不要访问该位);   EX1  外部中断1使能;

     ES串行口中断使能;       ET0   Timer0中断使能;
                              
                              EX0    外部中断0使能;

五、外部中断的电平触发

   1) 在使能中断后,如果在INT0和INT1口上出现低电平就会触发外部中断0或外部中断1,  单片机会立即停止正在执行的程序,执行中断服务子程序,是单片机复位之后的外部中断默认触发方式。

   2)在单片机进入执行中断服务子程序时,在执行到中断服务子程序结束指令RETI之前,这样低电平必须撤走,否则将会使单片机执行完RETI指令后再次进入中断服务子程序。

   3)外部中断的(Tdp)电平触发--一般为了保证外部中断的产生,低电平的时长到少需要4个机器周期,若晶振是12MHZ,则一个机器周期是一微秒,4个机器周期就是4微秒。
     低电平触发外部中断的保持时间至少要大于或等于4微秒。(Tdp≥4us)

   4)外部中断的(Tby)边沿触发---至少一个机器周期的高电平,且向低电平跳变之后至少保持1个机器周期,如晶振为12MHz,则一个周期的高电平和一个机器周期的低电平。(Tby≥1us)

   5)外部中断的(Tby)边沿触发---需要指令来设置寄存器TCON。

     7       6       5       4       3      2      1      0
    TF1     TR1     TF0     TR0     IE1    IT1    IE0    IT0
        7654与定时/计数器有关。

      IE1外部中断1边沿标志位;             IE0外部中断0边沿标志位;
      IT1外部中断1方式控制位;             IT0外部中断0方式控制位;
     (IT1清0 ,电平触发//置1,边沿触发)  (IT0清0 ,电平触发//置1,边沿触发)
   
  6)外部中断的(Tdp)电平触发//(Tby)边沿触发特点:
      ①电平触发方式下,若按下开关S不放,端口将不断获得低电平,中断不断产生,中断服务子程序被重复执行;

  ②边沿触发方式下,只对端口的电平跳变有反应,若也不放开开关S,并不会连续地产生中断。

       ③电平触发方式下,若单片机正在执行中断服务子程序时,外部中断再次发生,电平触发信号不会被锁存,所以单片机不会响应第二次中断。而在边沿触发方式下有所不同,单片机正在执行中断服务子程序,如果中断发生,电平跳变产生的中断触发信号保存在TCON寄存器中的IE0或IE1中,单片机再次检测到IE0或IE1,又进入中断服务子程序中。

   注意:在单片机正在执行中断服务子程序时,电平触发方式会(★漏掉★)新的中断,而边沿触发方式会(★保留★)新的中断。

   7)★问题★:前面通过检测Tmier溢出标志位TFx来判断计时是否完成。在判断的过程中,单片机除了循环判断之外一般不做任何操作,如果在计时的同时又需要执行别的程序该怎么办呢?

    ★解决办法:当通过中断使能寄存器IE使能Tmier中断,设置好Tmier的工作参数,启动Tmier之后,单片机就可以去做别的操作。Tmier溢出时,单片机将会自动停下正在执行的任何程序而进入Tmier中断服务子程序中执行。

     两个中断的中断向量地址分别为00BH和001BH。

例:利用Tmier0中断产生50HZ方波信号(★此程序有错误,高电平有0.02秒,低电平无法保持0.02秒以上)

程序:
ORG 00H;              起始地址00H
JMP MAIN;             跳转到MAIN
ORG 0BH;              Tmier0中断服务子程序起始地址为0BH
JMP TIM_LOW;           跳转到TIM_LOW
;                      下面是主程序段,初始化
MAIN:
     MOV     IE,#82H;    使能Tmier0中断(10000010B)
     MOV     TMOD,#01H;  设置Tmier0工作在模式1下
TIMER0_LOAD:
     MOV     TH0,#0B1H;  往TH0中载入计数初始值(65536-20000=45536)0.02秒
     MOV     TL0,#0E0H;  往TL0中载入计数初始值(45536=B1E0,则:TH0=B1H,TL0=E0H)
     SETB    TR0;        使TR0置1,以启动Tmier0
SET_HIGH:
     SETB    P1.0;        p1.0=1
     JMP     SET_HIGH;    循环
TIM_LOW:
     CLR     P1.0;        P1.0=0
     MOV     TH0,#0B1H;   重新往TH0中载入计数初始值
     MOV     TL0,#0E0H;   重新往TL0中载入计数初始值
     RETI;                中断服务子程序结束
     END;                 程序结束
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表