I got several lines of code in TIM1_CC_IRQHandler and need to know its exact running time because some real-time requirements.
So when I run simulation I got a time span between the entrance and the exit of the ISR. I write down the value of TIM1->CNT at the entrance, the start time is 0x0242. Then set a breakpoint at the exit of the ISR and run. At the exit TIM1->CNT is 0x0288.
(I have adopted the code DBGMCU->CR |= DBGMCU_TIM1_STOP in initialization)
BUT when I emulation(connect to hardware through JLink), the start time is 0x0245, the exit time is 0x02DD.
It was big shock and difference to me. The Simulation's timespan differs from the Emulation's timespan of the same code! Why?
The Simulation's timespan is decimal 70 system clocks(TIM1 72MHz), while the Emulation's timespan is 152 system clocks. Doubling the previous one and even more!
So what's wrong with it? In my project I must know the exact time of the ISR, which timespan should I trust?
我的工程需要用到TIM1_CC_IRQHandler中断,需要知道我写在里面的代码的准确具体的执行时间。
因此,在中断入口和出口设置断点,在断点处记录TIM1->CNT的值(TIM1的时钟为72MHz,且已经设置了断点时TIM1停止运行,来获得准确的TIM1的值。)
首先我模拟运行,发现入口断点处TIM1->CNT = 0x242,而出口处TIM1->CNT = 0x0288,时间差是70个系统时钟;
而当我用JLink连接硬件实际运行时,发现入口断点处TIM1->CNT = 0x245,而出口处TIM1->CNT = 0x02DD,时间差是152个系统时钟!
模拟运行的代码时间和实际运行的代码时间非常不同!
那我到底是应该信任哪一个时间呢?
下面是我的代码:
Below is my ISR code:
#include “stm32f10x.h”
#define DBGMCU_TIM1_STOP ((u32)0x00000400)
u16 CCR_Acc_x;
u16 CCR_Acc_y;
int main(void)
{
RCC->APB2ENR = 0x0845; //使能TIM1和GPIOA/E和AFIO时钟}
GPIOA->CRH = 0x0B; //PA8,9配置为复用推挽输出,50MHz
TIM1->ARR = 0xffff; //ARR为最大值,使用CCR1和CCR2的比较匹配事件来产生中断
TIM1->DIER = 0x06; //使能中断CC1IE和CC2IE
TIM1->CCMR1 = 0x3030; //CH1和CH2都是输出比较模式(翻转)
TIM1->BDTR = 0x8000; //使能MOE主输出
TIM1->CCER |= TIM_CCER_CC1E; //使能CC1E输出
TIM1->CR1 |= TIM_CR1_CEN; //使能定时器
CCR_Acc_x = 562;
CCR_Acc_y = 18000;
TIM1->CCR1 = CCR_Acc_x;
TIM1->CCR2 = CCR_Acc_y;
TIM1->CCR3 = 0xffff;
TIM1->CCR4 = 0xffff;
NVIC_SetPriorityGrouping(4); //3 bits preemption
NVIC_SetPriority(TIM1_CC_IRQn, 0); //highest
NVIC_EnableIRQ(TIM1_CC_IRQn);
DBGMCU->CR |= DBGMCU_TIM1_STOP;
while(1)
{
}
u16 TIM1_SR_mask;
void TIM1_CC_IRQHandler(void)
{//entrance breakpoint here
TIM1_SR_mask = TIM1->SR;
if (TIM1_SR_mask & TIM_SR_CC1IF) //CC1IF
{
TIM1->SR = ~TIM_SR_CC1IF;TIM1->CCR1 = TIM1->CCR1 + CCR_Acc_x;
}
if (TIM1_SR_mask & TIM_SR_CC2IF) //CC2IF
{
TIM1->SR = ~TIM_SR_CC2IF;
}
TIM1_SR_mask = TIM1->SR;
if (TIM1_SR_mask & TIM_SR_CC1IF) //CC1IF
{
NVIC_SetPendingIRQ(TIM1_CC_IRQn);
}
if (TIM1_SR_mask & TIM_SR_CC2IF) //CC2IF
{
NVIC_SetPendingIRQ(TIM1_CC_IRQn);
}}//exit breakpoint here
my Chip: STM32F103 ZET6
my IDE: Keil MDK 4.73
JLink 4.76d