(1)配置步骤
1.配置RCC外设时钟 开启GPIO以及TIM外设
2.配置时基单元的时钟 包含时钟源选择配置初始化时基单元
3.配置输出比较单元 包含CCR的值 输出比较模式 极性选择 输出使能等
4.配置GPIO口 初始化为复用式推挽输出的配置
5.运行控制 启动计数器 输出PWM
(2)代码示例
案例1(TIM_2CH1(PA0)通道输出PWM驱动LED呼吸灯)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
//下面的是初始化结构体的函数,因为高级定时器跟普通定时器共用一个结构体
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0; //CCR
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
//呼吸灯逻辑函数
for (i = 0; i <= 100; i++){
TIM_SetCompare1(TIM2,i);
Delay_ms(10);
}
for (i = 0; i <= 100; i++){
TIM_SetCompare1(TIM2,100-i);
Delay_ms(10);
}
案例2(TIM_2CH2(PA1)通道输出PWM驱动舵机)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
//已知以上数据的来源是由于舵机需要信号脉冲宽度为周期20MS
//其次舵机分别在0.5ms 驱动舵机-90度
//舵机分别在0.5ms 驱动舵机-45度
//舵机分别在1.5ms 驱动舵机0度
//舵机分别在2ms 驱动舵机+45度
//舵机分别在2.5ms 驱动舵机+90度
//频率也就是1/0.02s=50HZ CK_PSC时钟频率 PSC预分配 ARR自动重装值
//公式已知 PWM频率; Freq=CK_PSC/(PSC+1)/(ARR+1)
// PWM占空比;Duty=CRR/(ARR+1)
// PWM分辨率;Reso=1/(ARR+1)
//则Freq=72MHZ/(PSC+1)/(ARR+1)=50HZ -> 72000 000HZ/(PSC+1)/(ARR+1)=50
//设PSC预分配为71 则原式72000 000/(71+1)/(ARR+1)=50 ARR=20000-1
//以上是根据自身自行设定的 最好可以多试试PSC*10的值 找到合适的
//所以算好了20MS周期的值 由于PSC固定 所以可以直接用来比值
//20MS / 20 000=0,5MS / x 20x=10 000 因为我们只需要比值X=500
//则舵机分别在0.5ms 驱动舵机-90度 CRR等于500
//舵机分别在0.5ms 驱动舵机-45度 CRR等于1000
//舵机分别在1.5ms 驱动舵机0度 CRR等于1500
//舵机分别在2ms 驱动舵机+45度 CRR等于2000
//舵机分别在2.5ms 驱动舵机+90度 CRR等于2500
TIM_OCInitTypeDef TIM_OCInitStructure;
//下面的是初始化结构体的函数,因为高级定时器跟普通定时器共用一个结构体
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0; //CCR
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
//以上为配置的某些环节 具体函数位于程序中 本文档没有直接提供
案例3(TIM_2CH3(PA2)通道输出PWM驱动直流电机)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
//维持在20HZ-20KHZ(上述为20000HZ)人耳听不到电机声音 这样好点
TIM_OCInitTypeDef TIM_OCInitStructure;
//下面的是初始化结构体的函数,因为高级定时器跟普通定时器共用一个结构体
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0; //CCR
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
//以上为配置的某些环节 具体函数位于程序中 本文档没有直接提供
(3)函数分析
函数1:void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)(stm32f10x_tim.h)
该函数不同的GPIO口对应的通道不同函数名也不同,对于TIM_OCInitTypeDef的使用; 通用定时器选择参数如下。
序号 | 名称 | 参数解释 | 示例 |
参数1 | TIM_OCMode | 设置输出比较的模式 | TIM_OCMode_PWM1 |
参数2 | TIM_OCPolarity | 设置输出比较的极性 | TIM_OCPolarity_High |
参数3 | TIM_OutputState | 设置输出的使能 | TIM_OutputState_Enable |
参数4 | TIM_Pulse | 设置CCR的参数 | 0 |
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
在引脚定义图里面去找对应的通道是多少,例如TIM_2CH1就是通道1,也可以去STM32CubeMX里面去看。
函数2:void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1) (stm32f10x_tim.h) 该函数不同的GPIO口对应的通道不同函数名也不同。
序号 | 名称 | 参数解释 | 示例 |
参数1 | TIM_TypeDef* TIMx | 定时器选择 | TIM2 |
参数2 | Compare1 | 通道选择 | 1、2、3、4 |
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3)
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4)
在引脚定义图里面去找对应的通道是多少,例如TIM_2CH1就是通道1,也可以去STM32CubeMX里面去看。