对于STM32定时器输出PWM波需要了解定时器的基本使用方法和pwm的基本原理。这里使用STM32定时器3输出PWM波。
' L8 n2 w/ a) R7 Q, H4 g) a
9 d. @+ \/ `5 E) T* T$ C- M1.什么是PWM波
- P7 B" Y1 n5 Y! A1.我们都知道单片机的引脚可以输出高低两种电平,高电平称之为1,而低电平称之为0;而所谓的PWM波指的是在一定周期内不同比例的高低电平,如下图所示,输出不同比例的方波,在一定时间内高电平的比例分别达到10%,50%,90%。; Y8 e V( z; q3 p
" H+ O, [* u0 V! P# v& W
! C2 U- v; z/ Y. s
b- p& I/ N( p& R' G0 k- X# P2.PWM的作用,我们都知道对于一个发光二极管,在一定电压范围内,输入端的电压越高,二极管的亮度也就越大。我们可以用单片机控制二极管的亮灭,我们会发现单片机引脚只能输出两种电压,即1与0;但是我们想控制二极管亮度。这是我们可以用PWM波控制,通过输出不同比例的高低电平,等效于一定的电压值,此时,就可以对二极管亮度调节了。/ d) t: k) i+ G+ r @0 T
/ Y2 h6 c% L5 O# p" y5 I+ }# P2.用定时器输出PWM
7 p" ^- Y/ u* b- K1.如下通过STM32的定时器3编写的pwm输出程序代码。
' M& g1 T, n; ]( p! ?5 x
6 w: q) Y% W/ E- //TIM3 PWM部分初始化 + m4 k8 U- Q! f: ^0 V I
- //PWM输出初始化& O, s# j1 Z' D3 r
- //arr:自动重装值
: ?$ d4 s* V" q }7 U - //psc:时钟预分频数
: n+ {7 s( C, C* C - void TIM3_PWM_Init(u16 arr,u16 psc)
& k- ?5 s- f! [8 e - {
. T1 T0 n, Y" l, E0 K2 I$ a - GPIO_InitTypeDef GPIO_InitStructure;
% y" ^8 G; Z# N& N3 m7 M - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;# f9 d: Q! ^# P3 G6 N7 Y
- TIM_OCInitTypeDef TIM_OCInitStructure;) ?2 \; W! j1 ^4 M* u, Y3 T
-
0 w' T( V7 a" a - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟& n7 E( E4 x& h' k. r
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
$ T: [: o/ _9 _- g4 a1 b -
( b/ V% G g9 w - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6; //TIM_CH2
% G! w+ m8 M9 P+ A+ Z - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出7 ~- {( m- h2 c8 ^5 Y. E
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/ G( G6 j; l, D+ C! S' m% f6 @$ c
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
% X) e6 ^# s. R) U, ]! I - ( y$ M" ~3 P1 ]* R. g4 k/ \: R! o! J
- //初始化TIM3
4 z# [1 q' j L" [ - TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值: n) t* s! m8 ]& X& z: b, v
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 8 A6 b: X5 A5 O' ?
- TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim! E. O0 S9 o5 c8 E+ c" a$ E
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式5 u8 S8 r% F- @ Q. }7 \: ?* [9 z
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位9 N! n( d* r5 Z; x( H
-
1 m. B7 U5 g7 X0 k3 o% o - //初始化TIM3 Channel2 PWM模式
" O7 }: p( U& B5 h' w" y, Q - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2" d5 ^; K1 W$ f% L, B/ X/ d) w; j
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 S' m4 [3 T$ g+ ~2 f' W+ J' k+ C
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高. _' X! b' v; v- W3 w
-
8 a. i6 P9 d* y2 Z. B% a - TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC1
@0 _5 ?& ?7 y+ m) V8 z- Q - TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
& W3 ~0 V8 i$ ]; s: A3 @6 u - TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的预装载寄存器
5 {0 x( ^0 I5 [& V, |, v9 t - TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
1 t. g R1 {0 h6 W( A - ) i j, k$ U% g) s5 h4 R. g P
- TIM_Cmd(TIM3, ENABLE); //使能TIM3 7 C b$ ?* H/ O9 D- `
- }
复制代码 0 S) M2 g. T& q8 I, T. l1 P
这里使用的是定时器的通道1与通道2,对应着A6,A7两个引脚。具体详细配置请看上述注释。3 `6 B! o! f+ B1 {2 C$ @
. V+ F. j, j) M& l& z: y. Z) ~其中:! l" N+ Y+ j) J* j
& U& [$ F( Q' o' Q6 \1.定时器中断一次的时间为Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk,tclk为时钟频率,一般为72000000,arr:自动重装值 psc:时钟预分频数2 f, P1 j) k. D8 R' H
) h( s$ |9 X( L% _$ M
8 k) C/ l0 l9 E9 f) J
* ~ |" w t" ?+ q! h! U2.
4 e* g5 Y# Z( Q! ]; Q
z8 c# B9 o8 B, j/ `
- A+ y, a2 |/ i; a7 L! _% T6 M5 n: O u8 P% K+ o: o
2.主程序中的相关配置$ R2 t l$ h" g* T% x0 h
- p9 [1 x: Q! J: \$ B& J! g8 N
对于主程序先对TIM3_PWM_Init(u16 arr,u16 psc)进行初始化,并配置好arr与psc,以确定周期频率。然后再调用 void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare2);与void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);即可配置PWM值。+ N k; @' ]: F) [
————————————————
0 n6 K' _" y0 e' M' ?$ w |6 [6 [版权声明:一条田园犬, J# ~+ w& p% c' A3 R: N5 s
4 t" V1 i0 Z1 r, p
|