定时器使用小技巧

描述

介绍一个定时器的使用小技巧,今天写代码需要用到一个功能,实时测量程序运行时间,要求测量时间精度要高。

精度高就想到了硬件定时器,但是整个系统比较复杂,硬件定时器都被占用了,想了想只能和某项功能共用一个定时器了。系统中使用了一个systick定时器,systick定时器是一个自动装载递减定时器,即,计数器从设定值开始递减,减到零时触发systick中断,然后计数器自动装载初值开始下一个计数周期。这里配置为1ms产生一次中断,中断内有一个全局变量加1,如果直接用这个变量计算时间,精度±1ms,太差了。于是乎又写了俩函数,可以实现us级别测量,后面一一介绍。

void SysTick_Handler(void)
{
    g_dwSysTickCnt++;//ms中断,精度只有±1ms
}

函数1:测量开始函数:

//测量开始函数
void drvMeasureUsStart(void)
{
    SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;     //关闭定时器
    g_dwOldTime = SysTick->VAL;                     //记录当前计数值
    g_dwStartTimeMs = g_dwSysTickCnt;               //获取当前ms数
    SysTick->CTRL  |= SysTick_CTRL_ENABLE_Msk;      //使能定时器
    g_dwReload = SysTick->LOAD;                     //获取重载值
}

函数2:测量结束函数:

DWORD drvMeasureUsStop(void)
{
    DWORD dwNowTime,dwpRunTimeUs;

    SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;         //关闭定时器
    dwNowTime = SysTick->VAL;
    g_dwStartTimeMs = g_dwSysTickCnt - g_dwStartTimeMs; //获取ms数差值
    SysTick->CTRL  |= SysTick_CTRL_ENABLE_Msk;          //使能定时器

    if(g_dwStartTimeMs > 0u)
    {
        g_dwStartTimeMs--;
        dwpRunTimeUs = g_dwReload - dwNowTime + g_dwOldTime;
    }
    else
    {
        dwpRunTimeUs = g_dwOldTime - dwNowTime;
    }
    g_dwStartTimeMs *= 1000u;                           //换算为us
    dwpRunTimeUs = dwpRunTimeUs/(g_dwSysTickClockMhz);  //换算为us

    dwpRunTimeUs += g_dwStartTimeMs;

    return dwpRunTimeUs;
}

使用方法:

//测量usercode()函数运行时间
{
    DWORD dwTime;
    ...
    ...
    drvMeasureUsStart();
    usercode();
    dwTime = drvMeasureUsStop();
    ...
    ...
}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分