How to get interrupt after specified number of microseconds?
My idea was simple. Set TIM to have 1MHz after prescaler. Then set ARR to the number of microseconds. So - I toggle GPIO pin each period elapsed and I can measure the time on oscilloscope.
And here come troubles: for set 1us i get 2us. For 2us I get 2us. For 5us I get 5us.
So - times below 2us are unachievable. But it's fine, the shortest time I need is 6us.
But then again, I don't need to spam the interrupts every 6us, I need it only when I send a data bit. So - I set the TIM in the "One Pulse Mode". And here comes another surprise. Whatever time I set - circa 1.9us is added to it.
Here's the fragment of my test code:
static void tim_test_period(TIM_HandleTypeDef* htim)
{
if (!(data->state & 1))
{
data->GPIO->ODR &= ~data->PinBit;
}
else
{
data->GPIO->ODR |= data->PinBit;
}
data->TIM->Instance->CNT = 19;
__HAL_TIM_ENABLE(data->TIM);
data->state++;
if (data->state > 3) data->state = 0;
}
void tim_test_start()
{
debug("Starting TIM test...");
HAL_TIM_Base_Stop(data->TIM);
data->TIM->Instance->PSC = 20 - 1; // 20Mhz
data->TIM->Instance->ARR = 50 - 1; // 200kHz
HAL_TIM_RegisterCallback(data->TIM, HAL_TIM_PERIOD_ELAPSED_CB_ID, tim_test_period);
__HAL_TIM_ENABLE(data->TIM);
__HAL_TIM_ENABLE_IT(data->TIM, TIM_IT_UPDATE);
}Here's my signal (5us/div):
99.6KHz, accurate enough for what I need.
But why do I need to add 19 to the CNT? This is the time lost somewhere, is it between the timer reaching zero and interrupt triggered? Does it take 1.95us?
The MCU is running on 400MHz clock. The few lines of code in the interrupt handler don't affect the timing at all. When I don't restart the timer, when it runs continuously, I can set any time greater than 2us and it's totally accurate.
So I have 2 options now:
- Set the CNT to 19 (or any value equivalent of like 1.95us) on each interrupt. But will it be consistent?
- Set the timer to run continuously with 6us period, count the sixes in code and have the fixed accuracy of 6us, but pretty high CPU load even if I don't need those short times.
Option 1 seems tempting, it would be exactly what I want, I start the timer, I get the interrupt exactly n microseconds later. Or 480us later (and the CPU is not bothered during that time). I just wish I knew why do I have that delay in one pulse mode and why it's value is 1.95us.