ARM cortex-M内核芯片的软件定时器功能异常问题解决

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fhqlongteng/article/details/80636015

      最近一个项目中的使用了软件定时器功能,程序运行在前后台的系统中,使用软件定时器建立任务处理应用。硬件上外接一个水流传感器,水流传感器输出的是一个方波信号,水流越快,信号的频率越高。CPU采用的是STM32L051的芯片,使用外部中断接收这个方波信号,中断内记录中断时间,以此来计算出来方波的频率,换算出来水流的速度。中断程序中使用了一个软件的定时器来判断这个方波信号没有了时,触发定时器超时来设置方波频率为零。

       在测试过程中发现,测量水流传感器的方波频率正常,但是有另外一个定时器任务在水流传感器工作时异外的被删除了。首先查看了程序的堆栈, 发现堆栈够用,不是堆栈小导致的程序修改了定时器的数据结构造成的。

/*水流传感器超时定时器句柄*/
HTMR  g_water_flow_tmr = NULL;

int main(void)
{
    /*时钟初始化*/
    
    /*GPIO初始化, 此函数中设置的水流传感器的外部管脚中断*/
    HAL_GPIO_Init()

    /*软件定时器全局变量初始化*/
    tmr_data_init();

    /*创建定时器*/
    tmr_creat(1000, TMR_LOOP, sersor_read, 0)

}
/*水流传感器中断处理程序*/
void Water_flow_Interrupt(void)
{
    /*记录方波信号的时间,计算方波信号的频率*/
    ...
    
    tmr_delete(g_water_flow_tmr);

    g_water_flow_tmr = tmr_creat(1000, TMR_ONE, water_flow_timeout, 0);
    

}

     经过调试发现,有水流时第一次进入水流传感器中断处理程序中g_water_flow_tmr = 0x100, 这个句柄正是另外一个异外删除的定时器的句柄,中断程序中首先删除超时定时器tmr_delete(),这里导致了那只定时器被意外删除了。原因定位到是水流传感器的中断程序引起的。但是g_water_flow_tmr为什么是0x100,而不是默认初始化的NULL呢?经过不断仿真调试,在初始化GPIO时HAL_GPIO_Init()函数中初化外部中断,打开外部中断后,CPU会在实际IO口未发现中断时产生一次中断(假中断),中断程序中执行tmr_creat()函数,g_water_flow_tmr被赋值为0x100,而主程序在继续执行定时器初始化后,创建的这个定时器被消除了,后面的程序中再执行定时器创建任务时返回的句柄也是0x100,这时再有水流流动时,中断程序就会删除了0x100这个句柄的定时器。

       解决办法:定时器初始化程序前移到GPIO初始化之前就可以了。

     经验总结:所有纯内部数据结构的初始化(如软件定时器初始化),尽量放在初始化的最前面。同时一定要注意cortex-M3,cortex-M0这些内核的芯片在使能中断时都会产生一次假中断(CHIP BUG),对你设计的程序逻辑产生的影响。

      

猜你喜欢

转载自blog.csdn.net/fhqlongteng/article/details/80636015