目录
选择TIM5CH2
1、GPIO配置输出
2、定时器配置
3、调用函数使用
初次易错点:
使用pwm输出是首先要看,那个引脚使用可以使用pwm输出。
高级控制和通用定时器通道引脚分布:
高级定时器 | 通用定时器 | |||||
TIM1 | TIM8 | TIM2 | TIM5 | TIM3 | TIM4 | |
CH1 | PA8/PE9 | PC6 | PA0/PA15 | PA0 | PA6/PC6/PB4 | PB6/PD12 |
CH1N | PB13/PA7/PE8 | PA7 | ||||
CH2 | PA9/PE11 | PC7 | PA1/PB3 | PA1 | PA7/PC7/PB5 | PB7/PD13 |
CH2N | PB14/PB0/PE10 | PB0 | ||||
CH3 | PA10/PE13 | PC8 | PA2/PB10 | PA2 | PB0/PC8 | PB8/PD14 |
CH3N | PB15/PB1/PE12 | PB1 | ||||
CH4 | PA11/PE14 | PC9 | PA3/PB11 | PA3 | PB1/PC9 | PB9/PD15 |
ETR | PA12/PE7 | PA0 | PA0/PA15 | PD2 | PE0 | |
BKIN | PB12/PA6/PE15 | PA6 |
static void TIM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 输出比较通道1 GPIO 初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/************通用定时器TIM参数定义,只限TIM2、3、4、5************/
// 当使用不同的定时器的时候,对应的GPIO是不一样的,这点要注意
// 我们这里默认使用TIM5
#define GENERAL_TIM TIM5
#define GENERAL_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd
#define GENERAL_TIM_CLK RCC_APB1Periph_TIM5
// TIM5 输出比较通道2
#define GENERAL_TIM_CH2_GPIO_CLK RCC_APB2Periph_GPIOA
#define GENERAL_TIM_CH2_PORT GPIOA
#define GENERAL_TIM_CH2_PIN GPIO_Pin_1
////////////////////////////////////////
//5khz
#define GENERAL_TIM_Period (20-1) //计数个数ARR
#define GENERAL_TIM_Prescaler (720-1) //周期 分频数PSC
// 占空比配置
uint16_t CCR1_Val = 10;
static void TIM_Mode_Config(void)
{
// 开启定时器时钟,即内部时钟CK_INT=72M
GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE);
/*--------------------时基结构体初始化-------------------------*/
/*--------------------定时器基本配置-------------------------*/
// 配置周期,这里配置为XXK
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period;
// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler;
// 时钟分频因子 ,配置死区时间时需要用到
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,设置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,没用到不用管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);
/*--------------------输出比较结构体初始化-------------------*/
/*--------------------PWM输出配置-------------------*/
TIM_OCInitTypeDef TIM_OCInitStructure;
// 配置为PWM模式1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
// 输出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
// 输出通道电平极性配置
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
// 输出通道空闲电平极性配置
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
// 输出比较通道 2
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);
// 使能计数器
TIM_Cmd(GENERAL_TIM, ENABLE);
// 主输出使能,当使用的是通用定时器时,这句不需要
//TIM_CtrlPWMOutputs(GENERAL_TIM, ENABLE);
}
void PWM_Init(void)
{
TIM_GPIO_Config();
TIM_Mode_Config();
//外面使用这个控制函数控制占空比
//TIM_SetCompare2(GENERAL_TIM , 70);
}
void pwm_test(void)
{
GPIO_ResetBits(MOTOR1EN_GPIO_PORT, MOTOR1EN_GPIO_PIN);
TIM_SetCompare2(GENERAL_TIM , 5);
Delay_s(4);
GPIO_SetBits(MOTOR1EN_GPIO_PORT, MOTOR1EN_GPIO_PIN);
Delay_s(2);
GPIO_ResetBits(MOTOR1EN_GPIO_PORT, MOTOR1EN_GPIO_PIN);
TIM_SetCompare2(GENERAL_TIM , 15);
Delay_s(4);
GPIO_SetBits(MOTOR1EN_GPIO_PORT, MOTOR1EN_GPIO_PIN);
Delay_s(2);
}
1,没有注意到相应的输出比较通道。使用的是ch2,但是函数调用的却是ch1的
TIM_SetCompare1/TIM_SetCompare2/TIM_SetCompare3/TIM_SetCompare4
TIM_OC1Init/TIM_OC2Init/TIM_OC3Init/TIM_OC4Init
TIM_OC1PreloadConfig/TIM_OC2PreloadConfig/TIM_OC3PreloadConfig/TIM_OC4PreloadConfig
2、pwm更改占空比
#define GENERAL_TIM_Period (20-1) //计数个数ARR
// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
#define GENERAL_TIM_Prescaler (720-1) //周期 分频数PSC
// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
TIM_Period:定时器周期,实际就是设定自动重载寄存器 ARR 的值, ARR 为要装载到实际自动重载寄存器(即影子寄存器) 的值, 可设置范围为 0 至 65535。
TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可设置范围为 0 至 65535。
TIM_SetCompare1(TIMx,CCRx);设置pwm占空比