在 STM32 的 HAL 库中调用 HAL_TIM_PWM_Stop(&htim, Channel)函数后,PWM 输出引脚的电平状态是确定的,但具体是高电平还是低电平取决于你在启动 PWM 前如何配置定时器通道的比较输出极性(TIM_OCPOLARITY)。
HAL_TIM_PWM_Stop的作用
这个函数的核心操作是将定时器通道对应的 Capture/Compare Enable Register (CCER) 中的 Capture/Compare x Enable bit (CCxE) 清零,CCxE = 0 意味着关闭了该通道的比较输出。
电平决定性的条件
当 CCxE被清零后,定时器通道的输出引脚不再由定时器的 PWM 生成逻辑控制。
此时,引脚的输出状态由 Output Control Circuit (OCC) 的一个特定状态决定,称为 Output Disable State 或者 Idle State。
这个 空闲状态 / 关闭状态电平 就是在初始化 PWM (HAL_TIM_PWM_Init) 后,并在启动 PWM (HAL_TIM_PWM_Start) 前,通过 HAL_TIM_PWM_ConfigChannel函数(或者配置 TIM_OC_InitTypeDef结构体并调用 HAL_TIM_PWM_ConfigChannel) 时指定的 TIM_OCPOLARITY 设置所决定的反相状态。
关闭输出后的电平状态
TIM_OCPOLARITY_HIGH(默认值):空闲状态/关闭状态是 低电平,调用 HAL_TIM_PWM_Stop后,引脚会变低。
TIM_OCPOLARITY_LOW:空闲状态/关闭状态是 高电平,调用 HAL_TIM_PWM_Stop后,引脚会变高。
#include "stm32f1xx_hal.h"
#include "delay.h"
TIM_HandleTypeDef htim1,htim3;
static TIM_HandleTypeDef *hal_timx = &htim3;
//使用20kHz 频率
#define PWM_FREQ_HZ (20000)
void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
uint32_t sys_freq = HAL_RCC_GetSysClockFreq(); // 获取系统时钟频率72MHz
uint32_t prescaler = 1; // 预分频系数
uint32_t reload_val = (sys_freq / (prescaler + 1) / PWM_FREQ_HZ) - 1; // 自动重装载值
/************************************ GPIO PA6 初始化************************************/
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; //必须使用复用推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高频20kHz 管脚建议使用高速度
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/************************************ AFIO 复用时钟 ************************************/
__HAL_RCC_AFIO_CLK_ENABLE();
/************************************ 时钟源配置 ************************************/
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(hal_timx, &sClockSourceConfig);
/************************************ PA6 TIM3 CH1 ************************************/
__HAL_RCC_TIM3_CLK_ENABLE();
//PA6 TIM3 CH1
hal_timx->Instance = TIM3;
hal_timx->Init.Prescaler = prescaler;
hal_timx->Init.Period = reload_val;
hal_timx->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
hal_timx->Init.CounterMode = TIM_COUNTERMODE_UP;
hal_timx->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
HAL_TIM_Base_Init(hal_timx);
HAL_TIM_PWM_Init(hal_timx);
//pwm配置
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = (reload_val + 1) / 2; // 初始输出约50%占空比
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 输出极性为高电平有效,使用HAL_TIM_PWM_Stop时极性相反
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // 普通的pwm模式时默认关闭即可
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
//输出
HAL_TIM_PWM_ConfigChannel(hal_timx, &sConfigOC, TIM_CHANNEL_1);
hal_timx = &htim3;
HAL_TIM_PWM_Start(hal_timx, TIM_CHANNEL_1); // 启动TIM3通道3
}
void PWM_Stop_PA6_To_Low(void)
{
hal_timx = &htim3;
HAL_TIM_PWM_Stop(hal_timx, TIM_CHANNEL_1);
delay_ms(1000); // debug在此处停留观看输出电平
HAL_TIM_PWM_Start(hal_timx, TIM_CHANNEL_1);
delay_ms(1000);
}
STM32调用HAL_TIM_PWM_Stop后引脚电平状态

被折叠的 条评论
为什么被折叠?



