STM32定时器输出比较不能正常工作
Posted
技术标签:
【中文标题】STM32定时器输出比较不能正常工作【英文标题】:STM32 Timer Output compare not working proper 【发布时间】:2020-07-09 17:52:23 【问题描述】:我正在使用 STM32L476 Nucleo 板和 STM32CubeMX。我想将输出比较通道 1 用于 2 毫秒的超时。我已经配置了定时器,但定时器没有为输出比较提供中断。我在给定时器的时间段内收到中断,但不是输出比较。
这是我的定时器配置:
static void MX_TIM1_Init(void)
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = 0;
TIM_SlaveConfigTypeDef sSlaveConfig = 0;
TIM_MasterConfigTypeDef sMasterConfig = 0;
TIM_OC_InitTypeDef sConfigOC = 0;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = 0;
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = TIMER1_PRESCALER_VAL;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = TIMER_PERIOD;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
Error_Handler();
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
Error_Handler();
if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
Error_Handler();
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
sSlaveConfig.InputTrigger = TIM_TS_ITR0;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
Error_Handler();
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
Error_Handler();
sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
sConfigOC.Pulse = 1000 * TIMER_OC_1_VAL;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
Error_Handler();
sBreakDeadTimeConfig.OffStateRunMode = TIM_Os-s-r_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
Error_Handler();
/* USER CODE BEGIN TIM1_Init 2 */
HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
我尝试更改 sConfigOC.Pulse
值,但没有看到预期的行为。
【问题讨论】:
【参考方案1】:您是否在中断处理程序中检查正确的中断标志? 另外请记住,您必须立即清除标志。
我的 IRQHandler 看起来像这样,如果这对你有帮助的话。
void TIM3_IRQHandler(void)
if(LL_TIM_IsActiveFlag_CC1(TIM3) == 1)
LL_TIM_ClearFlag_CC1(TIM3);
TimerCaptureCompare_Callback();
编辑:
看起来不错,HAL_TIM_OC_DelayElapsedCallback
中断仅在计时器溢出(即重置)时触发。
这意味着您必须启用溢出中断,因为HAL_TIM_OC_Start_IT
仅启用捕获/比较中断。
您只需要在启用计时器之前启用它即可。
__HAL_TIM_ENABLE_IT(&tim3, TIM_IT_UPDATE );
【讨论】:
这个标志在 HAL 库的定时器处理函数中被清除。 好的,我做了一些研究,发现了一些有趣的东西。但它没有很好的记录。【参考方案2】:尝试将“TIM_IT_CC1”替换为“TIM_CHANNEL_1”。
【讨论】:
虽然它可能会解决问题,但这更像是一个评论而不是一个答案,因为它是一个问题并且没有上下文。【参考方案3】:首先,您必须在启动定时器之前初始化输出引脚:
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
/* USER CODE BEGIN TIM1_Init 2 */
HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);
其次,你要启动输出定时器
HAL_TIM_OC_Start_IT( &htim1, TIM_CHANNEL_1 );
HAL_TIM_Base_Start_IT( &htim1 );
你的输出引脚是这样启用的: (此代码适用于 Stm32F4xx)
GPIO_InitStruct.Pin = GPIO_PIN_9; // channel 1
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
我不确定您是否需要 BREAK 代码。看看参考手册中的17.3.12使用break函数
【讨论】:
以上是关于STM32定时器输出比较不能正常工作的主要内容,如果未能解决你的问题,请参考以下文章