STM32第八课(PWM,HAL)

定时器TIM,产生 PWM 输出。

当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。

改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的
频率,
除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。
高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。
通用定时器也能同时产生多达 4路的 PWM 输出。
3 个寄存器,来控制 PWM 的。
捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2控制 CH3 和 4。
TIMx_CCER,该寄存器控制着各个输入输出通道的开关。 CC1E 位,该位是输入/捕获 1 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。
TIMx_CCR1到4),该寄存器总共有 4 个,对应 4 个通道 CH1到4。
输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。

如果是高级定时器,则还需要配置:刹车和死区寄存器(TIMx_BDTR),

++++++++++++++++++++++++++++++++++++
首先要提到的是, PWM 实际使用的是定时器的功能,所以相关的函数设置同样在库函数文件 stm32f4xx_hal_tim.h 和 stm32f4xx_hal_tim.c 文件中。

开启 TIM14 和 GPIO 时钟,配置 PF9 选择复用功能 AF9(TIM14) 输出。
要使用 TIM14,我们必须先开启 TIM14 的时钟,还要配置 PF9 为复用(AF9) 输出, 才可以实现 TIM14_CH1 的 PWM 经过 PF9输出。
HAL 库使能 TIM14 时钟和 GPIO 时钟方法是:

__HAL_RCC_TIM14_CLK_ENABLE(); //使能定时器 14
__HAL_RCC_GPIOF_CLK_ENABLE(); //开启 GPIOB 时钟

配置 PF9 复用映射为 TIM 的 PWM 输出引脚。

GPIO_Initure.Pin=GPIO_PIN_9; //PF9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速

GPIO_Initure.Alternate= GPIO_AF9_TIM14; //PF9 复用为 TIM14_CH1

HAL_GPIO_Init(GPIOF,&GPIO_Initure);

初始化 TIM14,设置 TIM14 的 ARR 和 PSC 等参数。
对于我们使用定时器的 PWM 输出功能时, HAL 库为我们提供了一个独立的定时器初始化函数 HAL_TIM_PWM_Init,该函数声明为:

HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim);

HAL 库 为 定 时 器 的 PWM 输 出 定 义 了 单 独 的 MSP 回 调 函 数HAL_TIM_PWM_MspInit,该函数声明为:

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim);

设置 TIM14_CH1 的 PWM 模式, 使能 TIM14 的 CH1 输出。
配置 TIM14_CCMR1 的相关位来控制 TIM14_CH1 的模式。
HAL 库中, PWM 通道设置是通过函数 HAL_TIM_PWM_ConfigChannel 来设置的:

HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim,
							TIM_OC_InitTypeDef* sConfig, uint32_t Channel);

参数 htim 是定时器初始化句柄,
参数 sConfig 是 TIM_OC_InitTypeDef 结构体指针类型,这也是该函数最重要的参数。该参数用来设置 PWM 输出模式,极性,比较值等重要参数。
参 数 Channel 用 来 选 择 定 时 器 的 通 道 ,
取 值 范 围 为 TIM_CHANNEL_1到TIM_CHANNEL_4。

看看结构体定义:

typedef struct
{
	uint32_t OCMode; //PWM 模式
	uint32_t Pulse; //捕获比较值
	uint32_t OCPolarity; //极性
	uint32_t OCNPolarity;
	uint32_t OCFastMode; //快速模式
	uint32_t OCIdleState;
	uint32_t OCNIdleState;
} TIM_OC_InitTypeDef;

OCMode 用来设置模式,这里我们设置为 PWM 模式 1。
Pulse 用来设置捕获比较值。
TIM_OCPolarity 用 来 设 置 输 出 极 性 是 高 还 是 低 。

例如我们要初始化定时器 14 的通道 1 为 PWM 模式 1,输出极性为低,那么实例代码为:

TIM_OC_InitTypeDef TIM14_CH1Handler; //定时器 14 通道 1 句柄
TIM3_CH4Handler.OCMode=TIM_OCMODE_PWM1; //模式选择 PWM1
TIM3_CH4Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比
TIM3_CH4Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低
HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH4Handler,TIM_CHANNEL_4);

++++++++++++++++++++++++++++++++++++
启动 TIM14。
定时器初始化之后,并没有启动。
启动定时器,需要手工启动。

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

参数 Channel 是用来设置要使能输出的通道号。

例如:

HAL_TIM_PWM_Start(&TIM14_Handler,TIM_CHANNEL_1);//开启 PWM 通道 1

HAL 库也同样提供了单独使能定时器的输出通道函数,函数为:

void TIM_CCxChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelState);

启动后,PWM 其实已经开始输出了,通过修改比较值 TIM14_CCR1 则可以控制 CH1 的输出占空比。HAL 库中并没有提供独立的修改占空比函数,编写如下:

void TIM_SetTIM14Compare1(u32 compare)
{
TIM14->CCR1=compare;
}

++++++++++++++++++++++++++++++++++++++++++
定时器如果是为了产生事件,那么就需要配合中断系统使用,将事件驱动的执行代码放在callback中处理。
定时器如果是为了生成PWM,那么不需要产生中断事件,这时,它就是一个自动工作的外设。

版权声明:本文为CSDN博主「Huskar_Liu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42418557/article/details/121971202

定时器TIM,产生 PWM 输出。

当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。

改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的
频率,
除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。
高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。
通用定时器也能同时产生多达 4路的 PWM 输出。
3 个寄存器,来控制 PWM 的。
捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2控制 CH3 和 4。
TIMx_CCER,该寄存器控制着各个输入输出通道的开关。 CC1E 位,该位是输入/捕获 1 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。
TIMx_CCR1到4),该寄存器总共有 4 个,对应 4 个通道 CH1到4。
输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。

如果是高级定时器,则还需要配置:刹车和死区寄存器(TIMx_BDTR),

++++++++++++++++++++++++++++++++++++
首先要提到的是, PWM 实际使用的是定时器的功能,所以相关的函数设置同样在库函数文件 stm32f4xx_hal_tim.h 和 stm32f4xx_hal_tim.c 文件中。

开启 TIM14 和 GPIO 时钟,配置 PF9 选择复用功能 AF9(TIM14) 输出。
要使用 TIM14,我们必须先开启 TIM14 的时钟,还要配置 PF9 为复用(AF9) 输出, 才可以实现 TIM14_CH1 的 PWM 经过 PF9输出。
HAL 库使能 TIM14 时钟和 GPIO 时钟方法是:

__HAL_RCC_TIM14_CLK_ENABLE(); //使能定时器 14
__HAL_RCC_GPIOF_CLK_ENABLE(); //开启 GPIOB 时钟

配置 PF9 复用映射为 TIM 的 PWM 输出引脚。

GPIO_Initure.Pin=GPIO_PIN_9; //PF9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速

GPIO_Initure.Alternate= GPIO_AF9_TIM14; //PF9 复用为 TIM14_CH1

HAL_GPIO_Init(GPIOF,&GPIO_Initure);

初始化 TIM14,设置 TIM14 的 ARR 和 PSC 等参数。
对于我们使用定时器的 PWM 输出功能时, HAL 库为我们提供了一个独立的定时器初始化函数 HAL_TIM_PWM_Init,该函数声明为:

HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim);

HAL 库 为 定 时 器 的 PWM 输 出 定 义 了 单 独 的 MSP 回 调 函 数HAL_TIM_PWM_MspInit,该函数声明为:

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim);

设置 TIM14_CH1 的 PWM 模式, 使能 TIM14 的 CH1 输出。
配置 TIM14_CCMR1 的相关位来控制 TIM14_CH1 的模式。
HAL 库中, PWM 通道设置是通过函数 HAL_TIM_PWM_ConfigChannel 来设置的:

HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim,
							TIM_OC_InitTypeDef* sConfig, uint32_t Channel);

参数 htim 是定时器初始化句柄,
参数 sConfig 是 TIM_OC_InitTypeDef 结构体指针类型,这也是该函数最重要的参数。该参数用来设置 PWM 输出模式,极性,比较值等重要参数。
参 数 Channel 用 来 选 择 定 时 器 的 通 道 ,
取 值 范 围 为 TIM_CHANNEL_1到TIM_CHANNEL_4。

看看结构体定义:

typedef struct
{
	uint32_t OCMode; //PWM 模式
	uint32_t Pulse; //捕获比较值
	uint32_t OCPolarity; //极性
	uint32_t OCNPolarity;
	uint32_t OCFastMode; //快速模式
	uint32_t OCIdleState;
	uint32_t OCNIdleState;
} TIM_OC_InitTypeDef;

OCMode 用来设置模式,这里我们设置为 PWM 模式 1。
Pulse 用来设置捕获比较值。
TIM_OCPolarity 用 来 设 置 输 出 极 性 是 高 还 是 低 。

例如我们要初始化定时器 14 的通道 1 为 PWM 模式 1,输出极性为低,那么实例代码为:

TIM_OC_InitTypeDef TIM14_CH1Handler; //定时器 14 通道 1 句柄
TIM3_CH4Handler.OCMode=TIM_OCMODE_PWM1; //模式选择 PWM1
TIM3_CH4Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比
TIM3_CH4Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低
HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH4Handler,TIM_CHANNEL_4);

++++++++++++++++++++++++++++++++++++
启动 TIM14。
定时器初始化之后,并没有启动。
启动定时器,需要手工启动。

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

参数 Channel 是用来设置要使能输出的通道号。

例如:

HAL_TIM_PWM_Start(&TIM14_Handler,TIM_CHANNEL_1);//开启 PWM 通道 1

HAL 库也同样提供了单独使能定时器的输出通道函数,函数为:

void TIM_CCxChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelState);

启动后,PWM 其实已经开始输出了,通过修改比较值 TIM14_CCR1 则可以控制 CH1 的输出占空比。HAL 库中并没有提供独立的修改占空比函数,编写如下:

void TIM_SetTIM14Compare1(u32 compare)
{
TIM14->CCR1=compare;
}

++++++++++++++++++++++++++++++++++++++++++
定时器如果是为了产生事件,那么就需要配合中断系统使用,将事件驱动的执行代码放在callback中处理。
定时器如果是为了生成PWM,那么不需要产生中断事件,这时,它就是一个自动工作的外设。

版权声明:本文为CSDN博主「Huskar_Liu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42418557/article/details/121971202

生成海报
点赞 0

Huskar_Liu

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

74HC138译码器的原理和使用

前言 译码器就是将每个输入的二进制代码译成对应的输出高低电平信号,和编码器互为逆过程。 百度百科 74HC138是一款高速CMOS器件,74HC138引脚兼容低功耗肖特基TTL(LSTTL&#xf

ESP32-GY_30光照强度传感器

GY_30光照强度传感器介绍 GY-30光强传感器特点及使用介绍 一、连接引脚 GY_30光照强度传感器使用I2C传输数据 。 5根引脚,名称与功能如下; vcc 为外接供电电源输入端 GND 地线 SCL I2C通信模式时钟