单片机输出pwm波在项目中是恨常用的一个功能,今天就总结一下用STM32F103C8T6单片机输出16路 pwm波。3 R1 |7 R7 a, @
* b6 ?6 ]. D& G5 u( K# h使用keil5软件,用标准库函数来实现。
" @6 h* u6 U8 m" n
& t" E$ x7 K9 u8 Y" I: V% ^, @首先看定时器初始化3 T, g: u! q. k( O
- void TIM1_PWM_Init(u16 arr, u16 psc)
3 P0 D5 _, m4 U& C6 S5 Y - {
; Y6 n9 r, I: b% S" s& I/ g - GPIO_InitTypeDef GPIO_InitStructure;
% `' x! X7 `1 c# w: G N - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
5 x. C/ ]. q* w" ` - TIM_OCInitTypeDef TIM_OCInitSturcture;
) M) w2 `% _6 D5 x% J, b) ~; b - . j/ x6 P& y. X7 x) c6 C
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
/ N. O& t; }5 \ - //初始化IO口
- |6 p, | Q% r: s - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
2 s$ s5 K9 @. J( ~ - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
5 I5 O9 n. E3 \ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;# \: V% c) _/ T* v1 M
- GPIO_Init(GPIOA, &GPIO_InitStructure);
/ G" U! }1 f* o/ E1 J& D
( G% B/ {6 ?: z0 _' e) {4 h: X2 \8 t1 j- //设置 TIM ARR PSC: w1 l) b9 m* L Z1 [! j# }" S
- TIM_TimeBaseInitStructure.TIM_Period = arr;$ D& T) J+ x* ?. D
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
5 D* p- U) _) ^ - TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
! {, y5 @) C+ c! ?' w - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式9 {! \: M( o+ z9 ?+ L" Z
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;5 c' `- K+ [2 a( ~. `
- TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);% i5 s; ~. k. _; u
- 8 i* _1 x0 p( b2 t* }6 N
- //TIM1_CH1 PWM1 模式' `$ V3 A5 R9 M: r: b0 t5 F# d* [2 T) c
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;" v# J. u% P- z
- TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
% w; G: r& a3 u - TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; //输出高电平有效
, n. T9 X' q+ @ - TIM_OC1Init(TIM1, &TIM_OCInitSturcture);! {$ e* i! b* t
4 ~( d2 N, W8 L B8 ?& v- //TIM1_CH2 PWM1 模式) N2 N- M G3 U2 m+ s/ V
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
2 A# P0 C) o- }: n/ \ - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;& M% m4 R4 S4 l# i
- TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; 8 y5 I3 R; X9 o p9 m
- TIM_OC2Init(TIM1, &TIM_OCInitSturcture);
' U5 Q# ~) q) y& I; k
4 |, n& {3 ?) h" [+ b! E
" E$ G0 `0 ]* e8 s! M7 ^. y- //TIM1_CH3 PWM2 模式
5 c* {# z5 i- ~ Z' b3 i% n& ? - TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
4 w' U7 c N+ y - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
% a( A0 }6 Q* m* F - TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; $ U/ H8 s9 C( v6 Z0 Q0 j, Q7 w
- TIM_OC3Init(TIM1, &TIM_OCInitSturcture);
$ x% x, G, S4 j: }4 L5 J; a' W
n% U/ w' V4 d- //TIM1_CH4 PWM2 模式7 u- }" P0 z2 ~/ j) _. q H7 N8 {
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
) s' S6 w& ?( d7 @% ^ - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
0 T! |0 D4 p. L9 r5 K+ g - TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;
" e; [& U0 n2 ?) E+ ~ - TIM_OC4Init(TIM1, &TIM_OCInitSturcture);0 T( o) |) [( S2 q( U
- 5 H/ x S) m F. `. c$ z4 k
9 I* V( T" n1 c+ m6 z# L) J: q, m* ^! j- TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH1 使能预装载寄存器
i s! e' _: C9 m% B - TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH2 使能预装载寄存器
% a2 `+ Z. e+ U3 ?" @ f g - TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH3 使能预装载寄存器
! y) I \7 y3 b" r - TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH4 使能预装载寄存器
5 y- U/ F1 b# B
! X$ p9 V$ Z6 v7 ^ D% p
, V& F) K' f. a% w3 H7 L- TIM_Cmd(TIM1, ENABLE); //使能计数器
- l% Z; v" q% U1 k0 h5 r0 n - TIM_CtrlPWMOutputs(TIM1, ENABLE); //主输出使能$ y; B2 ^- G5 \* ?( i
- }
复制代码
* J4 v# Z* P0 V$ {. n, j初始化定时1的4个通道,对应IO口为 PA8,PA9,PA10,PA11,将这4个口都设置为PWM输出口。入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
/ H: T# O c! ]/ c' g9 y$ ] H
8 x5 L4 k1 J. O6 O下来初始化定时器2
. V$ p6 \, w( _- `; E9 p) A* o% l# L) a0 O* y
- void TIM2_PWM_Init(u16 arr, u16 psc)
( y) {5 [; r% ~' y/ f - {
9 P0 s$ ]% n( ?6 j; O - GPIO_InitTypeDef GPIO_InitStructure; M( ^: T- Z" }9 T8 O0 q" H. ?
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;1 a; a& b$ \9 |. q
- TIM_OCInitTypeDef TIM_OCInitStructure;' b- ~( `: p4 t& M
& V; }8 E8 a7 s- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器2时钟2 p1 Q" ~$ V3 x7 q0 A `
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO时钟
! F1 u0 @+ c N" @3 l3 s - , r. m R% x4 R
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; o$ q8 g% _3 u
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;4 l8 m$ I7 Q& V" z9 w
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;0 ]- x. V) L- X
- GPIO_Init(GPIOA, &GPIO_InitStructure);' c! u& B" A. U5 Q" d+ M2 O8 W
' t) M) Z% _7 r5 ]1 {& k! n" R- //初始化TIM2) Q! B/ g7 S+ T& Z9 k: Q+ s
- TIM_TimeBaseInitStructure.TIM_Period = arr;0 G$ s( u/ Z/ {% j
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;: W }, y5 v! _2 f% _& {: y) S0 K, f
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
+ T0 a( j8 }0 P+ `9 K - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;4 N$ u" T1 p% l- j; v
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);- \, J4 f4 K. u" F' t% P
5 y0 j. D5 I* i# n4 A" M7 z* l- //初始化TIM2_CH1 PWM 模式
8 P0 I/ d; a" E4 L) m: k/ K - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;2 o8 O7 k& U/ B8 `6 a" ], S7 P
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
) r1 A4 N7 M5 V. {, s8 _ - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;7 |# c* Q4 {9 g$ {2 ^3 d; Q3 R
- TIM_OC1Init(TIM2, &TIM_OCInitStructure); 9 e0 ?+ ]$ a6 r! _- V' C
- / n# R0 x$ h' v; R
- //初始化TIM2_CH2 PWM 模式0 g/ C0 A6 K+ g/ F' u# o6 ~$ v; i
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;5 m) ^5 N0 W2 z, i; V4 j+ L
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;: N3 z( @6 E2 W/ R. W
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;: L* C3 f6 ]9 k
- TIM_OC2Init(TIM2, &TIM_OCInitStructure);+ T2 M3 c" t% @. {& V8 c, X
2 ]+ `1 \! f" `7 {+ C- //初始化TIM2_CH3 PWM 模式
# E( _+ E" ?1 D: m - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; |* T6 p9 r% `6 |) j; K* Q
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
6 N' Y$ t0 o9 j/ f L% C - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
. J$ |! m/ z( U \: M - TIM_OC3Init(TIM2, &TIM_OCInitStructure);" x) J5 M; M3 F3 Q6 r& H
, Q+ p$ _. C# }9 W$ F7 ]0 [- //初始化TIM2_CH4 PWM 模式
4 [# I' y# S6 N4 r - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
! q/ u6 e. g- e S; V; I - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
" R0 w' G. a4 _% L2 H s [ - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;, c% `8 v1 P {& @/ o
- TIM_OC4Init(TIM2, &TIM_OCInitStructure);# D4 i, H7 B4 ~, ?. K1 q
- @1 v/ N; {% t" C/ Q
- //使能TIM2在CCR上的预装载寄存器
! O+ P# Y' c+ E/ @7 [5 P) i5 e. m - TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);1 f. n+ }0 M' h- n: C% z
- TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
# a% o. p1 ^4 e4 g+ o' Q - TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);0 r( F2 R, m( J" u% y8 p: o E
- TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
2 v' I1 a5 L: |; }0 \! S& D: z5 Q
6 o8 Y: M. ^$ v- //使能TIM2
( B0 s, I8 N; F" ?# A- h - TIM_Cmd(TIM2, ENABLE);
6 w% C8 H5 d1 W+ U - }
复制代码 * p3 _$ @' a: Q$ C
这里要注意的是,定时器1是高级定时器,定时器2、3、4是通用定时器。只有高级定时器有重复计数寄存器,而通过定时器没有重复计数寄存器。定时器2初始化时,比定时器1少一行代码,这里要注意一下。; L9 p7 k. ^5 q) f! a5 u6 e
. u$ k; L2 l% a8 C# R9 z
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
复制代码 0 y' p6 v. o/ M, B
重复计数寄存器主要作用如下:
* F9 z4 j. u) \0 n2 t$ E2 o
) Q0 N" y) A: o! X
# R' s4 D5 |7 ]/ ]+ \* T1 t
# ]# f& o* \' v0 y8 l( p
其余设置方法和定时器1基本一样,定时器2的4个通道对应的IO口为PA0,PA1,PA2,PA3.将这四个口设置为PWM输出模式。
2 N' O) _$ L& }, z& C* a% A
/ b- t9 U7 s% Z! b入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
, _1 B8 i7 {7 _1 F2 w3 o; Y; d" ?8 P: `- u& H* P" w& O: ]
下来设置定时器3
L3 R% O$ @" m
; h$ L# N6 H: V+ n- void TIM3_PWM_Init(u16 arr, u16 psc)2 Y$ m; D [7 S. L6 \6 E
- {
" ]: f; R+ |+ }! A R3 ^ - GPIO_InitTypeDef GPIO_InitStructure;
+ O, j" F9 N& q( r6 Q5 e+ m" a$ ~ - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
P- L9 P- k' ~2 H: `/ P$ o- @' ^1 f - TIM_OCInitTypeDef TIM_OCInitStructure;5 O2 t% M9 @* [4 {3 ]+ w' G8 v
- ' u7 \6 `8 E/ `) K! O8 k# ]
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
6 l) @% d; X% ]# H! H - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO时钟. g$ _( v; y1 r9 `9 b z
- . C7 t% {# O1 t
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
/ k. x, q: @6 @( C - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
# x* D' y5 K1 b$ D. W - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
7 d' W: N5 I% W4 R" h2 p' \) ~ - GPIO_Init(GPIOA, &GPIO_InitStructure);/ T- s1 L% N9 P2 A: k* q- H; Q
- / C6 v* I. f: F3 l5 |6 F$ @0 w
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;# U# c- [+ K o9 j2 L
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
/ Q: x! A$ y* V( V( r" L; G - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;1 B# a! D# d, v9 D
- GPIO_Init(GPIOB, &GPIO_InitStructure);' M4 M4 Y+ [' O
- 1 X5 x0 h$ S( e/ Z7 j
- //初始化TIM3* |0 `6 L& j( B" k7 {$ g n$ O
- TIM_TimeBaseInitStructure.TIM_Period = arr;# c8 ~: g- Z5 m, ?3 e
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
6 G! B V7 Z6 d - TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
k$ o+ x/ \) ?8 q/ o3 P/ a; t* M - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; u4 e. L2 {3 Q
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);) t7 @# D2 W1 f: \* F
- 4 ]* ~9 S( |$ n1 p* Y! g- B0 z2 w1 r
- //初始化TIM3_CH1 PWM 模式
4 [' g: C2 Y# E, u( A - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
0 W& C3 Q" M3 u8 Z" p - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
4 V; J5 Q* p ^8 N' b# D - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;2 e) k' g! J2 h) ^
- TIM_OC1Init(TIM3, &TIM_OCInitStructure);
% ^, a# J0 c, ^1 n - 1 f3 H( i" X( {+ }. \2 r
- //初始化TIM3_CH2 PWM 模式! h. _. {+ Z8 e) K/ C* {( e
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
3 W+ V' U1 s% U% J: N - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
! N0 g1 v& _4 p# {5 h/ P - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
: c( o2 v( Z' {" Q6 b - TIM_OC2Init(TIM3, &TIM_OCInitStructure);# X! N, J5 f! q& W H& \6 A
- 5 b9 w+ V) i; {" a. ^. N( N
- //初始化TIM3_CH3 PWM 模式8 W' i$ [8 t: Z* |& {# q! ~5 X
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
) G) H Q# k! J4 }/ y; X; c - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
. m: q! B h+ s$ I% ?3 [ - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;" l: I6 i8 H) W& W+ x3 |
- TIM_OC3Init(TIM3, &TIM_OCInitStructure);
4 H5 h; Q2 r4 T9 w+ F1 _ - 5 J( }6 s. l) t9 A* |9 W
- //初始化TIM3_CH4 PWM 模式1 P+ K1 `2 E6 c
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;% t7 @5 R9 E. q3 C0 Y2 S8 y
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;+ ~! N3 n1 s# k, r" p
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
8 N' z$ A* a9 L) S6 f0 N: h - TIM_OC4Init(TIM3, &TIM_OCInitStructure);+ G9 D1 P5 M' [! {$ t
- 5 v! O% D5 L8 s# P7 r7 U
- //使能TIM3在CCR上的预装载寄存器/ r6 v4 ~+ F2 P( [, R- n3 [: W% {
- TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);' Q) ?+ j) r% `8 L
- TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
! k" e- ?# R& B- _0 a4 e - TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
" R: w: N/ a% n( Y - TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);( G g+ ]3 V0 O4 ^$ l! ^: E2 A
- //使能TIM39 q4 Q5 P! ?4 A/ [" ?
- TIM_Cmd(TIM3, ENABLE);7 F; u- [% r9 H/ h y
- }
复制代码
5 o% ~& d) }; m; V设置方法和定时器2一样,定时器3的4个通道对应的IO口为PA6,PA7,PB0,PB1。将这四个口设置为PWM输出模式。7 _8 t# |5 {* T+ Q O! g; f7 V
$ r& O8 P/ ~5 {
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
9 [- h( k: E: q, v# b
, m1 p# b& R7 f( Q/ B最后设置定时器4$ e% Z3 N& F) t
, S T- z: v/ v7 V
* _! P* {0 C" X% k- void TIM4_PWM_Init(u16 arr, u16 psc)
% P5 }6 W) H. F+ x( L7 B- _# \ - {2 ? ~( R9 l& C8 [. r- N8 W/ ^
- GPIO_InitTypeDef GPIO_InitStructure;0 E3 v0 M( ?3 a* d* k
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
1 A6 h- e b8 p5 b' i; M - TIM_OCInitTypeDef TIM_OCInitStructure;
) l5 S# o; x0 S: V5 z
: z7 N! c9 k, a4 w2 t9 y d- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟
2 n! P5 q2 C7 n( [ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO时钟6 F& J3 g2 X. ^
- 8 C3 G$ P8 I: H. Y3 H7 R
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;' b& ?5 L' ~* l7 t: u. p' b
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;- f' g) o6 D r) @+ j
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;" }1 X$ l# Q0 D% _5 B
- GPIO_Init(GPIOB, &GPIO_InitStructure);- x' k( N, C% ^( k+ f5 I S" \
- / `- {& |- o# a8 [" V
5 ~$ R! R' Y3 s* m) h6 D+ R' s- //初始化TIM4
4 [5 h$ u7 v+ H4 D# q - TIM_TimeBaseInitStructure.TIM_Period = arr;" b3 a1 f* }( w7 }! |& |
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
7 J+ K5 m' o; e0 ]4 m - TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
7 n, x7 Y2 w( j @: B3 z - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
! a# c9 K1 H9 [ - TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);
. U) L4 Y, w+ U! z: a* w
. M; }4 r# k$ Q! j6 G" x- //初始化TIM4_CH1 PWM 模式& X+ ]- y( \- J5 {
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
6 W2 ?% t: x0 D7 H( y - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
r; a8 n& Z4 ]' @1 K - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
3 h- P9 W0 u( z - TIM_OC1Init(TIM4, &TIM_OCInitStructure);
. v& }" t5 X0 Q -
* z7 h9 n( f5 n$ C. N9 w - 0 O4 x+ Z, W5 @" T" Z" j$ N" k
- //初始化TIM4_CH2 PWM 模式
, C7 B: l4 C5 G( `5 r, e - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
) {' `2 n* j% h/ ?+ U - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;8 z8 V2 F- d1 G$ |
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;+ h" R, U' H7 G, U: v0 q+ q4 ^- u
- TIM_OC2Init(TIM4, &TIM_OCInitStructure);
5 y' ]/ l: l, H3 V0 \) A - ' [+ f' ~6 e2 E9 V! |! [
- //初始化TIM4_CH3 PWM 模式
0 v/ x8 V: F& F9 i - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;5 {3 q9 I# W. q! o" H- c2 U
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;/ r5 R5 I. s$ \7 N4 s4 ^9 E
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
; C/ S6 Q4 M5 h4 V - TIM_OC3Init(TIM4, &TIM_OCInitStructure);/ g6 N/ [" ]7 A' P0 s
- I: \, m$ D0 A4 [, y
- //初始化TIM4_CH4 PWM 模式
, p( \: k9 ^+ V9 ^& }3 d - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;2 n) J- o: U J/ p# G
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;+ N* V$ e6 d1 c& ]9 a" [, ?. d
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
) e& B# Q c# F - TIM_OC4Init(TIM4, &TIM_OCInitStructure);
+ I- {& K& H& [; l
1 ^% z- Z, d. G0 n$ Q- //使能TIM4在CCR上的预装载寄存器
9 i: d* }4 c! Z - TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
: F- F/ o& @6 e5 A - TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);+ p8 z" `" J; N4 P- B7 g6 w
- TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
# c) z2 X# |4 Y+ l - TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);/ o$ P2 R9 B2 x+ \, b2 l
- " D- t' X0 w" }2 h* j$ A2 E0 g
- //使能TIM4
4 c# Z( K" E& T* b/ q' L+ D7 A - TIM_Cmd(TIM4, ENABLE);
* O/ V G, q. s$ z: h - }
复制代码 , X& h5 L- J q: t+ A
设置方法和定时器2一样,定时器4的4个通道对应的IO口为PB6,PB7,PB8,PB9。将这四个口设置为PWM输出模式。 |1 Y" F0 J, K+ j: I' r* h
3 ~2 h5 s7 R0 I9 l/ N* `$ c
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。& Y) P- N7 W) I& O
; b! `5 G* N8 h7 A0 o1 T2 Z这样总共16路的PWM初始化就完成了,下来看主函数设置
* s9 }1 q- W5 l, y& M* l L% ~( I/ V! R# `; s& B/ p
- #include "sys.h"
/ J8 f- d! O" P+ g5 i8 F - #include "delay.h"
4 q% D- j, u0 Z - #include "usart.h"
) y6 d, G4 _2 F, r; \ U6 E/ @6 T" s - #include "pwm.h"& a1 e6 E; ^' N4 C
/ L' ~3 v8 w+ a7 N" t8 T- int main(void)
; l6 I! F1 R4 M: T) z - {& K# ]0 K( R, J+ n1 C2 P* |5 f
- u16 led_pwm_val = 0;
% x' J9 `; Y5 t2 r' n) v$ b - * A+ e& E0 N4 t% q
- delay_init(); //延时函数初始化9 ~; M& d, R3 V! v) ~
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);0 o* j [: i$ W# T: H4 o
- * _- `" |% G" ^: n! J0 z
- //不分频。PWM频率=72000000/9000=8Khz7 A$ ^# w2 n' N/ u' y. J
- TIM1_PWM_Init(8999, 0);" X% z0 [0 s7 t; A2 W+ d+ C2 T
- TIM2_PWM_Init(8999, 0);
3 j) F( U7 u( D" ]$ G; _ - TIM3_PWM_Init(8999, 0);
/ ^; J) Q- T' ]) ^ - TIM4_PWM_Init(8999, 0);8 }' i* e; [. s4 g6 z& O" G
- led_pwm_val = 899;
, W8 F7 v/ H5 d& X% B) j - while(1)( E; f$ j1 v+ F0 j8 J
- {) p: U2 ?8 c1 s* ~$ m3 v
- if(led_pwm_val < 8999)
) U: t8 t% x! g7 S - led_pwm_val++;0 u" r6 A' N" F4 g Q8 R, n
- else2 P; K5 I: \& G
- led_pwm_val = 0;
( `- k9 b: O# f/ b$ H - $ Q+ b c7 u% K f
- TIM_SetCompare1(TIM1, led_pwm_val); //TIM1_CH1 PA8
4 m# r- _0 [( o( O - TIM_SetCompare2(TIM1, led_pwm_val); //TIM1_CH2 PA90 b0 Q7 L" e0 M; ?$ @7 C9 h: I7 V
- TIM_SetCompare3(TIM1, led_pwm_val); //TIM1_CH3 PA10
# |7 _1 L8 w, g/ T1 H9 h) L/ m2 ^3 Y - TIM_SetCompare4(TIM1, led_pwm_val); //TIM1_CH4 PA11
: Y% s4 K7 N _ - : s; H$ Y( @1 d; w
- TIM_SetCompare1(TIM2, led_pwm_val); //TIM2_CH1 PA0
, Y3 u$ k3 o' r! w% d0 f7 n8 ? - TIM_SetCompare2(TIM2, led_pwm_val); //TIM2_CH2 PA11 e9 K4 }, ?' f; G
- TIM_SetCompare3(TIM2, led_pwm_val); //TIM2_CH3 PA24 [3 I! `3 o' Z4 l9 {( r
- TIM_SetCompare4(TIM2, led_pwm_val); //TIM2_CH4 PA3. p5 Q8 {. {# A1 b% S' ]: P
- 4 X8 c1 F4 l9 o _, g G* d }: X
- TIM_SetCompare1(TIM3, led_pwm_val); //TIM3_CH1 PA6+ S+ [+ L4 g$ L6 E$ _. j& W
- TIM_SetCompare2(TIM3, led_pwm_val); //TIM3_CH2 PA7 O) Y- Q. c+ D8 O% u
- TIM_SetCompare3(TIM3, led_pwm_val); //TIM3_CH3 PB0
% Y: Z3 r" ~; Q( Q' j - TIM_SetCompare4(TIM3, led_pwm_val); //TIM3_CH4 PB1" H/ J H# s4 L% V$ o- K. Y
* t+ r1 M: {: S: n4 C+ |- TIM_SetCompare1(TIM4, led_pwm_val); //TIM4_CH1 PB6
. X) F2 l- D; u5 d - TIM_SetCompare2(TIM4, led_pwm_val); //TIM4_CH2 PB7 q @+ n% g* K3 F) h/ c d
- TIM_SetCompare3(TIM4, led_pwm_val); //TIM4_CH3 PB8! D! w9 o: ^% _( j7 @& u2 [
- TIM_SetCompare4(TIM4, led_pwm_val); //TIM4_CH4 PB9
1 ^( {6 R5 B3 a* g9 x - 2 R9 d- N! e( {3 t+ j
- delay_ms(1);* O: h h) g/ }- b6 y8 a
- }
1 A2 z+ Q* S7 G. H$ S - }0 `: P4 ~6 }0 H7 _: p K# w3 p
复制代码 9 S$ p6 ?+ W- D$ T: Q
初始化时设置4个定时器的频率为8K,在while循环中调节占空比从0---100%变化。程序编译后烧写到单片机中,通过示波器就能观察到PWM波形变化了。% v0 g& M- d4 b( O
/ M, t2 c0 g% @ O这里先用软件仿真看一下效果
# `6 `; U3 q: {4 b1 V) P
' |6 F( ]) I x$ K) k. S. j: G
# a" F" W# [" ?8 V2 v( y$ z3 X) r! k
% D6 P$ i3 G- D6 Z2 R' H( R |