问题现象:
在数据采集时一段时间会出现停止采集的情况,经过在线debug发现此时TBCCR0的值和TBR的值相差约为1.3s,即1.3s后才会再次产生TB0中断,才会再次采集数据。
使用背景:
用TB0做传感器定时采集,因为向传感器发送采集命令后要等待大约6ms才能获取到传感器数据,所以TB0的中断逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | __interrupt void Timer_B0_ISR(void) { TBCCTL0 &= ~CCIE; //关闭中断 switch (SampleCtrl.State) { case SAMPLE_STATE_SEND: //发送采集命令 LED2ON; TBCCR0 = TBR + 262; //8ms 发送采集命令; SampleCtrl.State = SAMPLE_STATE_READ; break; case SAMPLE_STATE_READ: //读取采集结果 if (g_bDRDYFlg) //DRDY脚中断使该标志置位,表明一次数据采集完成 { g_bDRDYFlg = FALSE; SampleCtrl.State = SAMPLE_STATE_SEND; if //采集的数据有效 { EventReqQue |= DETECT_VEHICLE; //完成一次采集,设置剩余定时时间 if (SAMPLE_FREQ_HI == SampleCtrl.Freq) //设置为10ms-8ms { TBCCR0 = TBR + 65; //2ms } else //设置为100ms-32ms { TBCCR0 = TBR + 3014; //92ms } LPM3_EXIT; } else //采集的数据无效 { TBCCR0 = TBR + 20; } } else //数据采集尚未完成 { TBCCR0 = TBR + 20; //约60us后再次进入中断,再去读取数据。 } break; default: SampleCtrl.State = SAMPLE_STATE_SEND; break; } |
1 |
1 | } |
问题原因:
由于在传感器数据采集时还需要跟24L01通信,为了保证SPI通信可靠,读写24L01时禁止了地磁采集,而禁止地磁采集时只是禁止了TB0中断,并没有停止TB,所以TB是一直在运行的,在TB0中断被禁止时TB0产生中断,则不会被响应,而开启TB0中断时人为清除了TB0中断标志,所以导致该次TB0中断不会被响应。从而TBCCR0不会被重新配置,使得TB0要在下一次等于TBCCR0时才能产生中断,而这个时间最大为2s。
解决方法:
在再次开启TB0中断时不应该人为清除TB0中断标志。因为这个中断是应该要响应的,只是在与24L01进行SPI通信时暂时被禁止。
一开始想要在禁止TB0中断时停止TB,这个思路是错误的,而且并没有针对问题的关键。一方面,TB是不应该被停止的,另一方面,导致2s左右没有采集地磁的真正原因是人为清除了TB0中断标志使得TBCCR0错过了一次配置。