打印

我个人对PIC教程的一段晦涩文字的理解

[复制链接]
3529|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huangleche|  楼主 | 2007-9-19 01:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下是原文(来源于《PIC单片机实用教程-基础篇(第2版)》P246(19)段文字或《PIC单片机原理》P115(19)段文字):
    (19) 当CPU正在执行一条对INTCON寄存器进行“读-修改-写”操作的指令时(如 BSF INTCON等),如果恰好发生了中断请求,则中断服务程序会被执行两次。这是因为当中断请求发生后INTCON寄存器中的GIE位会被硬件自动清0(屏蔽所有中断),并且程序转入中断例程入口(0004H)。当GIE被清0后,如果这时正好CPU在执行一条对INTCON读-修改-写的指令,则GIE位还会被写回操作重新置1,这样会造成CPU两次进入中断服务程序。解决的方法是: 如果在程序中需对INTCON的某一中断允许位进行修改,则应事先置GIE=0,修改完成后再恢复GIE=1。程序如下:
    BCF INTCON,GIE 
    BSF INTCON,XX 
    BSF INTCON,GIE 

该段解释晦涩难懂,我的理解是:
    设XX对应的是中断标志位,且PC=n的时候取BSF INTCON,XX指令,同时发生int中断,在PC=n+1的时候BSF INTCON,XX 被执行,而此时按时序表看,GIE还是等于1,所以在未完全进入int引起的中断时进入了XX置1引起的中断,至于在置1引起的中断程序中具体响应int还是XX中断,则由中断程序中程序员编写的中断源查询代码段来决定。   若在中断程序中把INTIF清0,则XX置1引起的中断程序结束后返回继续执行主程序;否则将再次进入INTIF=1引起的中断,因为在中断返回执行RETFIE时会将GIE置1。同理在中断程序中把XXIF清0,则XX置1引起的中断程序结束后返回继续执行主程序;否则将再次进入XXIF=1引起的中断。当然以上这整段描述是发生在总前提XX对应的是XX中断标志位,而不是原文所说的中断允许位的情况下。
    若XX是原文所说的中断允许位(除GIE外的),则应该是PC=n的时候取BSF INTCON,XX指令,同时发生int中断,在PC=n+1的时候BSF INTCON,XX 被执行,接着继续执行原来的int中断,中断并不会被执行两次。因为根据时序图可知,修改-写即执行BSF INTCON,XX指令时是在前面一个PC=n+1的指令周期,而GIE清0却是在后面一个PC=n+1的指令周期(注意时序图中有两个PC=n+1的指令周期)
    另外原文中指:“当GIE被清0后,如果这时正好CPU在执行一条对INTCON读-修改-写的指令,则GIE位还会被写回操作重新置1,这样会造成CPU两次进入中断服务程序。”根据时序图可知,修改-写即执行BSF INTCON,XX指令时是在前面一个PC=n+1的指令周期,而GIE清0却是在后面一个PC=n+1的指令周期(注意时序图中有两个PC=n+1的指令周期),且后面一个PC=n+1的指令周期并不执行任何指令,因此得出结论“当GIE被清0后,如果这时正好CPU在执行一条对INTCON读-修改-写的指令,则GIE位并不会被写回操作重新置1”所以原文所述并不正确。

另外最后说明一下下面一张图中 压入堆栈的应是n+1,不是图中的n+2,还有图中XX是某中断标志位应改为XX是某中断允许位,因为下面这张图的本意是解释“当GIE被清0后,如果这时正好CPU在执行一条对INTCON读-修改-写的指令,则GIE位并不会被写回操作重新置1”的
沙发
xieyuanbin| | 2007-9-19 08:30 | 只看该作者

应该肯定你的钻研精神。

书的作者可能对中断过程理解有误。如果说要发生文中“读-修改-写”的情况,唯一的机会是在图中②的位置,但PIC单片机在这个指令周期之内不执行任何指令,只是一个空操作的延时,所以书中写的情况是不可能发生的。
实际上,读-修改-写的情况在许多其它种类单片机中都会出现,一般都是发生在对端口的操作过程中,由于端口外部电压的不确定性,会导致读取的数据与原先写入的数据不符从而误操作。

使用特权

评论回复
板凳
systemchip| | 2007-9-19 09:32 | 只看该作者

:

还有一种情况应该注意:
   即当我们执行BCF INTCON,GIE用于禁止全局中断的时候,当这条指令执行过程中某个中断发生,因为这个中断发生的时候,GIE位还未被请0,而当这条指令执行完后,将立即响应中断,当中断完成返回时候(执行 RETFIE),GIE位将自动被置一,这样导致的结果将是GIE期望被禁止而实际并没有被禁止。所以可以采取下面措施:

here:
     bcf INTCON,GIE
     btfsc INTCON,GIE
     goto  here
     .....
     ....

使用特权

评论回复
地板
yewuyi| | 2007-9-19 09:56 | 只看该作者

关于LS提到的那个问题

好象已经讨论了很多次,应该也是错误。


当时还有人从PICC生成的代码中看,PICC也并没有做类似处理。

张明峰先生和MARTIN过去都曾就此问题做过论述,**中,似乎不需要做此处理。

使用特权

评论回复
5
martin| | 2007-9-19 10:11 | 只看该作者

楼上说的情况是历史了

楼上说的是PIC16C7X时代的问题了,现在新出的Flash的PIC都不需要做这个冗余的操作。在执行bcf INTCON,GIE这条指令是,如果发生中断,系统架构会在执行该指令周期的Q4把GIE清零,而中断系统是固定的3个指令周期的延时,中断响应与否取决于在这个延时期间对GIE位的判断。有先后之分,所以这种情况绝对不会出现。不要为了些古老的资料而误导了自己的思路。

使用特权

评论回复
6
huangleche|  楼主 | 2007-9-19 16:52 | 只看该作者

n+1对应的指令

还有一个问题,就是设XX对应的是中断标志位,PC=n的时候取BSF INTCON,XX指令,同时发生int中断,在前一个n+1的时候BSF INTCON,XX 被执行,不知大家注意过没,在于此同时还取了一条指令,根据时序图是PC=n+1对应的指令,那这条n+1对应的指令是不是还是BSF INTCON,XX 呢?恳请各位大虾指教

使用特权

评论回复
7
huangleche|  楼主 | 2007-9-19 17:10 | 只看该作者

接上面所述

接上面所述,如果n+1对应的指令是BSF INTCON,XX,则在进入XX中断之后的n+2的周期BSF INTCON,XX还会被执行一边,在这时MCU还是不是依旧会再响应XX中断一边呢?

使用特权

评论回复
8
yewuyi| | 2007-9-19 22:15 | 只看该作者

bcf INTCON,GIE就可以,不需要考虑

使用特权

评论回复
9
huangleche|  楼主 | 2007-9-19 22:32 | 只看该作者

看起来会进入死循环

不知各位大虾是否看出我上面的有个说法有点疑问的:
设PC=n的时候取BSF INTCON,XX指令,同时发生int中断,在n+1的时候BSF INTCON,XX 被执行,而此时按时序表看,GIE还是等于1,接着进入了XX对应的中断,XX对应的中断结束后再返回继续执行int中断,所以中断会被执行两次。前提是XX对应的是中断标志位,而不是原文所说的中断允许位。

在前一个n+1的时候BSF INTCON,XX 被执行,不知大家注意过没,在于此同时还取了一条指令,根据时序图是PC=n+1对应的指令,那这条n+1对应的指令是不是还是BSF INTCON,XX 呢?如果是BSF INTCON,XX就不是我上面所说的中断会被执行两次那么简单了,看起来会进入死循环,恳请各位大虾指教

使用特权

评论回复
10
xieyuanbin| | 2007-9-20 07:04 | 只看该作者

楼主的问题惊动了不少人啊。

MARTIN老版主也出来了。SYSTEMCHIP也是一位重量级人物呢。
对于楼主的问题解答如下:
“设PC=n的时候取BSF INTCON,XX指令,同时发生int中断,在n+1的时候BSF INTCON,XX 被执行,而此时按时序表看,GIE还是等于1,接着进入了XX对应的中断,XX对应的中断结束后再返回继续执行int中断,所以中断会被执行两次。前提是XX对应的是中断标志位,而不是原文所说的中断允许位。”
这里如果XX中断允许位没开,当然不会进入中断,而且不管如何,PIC还是有中断优先级,也有个先来后到的时序,所以此时仍然进入INT中断,而XX中断会在INT中断之后,执行了BSF INTCON,XX指令的下一条指令之后执行。

“在前一个n+1的时候BSF INTCON,XX 被执行,不知大家注意过没,在于此同时还取了一条指令,根据时序图是PC=n+1对应的指令,那这条n+1对应的指令是不是还是BSF INTCON,XX 呢?如果是BSF INTCON,XX就不是我上面所说的中断会被执行两次那么简单了,看起来会进入死循环,恳请各位大虾指教”
PC=N+1对应的指令是BSF INTCON,XX后面的一条指令,进入中断前压栈的就是这条指令的地址。所以不会出现死循环。

使用特权

评论回复
11
huangleche|  楼主 | 2007-9-20 19:45 | 只看该作者

PIC有硬件检测中断谁先来谁先响应??

    LS说:“PIC还是有中断优先级,也有个先来后到的时序”不是吧,我看《PIC单片机入门与实战》里P40说的清清楚楚“PIC单片机的中断入口只有一个,故对中断优先级的控制也由编程人员通过软件来实现。”即由软件编写程序来实现谁先检测谁中断的原则,在后面一段书中也说:“如果现在正在处理低优先级的中断,就算有高优先级的中断发生,也必须等到低优先中断处理完毕后才相应”但书中有一个前提即:“在响应任何中断请求时,PIC单片机会自动把全局中断使能位(INTCON的第7位)清除。这样其他中断请求就暂时不被响应”。

    然而我不知道LS注意了时序图没,我所说的BSF INTCON,XX(当然XX是指某中断的标志位)被执行是在GIE被硬件清0之前发生的,我要问的是,此后是继续后一个n+1周期呢?还是会因XX标志位的置1而重新开始中断过程??

    换而言之就是,PIC单片机在发生INT中断后GIE被硬件清0前的时刻,别的中断标志位被置1,CPU是不是会响应那个中断标志位被置1的中断??PIC单片机有没有硬件检测中断谁先来谁先响应的功能(除GIE被硬件自动清0外)??

使用特权

评论回复
12
yewuyi| | 2007-9-20 21:42 | 只看该作者

优先级问题见数据手册

16系列没有优先级,其余问题见以上回答

使用特权

评论回复
13
xieyuanbin| | 2007-9-21 08:45 | 只看该作者

中断优先在硬件上还是有一些区分。

但在软件处理上没什么区别。因为不管如何,进入中断后还是要软件来判断中断标志。
楼主有些钻牛角尖了,险些被你弄晕。
 “换而言之就是,PIC单片机在发生INT中断后GIE被硬件清0前的时刻,别的中断标志位被置1,CPU是不是会响应那个中断标志位被置1的中断??PIC单片机有没有硬件检测中断谁先来谁先响应的功能(除GIE被硬件自动清0外)??”
像这样的情况,当进入中断时,如果那个XX中断发生,中断标志一样会被置1,如果你的软件去处理,就是响应了。换句话说,即使你xx中断允许位没开,相应的中断标志在中断条件符合时也一样会置1,这样的情况常常用在普通程序中判断一个工作是否完成,比如AD转换等。而此时如果你在中断处理中判断了这个标志,程序也一样会去处理这个中断,这完全取决于你的程序。

使用特权

评论回复
14
huangleche|  楼主 | 2007-9-23 00:04 | 只看该作者

彻底搞明白了

对不起,是我把PC的内容和指令存储的程序存储器地址搞混了,所以思维发生混乱,所以也在上面一张图中发生了个错误,在此修正一下,压栈的该是n+1,而不是上面那些图中的n+2

使用特权

评论回复
15
huangleche|  楼主 | 2007-9-23 00:12 | 只看该作者

谢谢版主的耐心

另外楼上的楼上说法是正确的,谢谢版主的耐心回应,谢谢
    当进入中断时,如果那个XX中断发生,中断标志一样会被置1,如果你的软件去处理,就是响应了。换句话说,即使你xx中断允许位没开,相应的中断标志在中断条件符合时也一样会置1,这样的情况常常用在普通程序中判断一个工作是否完成,比如AD转换等。而此时如果你在中断处理中判断了这个标志,程序也一样会去处理这个中断,这完全取决于你的程序。我也将这种情况的时序图整理了一下,画了出来,不知道对不对,请各位大大指教

使用特权

评论回复
16
兰天白云| | 2007-9-25 14:39 | 只看该作者

本人以前也有LZ的担心,但又无法验证

最后搞了个歪招
在BSF INTCON,XX 之前先清除对应的标志位,不过这招对TO特别没用

1:清除对应的标志位
2:BCF INTCON,GIE 
3:BSF INTCON,XX 
4:BSF INTCON,GIE 

后来觉得这样也不好,更改设计,先允许对应中断,最后再BSF INTCON,GIE 
而且再整个程序中就只有这么一句置位GIE的指令

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

16

帖子

0

粉丝