在项目进行过程中,设置了脉冲捕捉,然后发生间断,我的做法是,设置了个全局变量环形数组,将捕获的脉冲计数值与前一次作差后放入环形数组里,然后由相关使命去处理。然是奇怪的是,捕捉间断进行几回之后就不再呼应了,并且还会导致死机,代码如下:
#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);
等待正解啊。
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/jichu/262694.html