热度 17
2013-6-26 20:20
1661 次阅读|
0 个评论
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外设 }