STM32除TIM6和TIM7外都可以产生PWM输出。高级定时器TIM1和TIM8可以同时产生7路PWM,通用定时器可以产生4路PWM输出。 1.TIM1 CH1输出PWM配置步骤 ①开启TIM1时钟,配置PA8为复用输出 APB2外设时钟使能寄存器(RCC_APB2ENR)
APB1外设复位寄存器 (RCC_APB1RSTR)
置1开启。清0关闭。 Eg:RCC->APB2ENR|=1<<11; //使能TIM1时钟 Eg:GPIOA->CRH&=0XFFFFFFF0; //PA8清除之前的设置 GPIOA->CRH|=0X0000000B; //PA8复用功能输出
②设置TIM1的ARR和PSC 自动重装载寄存器(TIMx_ARR)
TIM1和TIM8预分频器(TIMx_PSC)
③设置TIM1_CH1的PWM模式及通道方向 TIM1和TIM8捕获/比较模式寄存器1(TIMx_CCMR1)
输出比较模式
Eg:TIM1->CCMR1|= 7<<4; //CH1 PWM2模式 TIM1->CCMR1|= 1<<3; //CH1预装载使能 CH1为输出,CC1S[1:0] 默认为00.
④使能TIM1的CH1输出,使能TIM1 设置TIM1_CCER来开启TIM1的通道1的输出。设置TIM1_CR1来开启TIM1的时钟。 TIM1和TIM8捕获/比较使能寄存器(TIMx_CCER)
Eg:TIM1->CCER|= 1<<3; //OC1输出使能 TIM1和TIM8控制寄存器1(TIMx_CR1)
ARPE:自动重装载预装载允许位 0:TIMx_ARR寄存器没有缓冲; 1:TIMx_ARR寄存器被装入缓冲器。 CEN:使能计数器 位0 0:禁止计数器; 1:使能计数器。 Eg:TIM1->CR1=0x0080; //ARPE使能 TIM1->CR1|=0X01; //使能定时器1
⑤设置MOE输出,使能PWM输出 普通定时器在完成以上设置后可以输出PWM,但高级定时器要使能刹车和死区寄存器。 TIM1和TIM8刹车和死区寄存器(TIMx_BDTR)
Eg:TIM1->BDTR|=1<<15; //MOE主输出使能
⑥修改TIM1_CCR1来控制占空比 Eg:#define PWM_VAL TIM1->CCR1 (可以直接设置) 2.TIMx复用功能重印象
 …… 3.高级定时器TIM1输出PWM应用 - //timer.c
- //TIM1_CH1 PWM输出初始化
- //arr:自动重装值
- //psc:时钟预分频数
- void TIM1_PWM_Init(u16 arr,u16 psc)
- {
- //此部分需手动修改IO口设置
- RCC->APB2ENR|=1<<11; //TIM1时钟使能
- GPIOA->CRH&=0XFFFFFFF0; //PA8清除之前的设置
- GPIOA->CRH|=0X0000000B; //复用功能输出
- TIM1->ARR=arr; //设定计数器自动重装值
- TIM1->PSC=psc; //预分频器设置
- TIM1->CCMR1|=7<<4; //CH1 PWM2模式
- TIM1->CCMR1|=1<<3; //CH1预装载使能
- TIM1->CCER|=1<<0; //OC1 输出使能
- TIM1->BDTR|=1<<15; //MOE 主输出使能
- TIM1->CR1=0x0080; //ARPE使能
- TIM1->CR1|=0x01; //使能定时器1
- }
复制代码- //timer.h
- #ifndef __TIMER_H
- #define __TIMER_H
- #include "sys.h"
- //通过改变TIM1->CCR1的值来改变占空比,从而控制LED0的亮度
- #define LED0_PWM_VAL TIM1->CCR1
- void TIM1_PWM_Init(u16 arr,u16 psc);
- #endif
复制代码
4.普通定时器TIM2输出2路PWM 应用 - //TIM2_CH3~4 PWM输出初始化
- //arr:自动重装值
- //psc:时钟预分频数
- void TIM2_PWM_Init(u16 arr,u16 psc)
- {
- //此部分需手动修改IO口设置
- RCC->APB1ENR|=1<<0; //TIM2时钟使能
- GPIOA->CRL&=0XFFFF00FF; //PA2-3清除之前的设置
- GPIOA->CRL|=0X0000BB00; //复用功能输出
- TIM2->ARR=arr; //设定计数器自动重装值
- TIM2->PSC=psc; //预分频器设置
- TIM2->CCMR2|=7<<4; //CH3 PWM2模式(输出)
- TIM2->CCMR2|=1<<3; //CH3预装载使能
- TIM2->CCER|=1<<8; //OC3 输出使能
- TIM2->CCMR2|=7<<12; //CH4 PWM2模式(输出)
- TIM2->CCMR2|=1<<11; //CH4预装载使能
- TIM2->CCER|=1<<12; //OC4 输出使能
- TIM2->CR1=0x0080; //ARPE使能
- TIM2->CR1|=0x01; //使能定时器2
- }
- //设定占空比 duty<899
- //设置多少就是多少低的
- void pwm_duty1(u16 duty)
- {
- TIM2->CCR3=duty;
- }
- void pwm_duty2(u16 duty)
- {
- TIM2->CCR4=duty;
- }
复制代码
5.普通定时器TIM3输出2路PWM 应用 - //timer.c
- //TIM3_CH1~2 PWM输出初始化
- //arr:自动重装值
- //psc:时钟预分频数
- void TIM3_PWM_Init(u16 arr,u16 psc)
- {
- //此部分需手动修改IO口设置
- RCC->APB1ENR|=1<<1; //TIM3时钟使能
- GPIOA->CRL&=0X00FFFFFF; //PA6-7清除之前的设置
- GPIOA->CRL|=0XBB000000; //复用功能输出
- TIM3->ARR=arr; //设定计数器自动重装值
- TIM3->PSC=psc; //预分频器设置
- TIM3->CCMR1|=7<<4; //CH1 PWM2模式(输出)
- TIM3->CCMR1|=1<<3; //CH1预装载使能
- TIM3->CCER|=1<<0; //OC1 输出使能
- TIM3->CCMR1|=7<<12; //CH2 PWM2模式(输出)
- TIM3->CCMR1|=1<<11; //CH2预装载使能
- TIM3->CCER|=1<<4; //OC2 输出使能
- TIM3->CR1=0x0080; //ARPE使能
- TIM3->CR1|=0x01; //使能定时器3
- }
- void pwm_duty3(u16 duty)
- {
- PWM3_PWM_VAL=duty;
- }
- void pwm_duty4(u16 duty)
- {
- PWM4_PWM_VAL=duty;
- }
- //timer.h
- #define PWM3_PWM_VAL TIM3->CCR1
- #define PWM4_PWM_VAL TIM3->CCR2
复制代码
切记在主函数前添加输出化函数! Eg:TIM2_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz
|