打印
[MCU]

CC2530睡眠定时器问题

[复制链接]
3711|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhenxizhou|  楼主 | 2022-3-3 16:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在维护别人写的代码,其中有一个睡眠定时器问题,我怎么都看不出来问题在哪里?
代码在下面,做了一点简化。该段程序由睡眠定时器来实现所有的定时功能,当需要定时器时,添加到SysTimerTable表中,每产生一次定时中断,从SysTimerTable表中各个活动的定时器countDown值减去定时器的值,如果时间到,调用回调函数。然后再从SysTimerTable表中找到最近的定时器。
原来代码中nextInterruptTick = 0xFFFFF;使用时一直使用的最长的定时时间是30秒(32768x30=0xF0000),10秒,20秒也没问题。
最近项目需要,想使用定时时间到几分钟,发现有问题,最长时间也就30几秒(因为nextInterruptTick = 0xFFFFF)。睡眠定时器是24位的,然后我改成nextInterruptTick = 0xFFFFFF,时间是延长了,但不是想要的,比如设了两分钟,50几秒就来中断了,设了8分钟,40秒不到就中断了。
我已经检查了好几遍了,有人遇到过这个问题吗?
typedef uint32_t    tick_t;

static uint32_t tickExt;

#define EnterCritical(lock)     HAL_INT_LOCK(lock)

#define ExitCritical(lock)      HAL_INT_UNLOCK(lock)

tick_t TickGet(void)
{
    uint8_t     hwlock;
    static tick_t   preTick=0;
    tick_t  curTick;
    uint8_t st0,st1,st2;
   
    EnterCritical(hwlock);
   
    st0 = ST0;
    st1 = ST1;
    st2 = ST2;
   
    curTick = tickExt;
    curTick <<= 8;
    curTick |= st2&0xFF;
    curTick <<= 8;
    curTick |= st1&0xFF;
    curTick <<= 8;
    curTick |= st0&0xFF;
   
    if (curTick < preTick)
    {
        tickExt ++;
        curTick += 0x1000000;
    }
   
    preTick = curTick;
   
    ExitCritical(hwlock);
   
    return curTick;
}

/* 设置下一次定时器中断时间 */
void SleepTimeCompSet(tick_t   tick)
{
    tick_t next = tick + TickGet();
    uint8_t st0,st1,st2;
   
    st0 = next&0xFF;
    next>>=8;
    st1 = next&0xFF;
    next>>=8;
    st2 = next&0xFF;
   
    while(!(STLOAD&0x01));
   
    ST2 = st2;
    ST1 = st1;
    ST0 = st0;

    STIF = 0;
    STIE = 1;
}

void SysTimerTask(event_t event)
{
    tick_t              tick1,        tick2;
    tick_t              deltaTick;
    tick_t              ticksdiff;
    tick_t              nextInterruptTick;
    static tick_t      previousTick = 0;
  
    SysTimerID_t        timerID;  
    SysTimerStatus_t    status;
  
    uint8_t             hwlock;
   
    tick1 = TickGet();
    deltaTick = tick1 - previousTick;
    previousTick = tick1;
   
    for (timerID = 0; timerID < MAX_SYSTIMERS; timerID ++)
    {
        EnterCritical(hwlock);
        
        status = SysTimerStatusGet(timerID);
   
        if (status != SYSTIMER_STATUS_ACTIVE)
            goto CONTINUE;
   
        if (SysTimerTable[timerID].countDown > deltaTick)
        {
            SysTimerTable[timerID].countDown -= deltaTick;
            goto CONTINUE;
        }
   
        SysTimerDisable(timerID);
     
        if (SysTimerTable[timerID].pCallBack != NULL)
            (SysTimerTable[timerID].pCallBack)(timerID);
     
CONTINUE:
        ExitCritical(hwlock);
    }   

    /* 接下来找出最近的一个 active timer */  
    nextInterruptTick = 0xFFFFFF;

        EnterCritical(hwlock);
  
    for (timerID = 0; timerID < MAX_SYSTIMERS; ++timerID)
    {
        if (SysTimerStatusGet(timerID) == SYSTIMER_STATUS_ACTIVE)
        {
            if (nextInterruptTick > SysTimerTable[timerID].countDown)
            {
                nextInterruptTick = (tick_t)(SysTimerTable[timerID].countDown);
            }
        }
    }
       
        ExitCritical(hwlock);
   
    SleepTimeCompSet(nextInterruptTick);
}

使用特权

评论回复

相关帖子

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

本版积分规则

37

主题

76

帖子

2

粉丝