0

我正在为一种单线通信协议编写低级驱动程序。这条线连接到 STM32F0 微控制器上的 Tx 引脚和 Rx 引脚,以 8Mhz 运行内部时钟。Tx 引脚状态在定时器中断中设置,Rx 引脚在外部 GPIO 中断中读取。

为了测试,我在 416µs 时切换 Tx 引脚(自动重载值为 3333,没有预分频器),在 GPIO 中断中,我读取了 2 个连续中断之间的时序差。测量的时间大约是从“高到低”转换中断到“低到高”转换中断的 500µs 和从“低到高”转换中断到“高到低”转换中断的 300µs。为什么会有这样的差异?以及如何摆脱它?

我检查了示波器上的信号,它是一个脉冲宽度为 416µs 的完美方波。我还使用htim->Instance->CNT = 0;time = htim->Instance->CNT;包装代码的不同部分以查找差异的来源,但无济于事。

这是中断句柄,测量的时间保存在tim3_value变量中:

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;
}
4

1 回答 1

1

STM32 定时器已预加载 ARR。这意味着它将在更新事件上更改内部 ARR 寄存器的实际值。如果您想在特定时刻更改它,您需要自己通过写入1EGR 寄存器中的 UG 位来生成此事件。

我强烈建议仔细阅读 STM32 参考手册,因为神奇的 HAL 功能还不够

无论如何,我不会在中断中这样做。STM32时代有个机制叫“直接传输模式”。它使用 DMA 加载所选事件的定时器寄存器的值。您只需要为其准备数据,更新事件 ARR 将自动从内存中加载。

于 2020-09-30T20:43:38.640 回答