原创 STM32 学习笔记之通用定时器输出PWM信号

2013-6-26 20:20 1646 17 17 分类: 消费电子

PWM——Pulse Width Modulation(脉冲宽度调制)。STM32除了基本定时器TIM6和TIM7不能产生PWM,其他定时器都能产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出,通用定时器TIM2-TIM5每个都能同时产生4路PWM输出。

     使用通用定时器产生PWM,除了使用到DMA/中断使能寄存器(TIMx_DIER),预分频寄存器(TIMx_PSC),重装载寄存器(TIMx_ARR)还需要用到捕获/比较模式寄存器(TIMx_CCMR1/2),捕获/比较使能寄存器(TIMx_CCER),捕获/比较寄存器(TIMx_CCR1/2/3/4).

     捕获/比较模式寄存器(TIMx_CCMR1/2),一个16位寄存器,其中TIMx_CCMR1控制CH1和CH2,TIMx_CCMR2控制CH3和CH4。设置OCxM,三位可以配置7种模式,使用PWM模式,这三位必须置为110(PWM模式1)/111(PWM模式2),这两种模式区别在于输出电平的极性相反。

     捕获/比较使能寄存器(TIMx_CCER),改寄存器控制着各个输入输出通道的开关,一个16位寄存器。

    捕获/比较寄存器(TIMx_CCR1~4),16位寄存器,在输出模式下该寄存器的值与CNT的值比较,根据比较结果产生相应动作,利用这点,我们通过修改这个寄存器的值,就可以控制PWM的输出脉宽。

       所以,要实现PWM输出需要一下方法配置端口:

       1)开启TIMx时钟,配置相应端口为复用输出;

       2)设置TIMx的ARR和PSC。(设置ARR和PSC的值来控制输出PWM的周期);

       3)设置TIMx_CHx的PWM模式;

       4)使能TIMx的CHx输出,使能TIMx.。(设置TIMx_CCER1和TIMx_CR1来控制开关);

       5)修改TIMx_CCRx来控制占空比。

      分享一下我调试时的程序:

/*==================================================================
* Function : PWM_Init
* Description : Init  PWM
* Input Para : arr: autio reload value.   
*                     psc: time prescaler
* Output Para : void
* Return Value: void
* Author: penny
* Date: 2013/06/24
==================================================================*/
void PWM_Init (u16 arr, u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO 复用功能模块时钟使能
                                                                                 //用于TIM3的CH4输出的PWM通过该LED显示      
//设置PB.1为复用输出功能,输出TIM3_CH4的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_0;   //TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
 
TIM_TimeBaseStructure.TIM_Period = arr;     //设置在下一个更新事件装入活动的自动重装载寄存器周期的值  
TIM_TimeBaseStructure.TIM_Prescaler = psc;  //设置用来作为TIMx时钟频率除数的预分频值    不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);       //根据TIM_TimeBaseInitStruct 中指定的参数初始化TIMx的时间基数单位
 
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;     //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0;      //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    //输出极性:TIM输出比较级性高
TIM_OC3Init(TIM3, &TIM_OCInitStructure);     //根据TIM_OCInitStruct中指定的参数初始化外设TIM3
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);    //使能TIMx在CCR1上的预装载寄存器
 
// TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;     //选择定时器模式:TIM脉冲宽度调制模式2
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //比较输出使能
// TIM_OCInitStructure.TIM_Pulse = 0;      //设置待装入捕获比较寄存器的脉冲值
// TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;    //输出极性:TIM输出比较级性高
TIM_OC4Init(TIM3, &TIM_OCInitStructure);     //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);    //使能TIMx在CCR2上的预装载寄存器
 
TIM_ARRPreloadConfig(TIM3, ENABLE);      //使能TIMx在ARR上的预装载寄存器
 
TIM_Cmd(TIM3, ENABLE);   //使能TIMx外设
 
}

文章评论0条评论)

登录后参与讨论
我要评论
0
17
关闭 站长推荐上一条 /2 下一条