0
votes

I am writing a low level driver for a type of one line communication protocol. This line is connected to both Tx pin and Rx pin on a STM32F0 micro running internal clock at 8Mhz. The Tx pin state is set in a timer interrupt, and the Rx pin is read in a external GPIO interrupt.

For testing, I toggle the Tx pin at 416µs (auto reload value is 3333 with no prescaler), and in the GPIO interrupt I read the timing difference between 2 consecutive interrupts. The measured time are roughly 500µs from "High To Low" transition interrupt to "Low To High" transition interrupt and 300µs from "Low To High" transition interrupt to "High To Low" transition interrupt. Why is there such a difference? And how to get rid of it?

I have checked the signal on the scope and it's a perfect square wave with pulse width of 416µs. I also use htim->Instance->CNT = 0; and time = htim->Instance->CNT; to wrap different parts of the code to find where the difference comes from but no avail.

Here are the interrupt handles, the measured time is saved in tim3_value variable:

void TIM2_IRQHandler(void)
{
  if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET)
  {
    if (__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) != RESET)
    {
        __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);
        HAL_GPIO_TogglePin(TX_GPIO_Port, TX_Pin);
        htim2.Instance->ARR = 3333;
    }
  }
return;
}

void EXTI4_15_IRQHandler(void)
{
  if(__HAL_GPIO_EXTI_GET_IT(RX_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(RX_Pin);
    tim3_value = htim3.Instance->CNT;
    htim3.Instance->CNT = 0;
  }
return;
}
1
Probably because of the physical properties of the input/output pins. Their transition times and hi/lo threshold voltagesEugene Sh.
I have measured the time between the end of the timer interrupt and the beginning of the GPIO interrupt but didn't find any significant differencecuckoo
@EugeneSh. negligible.0___________
OK, how do you measure the time?Eugene Sh.
Are these interrupts guaranteed to arrive at a particular time? Can they be held up if other interrupt processing is under way?tadman

1 Answers

1
votes

STM32 timers have ARR preloaded. It means that it will change the actual value of the interal ARR register on the update event. If you want to change it at particular moment you need to generate this event yourself by writing 1 to the UG bit in the EGR register.

I strongly advice to read carefully the STM32 Reference Manual as magical HAL functions are not enough

I would not do it in the interrupt anyway. STM32 times have a mechanism called "direct transfer mode". It uses DMA to load the value(s) of the timer register on the chosen event. You just need to prepare data for it and on the update event ARR will be loaded from the memory autoatically.