预分频器相当于一个计数器,2分频就是接收2个脉冲传递一个脉冲,3分频就是接收3个脉冲传递一个脉冲,最高65535分频,那么总计时间能达到65535*65535*1/72MHZ 约59秒,没有分频器只能计数最高0.09秒
PWM配置步骤
1.配置定时器基础工作参数 HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)
2.定时器PWM输出Msp初始化 HAL_TIM_PWM_MspInit()
3.配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()
4.使能输出并启动计数器 HAL_TIM_PWM_Start()
5.修改比较值控制占空比 __HAL_TIM_SET_COMPARE()
解释步骤1中TIM_HandleTypeDef
typedef struct
{
TIM_TypeDef *Instance; /* 外设寄存器基地址 */
TIM_Base_InitTypeDef Init; /* 定时器初始化结构体*/
}TIM_HandleTypeDef;
再解释其中Init
typedef struct
{
uint32_t Prescaler; /* 预分频系数 */
uint32_t CounterMode; /* 计数模式 */
uint32_t Period; /* 自动重载值 ARR */
uint32_t ClockDivision; /* 时钟分频因子 */
uint32_t RepetitionCounter; /* 重复计数器 */
uint32_t AutoReloadPreload; /* 自动重载预装载使能 */
} TIM_Base_InitTypeDef;
解释步骤3中
HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim,
TIM_OC_InitTypeDef *sConfig, uint32_t Channel)的 TIM_OC_InitTypeDef 结构体
typedef struct
{
uint32_t OCMode; /* 输出比较模式选择,寄存器的时候说过了,共 8 种模式 */
uint32_t Pulse; /* 设置比较值 */
uint32_t OCPolarity; /* 设置输出比较极性 */
uint32_t OCNPolarity; /* 设置互补输出比较极性 */
uint32_t OCFastMode; /* 使能或失能输出比较快速模式 */
uint32_t OCIdleState; /* 选择空闲状态下的非工作状态(OC1 输出) */
uint32_t OCNIdleState; /* 设置空闲状态下的非工作状态(OC1N 输出) */
} TIM_OC_InitTypeDef
PWM控制呼吸灯实验
gtim代码
//gtim.c
#include "./BSP/TIMER/gtim.h"
TIM_HandleTypeDef g_timx_pwm_chy_handle;
// 通用定时器PWM输出初初始化函数
void gitm_timx_pwm_chy_init(uint16_t arr,uint16_t psc) //1.配置定时器基础工作参数
{
TIM_OC_InitTypeDef timx_oc_pwm_chy = {0x00}; //定时器输出句柄
g_timx_pwm_chy_handle.Instance = TIM14;
g_timx_pwm_chy_handle.Init.Prescaler = psc; //自动重装载值
g_timx_pwm_chy_handle.Init.Period = arr; //预分频系数
g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle); //初始化PWM
timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1; //选择PWM模式1
timx_oc_pwm_chy.Pulse = arr / 2; //设置占空比,百分之五十
timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW; //设置输出极性为低
HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle,&timx_oc_pwm_chy,TIM_CHANNEL_1); //3.配置PWM模式/比较值
HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle,TIM_CHANNEL_1); //4.使能输出计数器
}
//定时器输出PWM MSP初始化函数
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) //配置GPIO
{
if (htim->Instance == TIM14)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOF_CLK_ENABLE(); /* 开启通道y的CPIO时钟 */
__HAL_RCC_TIM14_CLK_ENABLE(); /* 使能定时器时钟 */
gpio_init_struct.Pin = GPIO_PIN_9; /* 通道y的CPIO口 */
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 复用推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
gpio_init_struct.Alternate = GPIO_AF9_TIM14; /* IO复用设置 */
HAL_GPIO_Init(GPIOF, &gpio_init_struct);
}
}
//gtim.h
#ifndef __GTIM_H
#define __GTIM_H
#include "./SYSTEM/sys/sys.h"
void gitm_timx_pwm_chy_init(uint16_t arr,uint16_t psc);
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim);
#endif
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/gtim.h"
extern TIM_HandleTypeDef g_timx_pwm_chy_handle; //引入结构体
int main(void)
{
uint16_t ledrpwmval = 0;
uint8_t dir = 1;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
usart_init(115200); /* 串口初始化为115200 */
led_init(); /* 初始化LED */
gitm_timx_pwm_chy_init(500 - 1, 84 - 1); /* 84 000 000 / 84 = 1 000 000 1Mhz的计数频率,2Khz的PWM */
while (1)
{
delay_ms(10);
if (dir)ledrpwmval++; /* dir==1 ledrpwmval递增 */
else ledrpwmval--; /* dir==0 ledrpwmval递减 */
if (ledrpwmval > 100)dir = 0; /* ledrpwmval到达300后,方向为递减 */
if (ledrpwmval == 0)dir = 1; /* ledrpwmval递减到0后,方向改为递增 */
/* 修改比较值控制占空比 */
__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_1, ledrpwmval);
}
}