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时钟

配置I/O口: 参见stm32寄存器版学习笔记01 GPIO口的配置

  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应用

 1 //timer.c
 2 //TIM1_CH1 PWM输出初始化
 3 //arr:自动重装值
 4 //psc:时钟预分频数
 5 void TIM1_PWM_Init(u16 arr,u16 psc)
 6 {                              
 7     //此部分需手动修改IO口设置
 8     RCC->APB2ENR|=1<<11;     //TIM1时钟使能    
 9     GPIOA->CRH&=0XFFFFFFF0;    //PA8清除之前的设置
10     GPIOA->CRH|=0X0000000B;    //复用功能输出 
11     
12     TIM1->ARR=arr;            //设定计数器自动重装值 
13     TIM1->PSC=psc;            //预分频器设置
14   
15     TIM1->CCMR1|=7<<4;      //CH1 PWM2模式         
16     TIM1->CCMR1|=1<<3;         //CH1预装载使能     
17      TIM1->CCER|=1<<0;       //OC1 输出使能       
18     TIM1->BDTR|=1<<15;       //MOE 主输出使能       
19 
20     TIM1->CR1=0x0080;       //ARPE使能 
21     TIM1->CR1|=0x01;        //使能定时器1                                           
22 }  
1 //timer.h
2 #ifndef __TIMER_H
3 #define __TIMER_H
4 #include "sys.h" 
5 //通过改变TIM1->CCR1的值来改变占空比,从而控制LED0的亮度
6 #define LED0_PWM_VAL TIM1->CCR1     
7 
8 void TIM1_PWM_Init(u16 arr,u16 psc);
9 #endif

 

4.普通定时器TIM2输出2路PWM 应用

 1 //TIM2_CH3~4 PWM输出初始化
 2 //arr:自动重装值
 3 //psc:时钟预分频数
 4 void TIM2_PWM_Init(u16 arr,u16 psc)
 5 {                              
 6     //此部分需手动修改IO口设置
 7     RCC->APB1ENR|=1<<0;     //TIM2时钟使能    
 8     GPIOA->CRL&=0XFFFF00FF;    //PA2-3清除之前的设置
 9     GPIOA->CRL|=0X0000BB00;    //复用功能输出 
10     
11     TIM2->ARR=arr;            //设定计数器自动重装值 
12     TIM2->PSC=psc;            //预分频器设置
13   
14     
15     TIM2->CCMR2|=7<<4;      //CH3 PWM2模式(输出)
16     TIM2->CCMR2|=1<<3;         //CH3预装载使能
17     TIM2->CCER|=1<<8;       //OC3 输出使能
18     
19     TIM2->CCMR2|=7<<12;      //CH4 PWM2模式(输出)         
20     TIM2->CCMR2|=1<<11;     //CH4预装载使能    
21     TIM2->CCER|=1<<12;       //OC4 输出使能
22 
23     TIM2->CR1=0x0080;       //ARPE使能 
24     TIM2->CR1|=0x01;        //使能定时器2                                                       
25 }  
26 
27 
28 //设定占空比 duty<899
29 //设置多少就是多少低的
30 void pwm_duty1(u16 duty)
31 {
32     
33     TIM2->CCR3=duty;
34 }
35 
36 void pwm_duty2(u16 duty)
37 {                      
38     TIM2->CCR4=duty;
39 }

 

5.普通定时器TIM3输出2路PWM 应用

 1 //timer.c
 2 //TIM3_CH1~2 PWM输出初始化
 3 //arr:自动重装值
 4 //psc:时钟预分频数
 5 void TIM3_PWM_Init(u16 arr,u16 psc)
 6 {                              
 7     //此部分需手动修改IO口设置
 8     RCC->APB1ENR|=1<<1;     //TIM3时钟使能    
 9     GPIOA->CRL&=0X00FFFFFF;    //PA6-7清除之前的设置
10     GPIOA->CRL|=0XBB000000;    //复用功能输出 
11     
12     TIM3->ARR=arr;            //设定计数器自动重装值 
13     TIM3->PSC=psc;            //预分频器设置
14     
15     TIM3->CCMR1|=7<<4;      //CH1 PWM2模式(输出)
16     TIM3->CCMR1|=1<<3;         //CH1预装载使能
17     TIM3->CCER|=1<<0;       //OC1 输出使能
18     
19     TIM3->CCMR1|=7<<12;      //CH2 PWM2模式(输出)         
20     TIM3->CCMR1|=1<<11;     //CH2预装载使能    
21     TIM3->CCER|=1<<4;       //OC2 输出使能
22 
23     TIM3->CR1=0x0080;       //ARPE使能 
24     TIM3->CR1|=0x01;        //使能定时器3                                                       
25 } 
26 void pwm_duty3(u16 duty)
27 {
28     
29     PWM3_PWM_VAL=duty;
30 }
31 
32 void pwm_duty4(u16 duty)
33 {                      
34     PWM4_PWM_VAL=duty;
35 }
36 
37 //timer.h
38 #define PWM3_PWM_VAL TIM3->CCR1
39 #define PWM4_PWM_VAL TIM3->CCR2

 

切记在主函数前添加输出化函数!

Eg:TIM2_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz 

 

posted on 2016-07-01 00:06  kuotian  阅读(8391)  评论(2编辑  收藏  举报