stm32f103内部中断无法达到想要的频率(350ns)(最低达到4us)
stm32f103 internal interrupt can not reach the wanted frequency (350ns) (lowest reached is 4us)
我正在尝试使用 TIMER1 生成的中断通过将 GPIO 引脚调高和调低来生成 PWM 信号,为什么我这样做是完全不同的故事,所以我需要每 350ns 生成一个中断,我计算了 72MHz 的预分频器和 ARR,我发现我需要一个 1 的预分频器和一个 25 的 ARR,所以我根据这些值设置参数,现在我有 25 个时钟周期在下一个中断之前做我想做的事情触发器,所以在每次中断时,指定的引脚必须改变状态(从高到低或从低到高),我正在使用示波器查看输出信号,我被 8us 的输出卡住(这意味着每 4us 中断一次), 我怎样才能解决这个问题?我哪里失败了?我可能做错了什么?
这是我在中断函数中所做的:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if ((GPIOC->ODR & GPIO_PIN_13) != 0x00u)
{
GPIOC-> ODR = 0x0000;
}
else
{
GPIOC-> ODR = 0x2000;
}
}
这是输出信号的照片:
Oscilloscope output
有没有可能是中断里面的代码超过了25个时钟周期?如果是这样我怎么能不超过呢?谢谢
is it possible that the code inside the interrupt exceeds 25 clock
cycle? if so how can i do it without exceeding ? thanks
如果你使用 HAL 停止计数时钟:)
所以首先我们有原始处理程序:中断进入大约需要 12 个时钟 + FLASH 等待状态
void TIMx_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TimHandle);
}
然后我们在刷新管道时调用 HAL 处理程序 + 最少 3 个时钟 + 等待状态。
然后我们有 HAL 功能 - 很多时钟周期:
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
/* Capture compare 1 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
{
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
/* Input capture event */
if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
}
/* Capture compare 2 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
/* Input capture event */
if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* Capture compare 3 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
/* Input capture event */
if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* Capture compare 4 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
/* Input capture event */
if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* TIM Update event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
HAL_TIM_PeriodElapsedCallback(htim);
}
}
/* TIM Break input event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
HAL_TIMEx_BreakCallback(htim);
}
}
/* TIM Trigger detection event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
HAL_TIM_TriggerCallback(htim);
}
}
/* TIM commutation event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
HAL_TIMEx_CommutationCallback(htim);
}
}
}
并最终调用您的函数,执行将花费 8 到 15 个时钟。
所以如果你总共有 25 个时钟,那你就是一个非常幸运的人。
我正在尝试使用 TIMER1 生成的中断通过将 GPIO 引脚调高和调低来生成 PWM 信号,为什么我这样做是完全不同的故事,所以我需要每 350ns 生成一个中断,我计算了 72MHz 的预分频器和 ARR,我发现我需要一个 1 的预分频器和一个 25 的 ARR,所以我根据这些值设置参数,现在我有 25 个时钟周期在下一个中断之前做我想做的事情触发器,所以在每次中断时,指定的引脚必须改变状态(从高到低或从低到高),我正在使用示波器查看输出信号,我被 8us 的输出卡住(这意味着每 4us 中断一次), 我怎样才能解决这个问题?我哪里失败了?我可能做错了什么? 这是我在中断函数中所做的:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if ((GPIOC->ODR & GPIO_PIN_13) != 0x00u)
{
GPIOC-> ODR = 0x0000;
}
else
{
GPIOC-> ODR = 0x2000;
}
}
这是输出信号的照片: Oscilloscope output
有没有可能是中断里面的代码超过了25个时钟周期?如果是这样我怎么能不超过呢?谢谢
is it possible that the code inside the interrupt exceeds 25 clock cycle? if so how can i do it without exceeding ? thanks
如果你使用 HAL 停止计数时钟:)
所以首先我们有原始处理程序:中断进入大约需要 12 个时钟 + FLASH 等待状态
void TIMx_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TimHandle);
}
然后我们在刷新管道时调用 HAL 处理程序 + 最少 3 个时钟 + 等待状态。
然后我们有 HAL 功能 - 很多时钟周期:
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
/* Capture compare 1 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
{
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
/* Input capture event */
if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
}
/* Capture compare 2 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
/* Input capture event */
if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* Capture compare 3 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
/* Input capture event */
if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* Capture compare 4 event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
/* Input capture event */
if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
{
HAL_TIM_IC_CaptureCallback(htim);
}
/* Output compare event */
else
{
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* TIM Update event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
HAL_TIM_PeriodElapsedCallback(htim);
}
}
/* TIM Break input event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
HAL_TIMEx_BreakCallback(htim);
}
}
/* TIM Trigger detection event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
HAL_TIM_TriggerCallback(htim);
}
}
/* TIM commutation event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
HAL_TIMEx_CommutationCallback(htim);
}
}
}
并最终调用您的函数,执行将花费 8 到 15 个时钟。
所以如果你总共有 25 个时钟,那你就是一个非常幸运的人。