项目场景:
前段时间合宙官方搞活动,买了一个air001开发板和几片芯片,价格很香,买来一直吃灰,这段时间做小玩意,发现这款芯片挺合适,于是心血来潮捣鼓起来,官方例程很全,便拿官方PWM例程测试,发现开发板上的led不能被点亮
问题描述
发现问题出在没有对PWM的输出GPIO管脚进行初始化,和没有开启PWM时钟,官方例程如下
int main(void)
{
/* 初始化所有外设,Flash接口,SysTick */
HAL_Init();
/* 系统时钟配置 */
APP_SystemClockConfig();
TimHandle.Instance = TIM1; /* 选择TIM1 */
TimHandle.Init.Period = 50; /* 自动重装载值 */
TimHandle.Init.Prescaler = 800 - 1; /* 预分频为800-1 */
TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; /* 时钟不分频 */
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; /* 向上计数 */
TimHandle.Init.RepetitionCounter = 1 - 1; /* 不重复计数 */
TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; /* 自动重装载寄存器没有缓冲 */
/* 基础时钟初始化 */
if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK)
{
Error_Handler();
}
sConfig.OCMode = TIM_OCMODE_PWM1; /* 输出配置为PWM1 */
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; /* OC通道输出高电平有效 */
sConfig.OCFastMode = TIM_OCFAST_DISABLE; /* 输出快速使能关闭 */
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; /* OCN通道输出高电平有效 */
sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; /* 空闲状态OC1N输出低电平 */
sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; /* 空闲状态OC1输出低电平 */
sConfig.Pulse = PULSE1_VALUE; /* CC1值为10,占空比=10/50=20% */
/* 配置通道1 */
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfig.Pulse = PULSE2_VALUE; /* CC2值为20,占空比=20/50=40% */
/* 配置通道2 */
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sConfig.Pulse = PULSE3_VALUE; /* CC3值为30,占空比=30/50=60% */
/* 配置通道3 */
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_3) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
sConfig.Pulse = PULSE4_VALUE; /* CC4值为40,占空比=40/50=80% */
/* 配置通道4 */
if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
/* 开启所有通道输出 */
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
while (1)
{
}
}
于是加上PWM输出对应的GPIO的初始化函数,开发板第三个led灯对应管脚GPIOB_3,是PWM1的通道2,初始化函数如下参考其他例程
static void PWM_GPIO_Init(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_StructInit;
GPIO_StructInit.Pin=GPIO_PIN_3;
GPIO_StructInit.Mode=GPIO_MODE_AF_PP;
GPIO_StructInit.Pull=GPIO_NOPULL;
GPIO_StructInit.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_StructInit.Alternate=GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOB,&GPIO_StructInit);
}
其中需要注意这句
GPIO_StructInit.Alternate=GPIO_AF1_TIM1;
这个参数要填,并且要对应,这个在官方数据手册上有表格说明。在官方手册的3.3 端口复用功能列表
如下图所示
找到对应的GPIO即可,然后在hal库里找到对应语句即可。
至于开启PWM语句,我一开始没有加,也能使用,但后来见别人加了我也加了上去,没去探究为什么
__HAL_RCC_TIM1_CLK_ENABLE();//开启TIM1时钟