PIC16F87X单片机中断系统应用须关注的问题

时间:2012-04-10来源:网络

在图2中,第1行是系统时钟脉冲信号,每4个时钟周期对应1个指令周期。第2行就是指令周期信号。该信号只有在RC 振荡模式下,从OSC2脚上可以向片外送出。第3行是单片机外部引脚INT送入的中断脉冲信号。外部中断信号INT是用边沿触发的。假设预先设定的是 INT中断信号上升沿有效的话,则该信号的上升沿将会在1个时钟周期后引发中断标志位INTF被置位。第4行代表INTF信号。每个指令周期内的第2个时钟脉冲上升沿时,该信号被抽检1次。一旦检测到INTF信号被设置为“1”,则CPU会在接下来的1个指令周期内,将全局中断屏蔽位GIE清零。第5行是全局中断屏蔽位GIE。在GIE信号被清零的下一个指令周期内,程序计数器PC被置入中断向量0004H,见图2中第6行。同时在该指令周期内完成到中断服务程序的跳转,并且实现提取该子程序的首条指令,即指令(0004H),见图2中第7行。在其后的1个指令周期内,正式开始执行中断服务程序的第1条指令,见图2中第8行。自INT引脚输入有效信号,到中断服务程序的第1条指令得到执行,大约需要3~4个指令周期的延时。更精确的延迟时间取决于中断事件的发生时机。

以上描述的只是1次中断从申请到得到CPU的响应的延迟时间。下面分析从CPU响应1次中断到该中断得到有效处理的延迟时间。由于具有中断功能的PIC系列单片机(低档产品PIC16C5X和PIC12C5X系列不具备中断功能),采用的是“多源中断”的设计方案(即1个中断向量对应着多个中断源),只有惟一的1个中断向量,或者说只有1个中断服务程序入口地址。这就意味着,此类单片机的中断服务程序只能编写1个。这类单片机的硬件结构得到了简化,那么,相应的软件设计上就得多开销一些。在1个中断服务程序中,若想对多个中断源作出处理,就必须在进入中断服务程序后,首先执行调查具体中断源的一条或多条指令,其后才能对查到的中断源作出有针对性的服务。如此以来,就形成了1次中断从CPU响应到进入针对性处理的延迟时间。该时间有长有短,它会随着被开放的中断源的个数的增加而增加。最好情况是只有1个中断源被开放,这时不需要检测中断源就可以立即进入针对性处理;最坏情况是所有中断源全部开放,此时用在检测中断源上的时间会最长。

另外,PIC单片机中采用的是硬件堆栈结构。其好处是既不占用程序存储器空间,也不占用数据存储器空间,同时也不需用户去操作堆栈指针;但此时也带来1个不可回避的弱点,即不具备像其他单片机指令系统中的压栈(PUSH)和出栈(POP)指令那样,实现中断现场的保护会麻烦一些,并且占用的处理时间也相应多一点。

2 中断的现场保护问题

中断现场的保护是中断技术中一个很重要的环节。在进入中断服务程序期间,只有返回地址,即程序计数器PC的值被自动压入堆栈。若需要保留其他寄存器的内容,就得由程序员另想办法。由于PIC单片机的指令系统中没有像其他单片机那样的PUSH(入栈)和POP(出栈)之类的指令,所以要用1段用户程序来实现类似的功能。因为是用1段程序来实现现场保护,而程序的执行有可能会影响到W寄存器和STATUS寄存器,所以,首先应该把这2个寄存器保护起来,然后再去保存其他用户认为有必要保护的寄存器。并且在PIC单片机中,中断现场数据不是保留到芯片的堆栈存储区中,而是保留在用户自己选择的一些文件寄存器(即RAM数据存储器单元)中,当然一般应该选择通用寄存器来保护现场。下面给出的是1段原厂家最新提供的实现保护中断现场的范例程序片段。
  ;将W、STATUS和PCLATH寄存器的内容保存到临时备份寄存器中
  [1]MOVWFW_TEMP   ;复制W到它的临时备份寄存器W_TEMP中
  [2]SWAPFSTATUS,W ;将STATUS寄存器高低半字节交换后放入W
  [3]CLRFSTATUS ;不管当前处在哪个体,都设置体0作当前体
  [4]MOVWFSTATUS_TEMP ;保存STATUS到体0上的临时寄存器STATUS_TEMP
  [5]MOVF PCLATH, W ;把寄存器PCLATH内容复制到W中
  [6]MOVWFPCLATH_TEMP ;经W将PCLATH内容转到临时寄存器PCLATH_TEMP
  [7]CLRFPCLATH ;不管当前处在哪页,都把PCLATH设置成指向页0 (中断服务程序的核心部分)
  [8]MOVFPCLATH_TEMP, W ;经过W转移
  [9]MOVWFPCLATH ;恢复PCLATH内容
  [10]SWAPFSTATUS_TEMP,W ;将STATUS_TEMP寄存器高低半字节交换后放入W
  [11]MOVWFSTATUS ;把W内容移动到STATUS寄存器,(同时也把当前体恢复到原先的体上)
  [12]SWAPFW_TEMP,F ;将W_TEMP内容高低半字节交换后放回
  [13]SWAPFW_TEMP,W ;再次将W_TEMP内容高低半字节交换后放入W

这段程序适用于PIC16CXX系列中各款型号的单片机。在这段例程之前,假设预先对于待保留的各个寄存器都分别定义了相应的临时备份寄存器。用后缀 “_TEMP”表示临时备份寄存器,例如“W”的临时备份寄存器记为“W_TEMP”。对于这些临时备份寄存器究竟需要定义多少个,定义在通用寄存器区域中的哪个位置,都是值得考究的问题。并且单片机的型号不同,其内部的通用寄存器区域的分布也不同,因此这就使得临时备份寄存器定义的数量和位置也不能相同。

例如,对于PIC16F873/874来说,要求寄存器W_TEMP必须在文件寄存器(即RAM数据存储器)的体0和体1上各定义1 个,并且这2个W_TEMP寄存器单元必须具有相同的体内地址码(比如,在体0上把W_TEMP定义在20H单元,则在体1上就把另一个W_TEMP定义在A0H单元);而其他寄存器的临时备份寄存器(如STATUS_TEMP和PCLATH_TEMP)都仅仅需要在体0上定义1个即可。

又例如,对于PIC16F87X子系列中的其他5款型号来说,情况有所不同。其文件寄存器各个体的顶端部分有16个地址空间,都会寻址到相同的16个物理单元上。这16个单元不需要体选寻址,或者说,寻址这16个单元与体选码无关,即与当前所处的体无关。因此,将各个临时备份寄存器都安排在这个位置(W_TEMP也只需要定义1个即可)最为合适。这样做可以使得现场保护和现场恢复变得非常容易。中断是一种随机发生的事件。进入中断服务程序后,第1个要保存的应该是工作寄存器W。原因是PIC单片机没有在“不同寄存器”之间进行直接传递的指令,这样的功能得用W作中转(需要2条指令)才能实现,所以应该先把W寄存器腾空(对应程序中第1条指令)。急于腾空W寄存器,又不能破坏当前状态寄存器 STATUS中的体选码,还不能影响当前状态寄存器STATUS内的标志位,可又无法确定主程序所处的RAM数据存储器当前体是哪一个,就只好在主程序所有可能选择到的每一个RAM数据存储器体上的相同位置,都定义1个W_TEMP临时备份寄存器。

一旦把工作寄存器W腾空后,紧接着就应将状态寄存器STATUS的内容转移到W中。完成这一操作的指令也不能影响到STATUS寄存器内部原有的标志位,原因是STATUS寄存器的内容在此之前还没有安全地保护起来。经过仔细分析得知,PIC16系列单片机的指令系统中有3条“MOV”传送指令。但是,只有1条“MOVF f,W”是以RAM单元为源寄存器,以W为目标寄存器的;而这条指令的操作过程又偏偏会影响“Z”标志位。因此,该指令就不能使用了,只好用1条既有高、低半字节交换功能又有传递功能的“SWAPFSTATUS,W”来勉强顶替(对应程序中第2条指令)。不过在此只利用它的传递功能,其交换功能带来的多余操作还得记下来,等到工作完成之后还得把它倒换回来。

STATUS寄存器的内容已经保存到W中时,就可以大胆地将其清0了,以便把定义着 STATUS_TEMP和PCLATH_TEMP的体0设置为当前体(对应程序中第3条指令)。经过以上几步特别需要谨慎的操作过后,就可以轻而易举地将寄存器STATUS和PCLATH的内容保存到各自的临时备份寄存器中了(对应程序中第4~6条指令)。

1 2 3 4

关键词: 关注 问题 应用 系统 单片机 中断 PIC16F87X

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版