我似乎无法让TIM8 PWM与我尝试的任何东西一起工作。我已经尝试过所有计时器,除TIM8外,他们都使用我的PWM驱动程序。所有计时器都是使用CubeMx生成的,没有冲突。
以下是代码的一些内容。驱动程序相当大,所以我删除了部分内容:
引脚配置:
//Tim 8 Chan 1 IN1A
GPIO_InitStructure.Pin = GPIO_PIN_6;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF3_TIM8;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
//Tim 8 Chan 2 IN1B
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF3_TIM8;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
//Tim 8 Chan 3 IN2A
GPIO_InitStructure.Pin = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF3_TIM8;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
//Tim 8 Chan 4 IN2B
GPIO_InitStructure.Pin = GPIO_PIN_9;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF3_TIM8;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
定时器设置:
static PWM_ERC_T Timer8_Init(PWM_HANDLE_T *pwmHandle_, uint16_t prescaler_, uint16_t period_, uint16_t pulse_)
{
PWM_ERC_T erc = PWM_ERC_NO_ERROR;
__TIM8_CLK_ENABLE();
pwmHandle_->TimerHandle.Instance = TIM8;
TIM_MasterConfigTypeDef masterConfig;
TIM_BreakDeadTimeConfigTypeDef breakDeadTimeConfig;
TIM_OC_InitTypeDef configOC;
pwmHandle_->TimerHandle.Init.Prescaler = prescaler_;
pwmHandle_->TimerHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
pwmHandle_->TimerHandle.Init.Period = period_;
pwmHandle_->TimerHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
pwmHandle_->TimerHandle.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&pwmHandle_->TimerHandle);
masterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
masterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
masterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&pwmHandle_->TimerHandle, &masterConfig);
breakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
breakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
breakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
breakDeadTimeConfig.DeadTime = 0;
breakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
breakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
breakDeadTimeConfig.BreakFilter = 0;
breakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
breakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
breakDeadTimeConfig.Break2Filter = 0;
breakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&pwmHandle_->TimerHandle, &breakDeadTimeConfig);
configOC.OCMode = TIM_OCMODE_PWM1;
configOC.Pulse = pulse_;
configOC.OCPolarity = TIM_OCPOLARITY_HIGH;
configOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
configOC.OCFastMode = TIM_OCFAST_DISABLE;
configOC.OCIdleState = TIM_OCIDLESTATE_RESET;
configOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if(pwmHandle_->Init.Channels & PWM_CHANNEL_1)
{
HAL_TIM_PWM_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_1);
}
if(pwmHandle_->Init.Channels & PWM_CHANNEL_2)
{
HAL_TIM_PWM_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_2);
}
if(pwmHandle_->Init.Channels & PWM_CHANNEL_3)
{
HAL_TIM_PWM_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_3);
}
if(pwmHandle_->Init.Channels & PWM_CHANNEL_4)
{
HAL_TIM_PWM_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_4);
}
我向您保证每个频道都已启用,并且预先计算器/时段和时段正在正确计算。
有什么想法?这是唯一有问题的计时器。
解决方案:
终于弄清楚出了什么问题。
HAL_TIM_OC_Init(&pwmHandle_->TimerHandle);
由于某些原因,必须为TIM8添加...不确定原因和
HAL_TIM_OC_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_1);
需要使用代替
HAL_TIM_PWM_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_1);
更正定时器设置:
static PWM_ERC_T Timer8_Init(PWM_HANDLE_T *pwmHandle_, uint16_t prescaler_, uint16_t period_, uint16_t pulse_)
{
PWM_ERC_T erc = PWM_ERC_NO_ERROR;
TIM_MasterConfigTypeDef masterConfig;
TIM_BreakDeadTimeConfigTypeDef breakDeadTimeConfig;
TIM_OC_InitTypeDef configOC;
pwmHandle_->TimerHandle.Init.Prescaler = prescaler_;
pwmHandle_->TimerHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
pwmHandle_->TimerHandle.Init.Period = period_;
pwmHandle_->TimerHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
pwmHandle_->TimerHandle.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&pwmHandle_->TimerHandle);
HAL_TIM_PWM_Init(&pwmHandle_->TimerHandle);
masterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
masterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
masterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&pwmHandle_->TimerHandle, &masterConfig);
breakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
breakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
breakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
breakDeadTimeConfig.DeadTime = 0;
breakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
breakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
breakDeadTimeConfig.BreakFilter = 0;
breakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
breakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
breakDeadTimeConfig.Break2Filter = 0;
breakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&pwmHandle_->TimerHandle, &breakDeadTimeConfig);
configOC.OCMode = TIM_OCMODE_PWM1;
configOC.Pulse = pulse_;
configOC.OCPolarity = TIM_OCPOLARITY_HIGH;
configOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
configOC.OCFastMode = TIM_OCFAST_DISABLE;
configOC.OCIdleState = TIM_OCIDLESTATE_RESET;
configOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if(pwmHandle_->Init.Channels & PWM_CHANNEL_1)
{
HAL_TIM_OC_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_1);
}
if(pwmHandle_->Init.Channels & PWM_CHANNEL_2)
{
HAL_TIM_OC_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_2);
}
if(pwmHandle_->Init.Channels & PWM_CHANNEL_3)
{
HAL_TIM_OC_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_3);
}
if(pwmHandle_->Init.Channels & PWM_CHANNEL_4)
{
HAL_TIM_OC_ConfigChannel(&pwmHandle_->TimerHandle, &configOC, TIM_CHANNEL_4);
}
return erc;
}