对于STM32定时器输出PWM波需要了解定时器的基本使用方法和pwm的基本原理。这里使用STM32定时器3输出PWM波。 h3 \9 k. _( G1 q% F9 Q: G1 F
) }) x: B+ Q/ t5 r# c$ _1.什么是PWM波
3 o$ e0 ]4 l9 T; h1.我们都知道单片机的引脚可以输出高低两种电平,高电平称之为1,而低电平称之为0;而所谓的PWM波指的是在一定周期内不同比例的高低电平,如下图所示,输出不同比例的方波,在一定时间内高电平的比例分别达到10%,50%,90%。
& j2 i/ F e/ o% i# l' ]$ I1 m2 I( h* m
, Z$ q% P8 L' z1 l7 _
9 I$ e& J) V" M- v& ~4 w" K% o* [2.PWM的作用,我们都知道对于一个发光二极管,在一定电压范围内,输入端的电压越高,二极管的亮度也就越大。我们可以用单片机控制二极管的亮灭,我们会发现单片机引脚只能输出两种电压,即1与0;但是我们想控制二极管亮度。这是我们可以用PWM波控制,通过输出不同比例的高低电平,等效于一定的电压值,此时,就可以对二极管亮度调节了。) l- s, c- b+ _- O$ c; F
9 @ t; C" q( }2.用定时器输出PWM- _ ]0 W4 f2 ]8 w5 ^& h4 {) [
1.如下通过STM32的定时器3编写的pwm输出程序代码。' u& W- k& F2 {: q+ m0 Z
9 F3 l" M# E! K9 q$ Z! o: M
- //TIM3 PWM部分初始化 4 K1 g4 y: [2 b
- //PWM输出初始化
0 n( X: A' K- v B$ i& Z- s; P - //arr:自动重装值
/ a) b) W8 q! B3 d! q& |* J5 B4 M - //psc:时钟预分频数1 C5 p( g2 I, u; @4 R5 J9 S! Y
- void TIM3_PWM_Init(u16 arr,u16 psc)* y, Z4 ?3 l& l4 X
- {
9 [9 P! @3 t: c. E - GPIO_InitTypeDef GPIO_InitStructure;
) L( P9 a+ j; g# N4 l - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
: m( {# u+ c) w( J$ Y! i7 C - TIM_OCInitTypeDef TIM_OCInitStructure;* {1 N, z4 ~7 z/ D" D5 d
-
( Q3 v7 Z+ g3 |9 J - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
/ Y* q2 O; A+ }$ f5 ?; s4 X/ _6 x% T - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟6 w. }2 ?" V0 w6 x. l3 N$ }) k& ]
- ' x/ G* r9 X, D
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6; //TIM_CH20 N- A1 G3 T5 m
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出6 t+ y+ l6 ]& y3 B; _3 h/ Q; E
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
$ o7 R6 x- B0 C2 ^ - GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO5 H( g; A' ^1 N' `, A
- C# W' D$ F% m# l' ~- //初始化TIM3
0 l# E- ]; v' Y/ z/ K* i7 _ - TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值% ^9 u5 R) o8 z) J* O7 h
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
2 y: h% D3 k- ~( c - TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
6 p2 N) I o' m/ y% Q& Q3 _ - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
( G" z1 U3 p( N w7 c2 G - TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位% F4 \* D$ ^- O2 w1 [. z" K
-
' y9 ?# n5 O. o* h% P - //初始化TIM3 Channel2 PWM模式
u2 @+ J! Q; @5 V! b4 l& k; h5 ]& x - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
$ M4 y* g1 ?4 ^6 U% _ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
% K, `" C' q0 A* ]8 v. V - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
% H! R: D# N( m! U/ ~+ T q -
( @, x" |" g) u8 Z3 H9 o# j - TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC14 E! B) u4 R' F6 U E1 y0 ?
- TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
8 y$ M @4 _- K* s. u; M - TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的预装载寄存器% W) X: R: {7 a8 Z7 m- M8 o
- TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器: A9 N- _4 {! f3 C
- j! M* a# ~, x
- TIM_Cmd(TIM3, ENABLE); //使能TIM3
5 f! L0 g4 ~5 X - }
复制代码 ( @: F9 a# D! E& [$ q
这里使用的是定时器的通道1与通道2,对应着A6,A7两个引脚。具体详细配置请看上述注释。
/ j V' x) a" y. S9 C2 ]2 [ \6 b0 Z; R9 x3 R. T: `
其中:
8 n( }- |6 h S3 H
; p L# M5 }) R5 s( t1.定时器中断一次的时间为Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk,tclk为时钟频率,一般为72000000,arr:自动重装值 psc:时钟预分频数( a" H$ t' ^4 `$ t1 _; r7 X* O
6 C9 G0 M* ^) I" _: n& V
+ S# y( L7 R& f% o
$ n% {/ n# {: e ^$ i, r6 u* l2.7 q" ?' p6 E; H- Y6 x
: D" K7 A9 i+ f- N7 t
1 ^* b/ h/ Y/ h2 R0 Y, j- p) `
2 [) c, w* y9 k 2.主程序中的相关配置0 X4 e# c8 _+ J' w% B
3 W4 X; f- R) U1 N4 H3 x
对于主程序先对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值。7 u( {5 E+ Q( [8 O j% {* x
————————————————
, P; D R% |% `版权声明:一条田园犬
8 j) Y, Q( `3 Q" y" s7 T7 n. K! k, C: G; V) H
|