打印

TMRn_IRQHandler()的中断标志问题。

[复制链接]
10203|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
今天又对TIMER的中断标志做了测试,发现一个问题:
DrvTIMER_GetIntFlag()取得的中断标志貌似不正确。
测试程序如下:
#include "M051Series.h"
#include "Driver/DrvSYS.h"
#include "Driver/DrvGPIO.h"
#include "Driver/DrvTIMER.h"
int main()
{
  DrvTIMER_Init();
  DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC, 0);
  DrvTIMER_Open(E_TMR0, 1000, E_PERIODIC_MODE);     //每秒1000Tick,1ms/tick
  DrvTIMER_EnableInt(E_TMR0);
  DrvTIMER_Start(E_TMR0);
  while(1)
  {
    if(DrvTIMER_GetIntFlag(E_TMR0))
    { //每Tick产生一次中断标志(1ms)。
      DrvTIMER_ClearIntFlag (E_TMR0);
      if(DrvGPIO_GetDoutBit (E_PORT3, E_PIN6))
        DrvGPIO_ClrBit (E_PORT3, E_PIN6);
      else
        DrvGPIO_SetBit (E_PORT3, E_PIN6);
    }
  }
}
但实际输出波形是2ms的间隔,也就是说,2ms才产生一次中断标志。


找到 void TMR0_IRQHandler(void) 函数,发现如下代码:
void TMR0_IRQHandler(void)
{
    int32_t i;
    TIMER0->TISR.TIF = 1;    <--???
    uTimer0Tick++;
    if (bIsSetTime0Event)      /* Timer Event Handle */
    {
        for (i=0; i<TIMER_EVENT_COUNT; i++)
        {
            if (tTime0Event.active)
            {
                tTime0Event.curTick--;
                if (tTime0Event.curTick == 0)
                {
                    (*tTime0Event.funPtr)(tTime0Event.transParam);
                    tTime0Event.curTick = tTime0Event.initTick;
                }
            }
        }
    }
}
将 TIMER0->TISR.TIF = 1; 这行注释掉,再测试,变成正常的1ms产生一次中断标志,输出波形正常。

同理,TMR1、2、3 的 IRQHandler 也存在同样的问题。
改成这样就能正常获取中断标志了。
//    TIMER0->TISR.TIF = 1;
但要注意,用 DrvTIMER_GetIntFlag() 检查到这个标志后,应该在程序中使用 DrvTIMER_ClearIntFlag() 清除中断标志,以免重复执行代码。

天之蛟龙
2011-06-14

相关帖子

沙发
delong_z|  楼主 | 2011-6-15 15:56 | 只看该作者
本帖最后由 delong_z 于 2011-6-15 16:02 编辑

刚发现去掉这行后,DrvTIMER_SetTimerEvent() 设置的回调函数执行周期不正确了。:L
可能是因为不清除中断标志,退出中断后,又马上又进入中断引起的?是么?
那么如此说来,这行不可以去掉了。

使用特权

评论回复
板凳
delong_z|  楼主 | 2011-6-15 16:08 | 只看该作者
经测试证实,的确是退出中断后,又马上又进入中断引起的
这行不可以去掉,不好意思:D。

使用特权

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

本版积分规则

9

主题

86

帖子

1

粉丝