智能车制作

标题: 问个简单的问题 关于pit [打印本页]

作者: westzhao    时间: 2014-2-4 23:05
标题: 问个简单的问题 关于pit
用的是 xs128  1ms进入一次中断,我想问的是进入中断程序以后,单片机仍然在1ms倒计时么?还是进了中断后停止计时,出了中断程序 再开始1ms计时。  如果我中断里面的程序执行时间超过了1ms那不是混乱了。。。 还是进入中断时候把中断关了再执行中断里面的程序然后执行完再打开?
作者: 原来地球还在转    时间: 2014-2-4 23:56
这个可以自己设置啊,你可以进入中段时候立马关掉总中断时能,然后中断的执行时间就不会计入到你所定的时间里啦~终端执行完了后再打开总中断,然后时间就会从这次结束开始计时,到下次开始为1ms
作者: westzhao    时间: 2014-2-5 00:01
原来地球还在转 发表于 2014-2-4 23:56
这个可以自己设置啊,你可以进入中段时候立马关掉总中断时能,然后中断的执行时间就不会计入到你所定的时间 ...

3ks!
作者: gufeng    时间: 2014-2-5 11:42
原来地球还在转 发表于 2014-2-4 23:56
这个可以自己设置啊,你可以进入中段时候立马关掉总中断时能,然后中断的执行时间就不会计入到你所定的时间 ...

只是关掉总中断使能吗,那么执行中断的同时,PIT不也同时在计时吗,1ms以后只是不能够进入中断吧,等到中断服务程序执行完后,如果再开总中断的话,是不是它计时的时间不一定是1ms呢?这么说,设置1ms中断一次,并不一定等价于从上次中断服务到下一次的中断服务时间间隔不是1ms?亲,求回复
作者: 安安安然。    时间: 2014-2-6 09:29
顶上去~
作者: 原来地球还在转    时间: 2014-2-7 17:02
gufeng 发表于 2014-2-5 11:42
只是关掉总中断使能吗,那么执行中断的同时,PIT不也同时在计时吗,1ms以后只是不能够进入中断吧,等到中 ...

我也说不太明白,你自己用示波器一看立马就知道了啊,很容易的啊

作者: gufeng    时间: 2014-2-7 17:38
原来地球还在转 发表于 2014-2-7 17:02
我也说不太明白,你自己用示波器一看立马就知道了啊,很容易的啊

好吧,我们实验室只有一个示波器,还不能用了

作者: hjhee    时间: 2014-2-7 19:18
本帖最后由 hjhee 于 2014-2-7 19:22 编辑

PIT模块自己有个计时器(timer),一个计数器载入一个数值,每隔一个固定周期,计数器自减一。
待计数器的值减至0的时候,在下一个周期到来时,会发出一个中断请求,同时计数器重新载入一个数值。这个模块是独立工作的。

因此我想PIT中断请求的时间间隔和是否屏蔽总中断无关,关掉总中断仅仅是不处理这个中断请求而已。
作者: gufeng    时间: 2014-2-7 19:40
hjhee 发表于 2014-2-7 19:18
PIT模块自己有个计时器(timer),一个计数器载入一个数值,每隔一个固定周期,计数器自减一。
待计数器的值 ...

亲,我也认为应该是这样的,但是得验证验证。如何验证呢?如何才能知道两个中断服务程序之间的时间间隔是不一定相同的呢?一般来说设置的PIT时间远远大于中断服务程序执行的时间。如何验证是个难题吧?

作者: hjhee    时间: 2014-2-7 19:50
gufeng 发表于 2014-2-7 19:40
亲,我也认为应该是这样的,但是得验证验证。如何验证呢?如何才能知道两个中断服务程序之间的时间间隔是 ...

可以在PIT的ISR里面写一个延时函数看看效果,例如B0接LED灯
void pit0_isr(void){
    int i;
    for(i=0; i<10000000; ++i);
    gpio_toggle(PORTB, 0);
    PIT_FLAG_CLEAR(0);
}
对比ISR执行语句数与LED的闪烁时间间隔,看看有什么发现。


作者: gufeng    时间: 2014-2-7 21:00
hjhee 发表于 2014-2-7 19:50
可以在PIT的ISR里面写一个延时函数看看效果,例如B0接LED灯
void pit0_isr(void){
    int i;

这也不能验证中断服务程序之间的时间间隔是相等与不相等啊?

作者: hjhee    时间: 2014-2-7 22:31
本帖最后由 hjhee 于 2014-2-7 22:43 编辑
gufeng 发表于 2014-2-7 21:00
这也不能验证中断服务程序之间的时间间隔是相等与不相等啊?

参照下面的代码,可以尝试更改下N、"PIT_FLAG_CLEAR(0);"的执行位置(ISR的开头、末尾)、还有是否禁止总中断等,看看LED灯的闪烁时间间隔各有什么变化。

#define N 100
#define M 1000000

void delay(int t){
    int i;
    while(t--)
        for(i=0; i<M; ++i);
}

void pit0_isr(void){
    DisableInterrupts;
    delay(N);
    gpio_toggle(PORTB, 0);
    PIT_FLAG_CLEAR(0);
    EnableInterrupts;
}

假设PIT0的周期为500ms,设置长一些可以看到LED灯闪烁的频率。
ARM在一个周期内是不能完成10^8次加法的,所以在一个ISR中设置上面那样的delay函数,可能会导致在一个中断函数的语句未执行完毕之前,下一个中断请求已经到了。而PIT有中断标志位,未清除标志位之前是不会进入下一个PIT中断的。

如果进入ISR后,PIT的计时器还在计时,那么清除了中断标志后(PIT_FLAG_CLEAR(0);),我想应该就会再次进入ISR函数。
在上面的pit0_isr函数中,把“gpio_toggle(PORTB, 0);”语句放在delay函数之前的话,那么gpio_toggle会在进入ISR后立即执行,所以会看到LED闪烁的频率与正常的相比没有明显变化。

如果是进了中断后停止计时,出了中断程序再开始500ms计时,那么在ISR中放置的delay函数,中断里面的程序执行时间超过了500ms,PIT会产生混乱。那么改变上面程序的M、N的大小,应该会看到LED闪烁的频率有所变化。即便所设置的M、N使得ISR函数能在500ms内执行完毕,比如ISR函数要执行20ms或者100ms,这些频率的变化应该都是能看出来的。

还有,如果事实上是清除了中断标志后,PIT才开始计时,可以再另想其他办法看看究竟是怎么回事。不过最好还是先看看文档的说明吧,虽然长,但讲的比较清楚。
作者: gufeng    时间: 2014-2-7 23:10
hjhee 发表于 2014-2-7 22:31
参照下面的代码,可以尝试更改下N、"IT_FLAG_CLEAR(0);"的执行位置(ISR的开头、末尾)、还有是否禁止总 ...

好办法

作者: 暗光    时间: 2015-4-19 14:58
在退出中断函数是,把计数器清零一次,中断标志位清零即可




欢迎光临 智能车制作 (http://dns.znczz.com/) Powered by Discuz! X3.2