×
单片机 > 单片机程序设计 > 详情

在IAR环境下LPC2129平台上脉冲捕捉导致死机问题

发布时间:2020-08-27 发布时间:
|
在项目进行过程中,设置了脉冲捕捉,然后产生中断,我的做法是,设置了个全局变量环形数组,将捕获的脉冲计数值与前一次作差后放入环形数组里,然后由相关任务去处理。然是奇怪的是,捕捉中断进行几次之后就不再响应了,而且还会导致死机,代码如下:

#define LCD_LED_SW  1<<24
//extern OS_EVENT *pMbox_App_CapISR_Flowmeter;
INT8U capCnt = 0;
INT32U rcvLast = 0;
extern INT32U rcvBuf[];
extern BOOLEAN flag_capISR;

void  BSP_Tmr_Cap_ISR_Handler (void)
{
//#if OS_CRITICAL_METHOD == 3                             // Allocate storage for CPU status register
//    OS_CPU_SR   cpu_sr = 0;
//#endif    
   INT32U  rcvCur;
    //中断寄存器T1IR包含低4个位用于匹配中断,高4个位用于捕获中断。如果有中断产生,IR中的对应位会置位,否则为0。向
    //向对应的IR 位写入1 会复位中断。写入0 无效。
    //OS_ENTER_CRITICAL();
    rcvCur = T1CR2;
     if(rcvCur > rcvLast) //如果收到的值大于上次接收到的值,说明TC没有溢出
        rcvBuf[capCnt] = rcvCur - rcvLast;
    else  //否则TC产生了溢出,注意这rcvCur不可能是负值!!!,因为它们是无符号整数,
          //所以要按下面方式计算0xffffffff + rcvCur就会
        rcvBuf[capCnt] = 0xffffffff + rcvCur - rcvLast;
    //rcvBuf[capCnt] = __get_SP();
    if(10 > capCnt)           
        capCnt++;
    else 
        capCnt = 0;          
    rcvLast = rcvCur;//更新成最新值
    flag_capISR = 1;//标志捕捉中断已产生 
 
    //T1IR_bit.MR2INT = 1;  //匹配通道2 的中断标志
    //向TaskFlowmeter任务发送邮件
    //OSMboxPost(pMbox_App_CapISR_Flowmeter, (void *)&rcv);
       
    if(IO1PIN&LCD_LED_SW)                                          
      IO1CLR= LCD_LED_SW;//P1.24=0
    else
      IO1SET= LCD_LED_SW;//P1.24=1
   
    //清零操作一定要放在最后  
    T1IR_bit.CR2INT = 1;//清除捕获通道2事件的中断标志
    //OS_EXIT_CRITICAL();
    VICVectAddr = 0;
}

经过艰苦的排查之后,才发现原来犯了一个多么低级的错误,仔细看上面蓝色粗体部分,变量rcvCur是32为无符号整型,只要rcvCur不等于零,0xffffffff + rcvCur 当然就会溢出了,从而导致data abort数据中止异常。

当发现当前采样值小于上一次的采样值时,应先减再加就不会产生溢出异常了。正确写法如下:

rcvBuf[capCnt] = (0xffffffff - rcvLast) + rcvCur ;

但是,上机测试后仍然不行,实在是不明白是什么原因了。没办法只得采用开始的办法,不管什么数据,先发送走再说。

//向TaskFlowmeter任务发送邮件
OSMboxPost(pMbox_App_CapISR_Flowmeter, (void *)&rcv);


期待正解啊。

 

 

关键字:IAR环境  LPC2129  脉冲捕捉  死机问题 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向