单片机输出pwm波在项目中是恨常用的一个功能,今天就总结一下用STM32F103C8T6单片机输出16路 pwm波。
5 Q7 o/ I H2 ?; G- c- `0 g
! C8 D/ x% C3 j- I使用keil5软件,用标准库函数来实现。
8 A& S. p2 C+ I7 f' R
. g- p. z1 E- Q6 h I首先看定时器初始化. q, l& T( U8 B& t) R
- void TIM1_PWM_Init(u16 arr, u16 psc)
, d6 d6 q* h+ ~ - {
( z6 L, y! p, d! j! M4 h: v8 X - GPIO_InitTypeDef GPIO_InitStructure;
* F. F C" X5 _5 t - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
* p9 a$ Z2 E2 B5 H; {3 Y, D - TIM_OCInitTypeDef TIM_OCInitSturcture;2 d" t; k" s. Y0 s. o( b$ c
/ R( a) {' [& h& O+ {- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
- x! h3 C5 H, L7 B& j - //初始化IO口
# |8 e; ^6 U0 t1 [5 D - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
. s0 E, F2 I6 p& ?; q7 z% f - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; r: ?7 O1 C ]) K0 x% d
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& ~9 N$ i3 U4 @
- GPIO_Init(GPIOA, &GPIO_InitStructure);
8 x8 q6 {# u( A6 M, b% R - ; @! ~0 H, Q. H7 c/ f
- //设置 TIM ARR PSC: R6 H- X* F9 r0 i, i! g, e, ~! h
- TIM_TimeBaseInitStructure.TIM_Period = arr;
/ _9 E. c: P6 |9 k) ~- f9 v - TIM_TimeBaseInitStructure.TIM_Prescaler = psc;% s$ ?- }6 ]1 x* @7 j" U
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;# f7 M3 R$ g# m1 M% w Z' S. V
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式4 _( R+ W6 w7 J3 _* ]
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;( `+ \+ v( ~/ N) i: k7 q
- TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);5 E) f; [: c; k. m2 v2 s/ ~! G( U, r
- ! F) J* d, _' ]: M6 y
- //TIM1_CH1 PWM1 模式( I2 d4 ^4 g3 Y2 ^- x3 c' b
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;; r& c* S+ S9 P" `, n R
- TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
$ }( e! U% Q7 `9 w3 z+ U/ k! o+ \: N Y - TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; //输出高电平有效
' H0 R7 {: T% D3 k: l7 D - TIM_OC1Init(TIM1, &TIM_OCInitSturcture);1 f& K/ I5 V) w* h
- " G& z5 \% C! H1 q
- //TIM1_CH2 PWM1 模式
- J$ l( W' a! U5 o! f5 o. E - TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;) R& g: F6 O ~/ I% q& h) f" ~
- TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;- ^, u$ l5 Z0 J
- TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; & h" o% k# N4 K/ Y
- TIM_OC2Init(TIM1, &TIM_OCInitSturcture);
1 Q- m \1 |5 h! L2 Q( L ? - + p" V! |8 \! N D
- % U0 U6 `6 j3 a* o* R
- //TIM1_CH3 PWM2 模式
1 V& ]% ~ B3 b. V) d( g - TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;9 }$ U0 ~! Z# x) {- Q8 @4 z; u7 P
- TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
' R& D# u' q# X9 \ - TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; 9 ]7 y7 W, F9 q8 `$ @ i; r
- TIM_OC3Init(TIM1, &TIM_OCInitSturcture);
3 K B8 ]$ C* l' ?" M9 f
# p8 e7 i9 A3 J% \4 ^- //TIM1_CH4 PWM2 模式* q& J/ Y/ U1 `/ I l. C
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
9 M7 D& B+ Q! [( x" V: X( B+ n7 P- ` - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
: z% x v- U8 o8 J. p - TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;
( h- g4 j; ~+ c | - TIM_OC4Init(TIM1, &TIM_OCInitSturcture);
- E# D( b; x7 Y8 P9 L- t' k
5 ]0 W" {/ Z3 |0 X" a- [7 [3 m, c( k- ) E* d7 k; l6 P0 y0 _3 N7 [: V4 v
- TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH1 使能预装载寄存器
! O% y: e6 B4 X- ~; Y& m$ V- H' P - TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH2 使能预装载寄存器
0 c9 _& \, R- I - TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH3 使能预装载寄存器* b* R# q$ s7 G
- TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH4 使能预装载寄存器
) ?3 M$ l, j* I! F+ h
. r8 |0 Z' D$ S+ i: w- $ l) W, u7 t$ K: x" V7 u; I
- TIM_Cmd(TIM1, ENABLE); //使能计数器
: N; u7 u& {! |4 G+ I7 g - TIM_CtrlPWMOutputs(TIM1, ENABLE); //主输出使能: D* G5 }5 N, `7 f6 ^) ]
- }
复制代码
( c6 d: Z& n- b1 y' E; ^6 ~4 i初始化定时1的4个通道,对应IO口为 PA8,PA9,PA10,PA11,将这4个口都设置为PWM输出口。入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
~! n+ `1 h. M
/ e9 c1 r4 S6 ?3 u, ^$ e% x下来初始化定时器2
# }8 g+ f* @9 V+ y/ i/ f8 e. u! t3 o
- l1 r# N' {5 U: E8 ^- void TIM2_PWM_Init(u16 arr, u16 psc)' ^) q. m! m0 i# f
- {
* U: f$ _+ D( @( ~0 z' J4 H, e; A - GPIO_InitTypeDef GPIO_InitStructure;5 l) P; v7 J5 u5 F. I# E8 q3 t
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;4 n! l+ n' s( \6 H
- TIM_OCInitTypeDef TIM_OCInitStructure;
, M P. x# o* l7 s
! A/ v) N$ w0 G; d5 P6 U+ D- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器2时钟
2 n$ G9 A: u: d& J& |' X$ l - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO时钟( X0 _1 V% \0 r
. I" F* J3 x# v+ |- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
+ f4 W% ~% S+ Z8 u* {; C - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
) _8 R2 R/ P8 A* U# ]6 @" w - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;" n, C/ N6 ]: m F
- GPIO_Init(GPIOA, &GPIO_InitStructure);0 V/ h7 u& O m' ]. W
. f3 C) Z3 k- W. I- //初始化TIM28 Y- f! ~9 g& D* c
- TIM_TimeBaseInitStructure.TIM_Period = arr;
6 e' g" F, O6 t: B) V, x - TIM_TimeBaseInitStructure.TIM_Prescaler = psc;5 g6 P9 h' P3 B/ I; ]# J% U! k, C I$ I
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;, K/ k! ?$ [) L0 U
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;* k" G I r, `6 `
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
; I! L: H9 z. U7 j. j1 U
0 ?$ z' \& X+ d6 O6 {8 L4 D7 ?- //初始化TIM2_CH1 PWM 模式
2 s2 I. z0 z4 r- s9 C" c - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;) @3 d& M4 G r: J$ }
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
5 O) _/ s$ T' N2 i0 P - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;" [* R7 d B2 Y ]& g1 h4 c
- TIM_OC1Init(TIM2, &TIM_OCInitStructure); 1 e% `3 t. l1 @! `
- 0 U% Q6 j# G) j6 q: l* ~
- //初始化TIM2_CH2 PWM 模式
& K" m; y% ^& [8 y/ u5 N$ @ - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;2 B5 c1 I7 ?( d
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
: }: ?% {" B( w" t( r0 i - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
1 O1 n5 P& T# S% {7 F$ J% }- k& u2 B, { - TIM_OC2Init(TIM2, &TIM_OCInitStructure);
) `( a7 h+ o+ A - 6 I3 c2 B+ j* W: E! }: z' Q
- //初始化TIM2_CH3 PWM 模式! F* Y: r8 {9 c! z( C
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;' U! T# P' L+ Q* ^/ G! r
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;: T) S1 d8 o; q) {2 Z. o
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
, u5 n0 `" B' Y9 h4 B - TIM_OC3Init(TIM2, &TIM_OCInitStructure);1 ]0 t& I7 \0 u& b" C$ b
- - K) ~' s1 W2 J% Q
- //初始化TIM2_CH4 PWM 模式
5 }* r" s; c9 |- I+ U% H) d# j - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;! l0 N1 g4 }. q% v* s
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;# E+ [: a) U4 X- d3 _5 j6 ^* n
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;! r9 w% z/ H' o8 @# t: G
- TIM_OC4Init(TIM2, &TIM_OCInitStructure);
- Q2 Y. q. x, F5 v- _1 ~
P. g* h' G. J O$ g4 R- //使能TIM2在CCR上的预装载寄存器
/ C. c& T' G2 B; V' s - TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);1 J" W% n! Z* J9 Z) |
- TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
w& A. @7 F' L, d3 \ - TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);# f# y1 q% J0 @& o% o
- TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
* q% B8 I" O8 L5 K7 x: Y4 J+ E - . U' j& |' r: D0 \2 Y) Z
- //使能TIM20 [7 b, `' t# L7 D- h d
- TIM_Cmd(TIM2, ENABLE);% ^- \4 {' z: T: f/ W, m( |
- }
复制代码
% I* ]& Z8 L: S9 o( r这里要注意的是,定时器1是高级定时器,定时器2、3、4是通用定时器。只有高级定时器有重复计数寄存器,而通过定时器没有重复计数寄存器。定时器2初始化时,比定时器1少一行代码,这里要注意一下。
$ t7 j* a" o9 R
3 o# g. E# e; W# m( ^- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
复制代码 4 _9 ?, ]# |) M9 n6 t* `
重复计数寄存器主要作用如下:& u' b. K" J/ p5 |# W7 R" ]; i
- x: S. n. G$ A9 s" g: e; L
8 a% f: ^+ h2 D- P: P- {# h/ z/ O4 ^* A) b
其余设置方法和定时器1基本一样,定时器2的4个通道对应的IO口为PA0,PA1,PA2,PA3.将这四个口设置为PWM输出模式。
# B8 [0 J* T, j2 t' l4 I3 u# M8 w+ p; Y. |7 o
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
0 C6 K @! E) W3 t s3 B J- {1 ^ T0 j
下来设置定时器3
( C1 ^, K9 F4 |" s# |- W9 }9 Y& E% V" t& _
- void TIM3_PWM_Init(u16 arr, u16 psc)
, s) n7 U0 X& O$ P - {. Z* K& A& L: N1 t, |
- GPIO_InitTypeDef GPIO_InitStructure;
& J' e' E- x8 e* K" C- b3 d6 G - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;1 N$ i: L% @' D7 w0 M* x
- TIM_OCInitTypeDef TIM_OCInitStructure;
2 b% U4 j! e, i, U7 W6 Z. J$ I - % c) P( f8 u6 {" ?6 m* P
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟9 j r5 }* ^8 c: H, h9 a" A% Q
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO时钟& _' A+ g) E3 \0 j8 h
- , z. _9 u# {/ C% v1 b0 Z
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;9 ]( K" p; d7 w* e, g. ], d
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
: @; ?* m) V, M9 g* |4 z9 k - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;4 p/ S# z+ t4 l' S5 N, q* r6 S
- GPIO_Init(GPIOA, &GPIO_InitStructure);
) L+ _2 \, K; e* @1 ?' X# ?
S' H3 b, J$ S" R: {- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;; G9 h: f6 o. O# R$ q/ g
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- V/ U& ?7 G) |: U' Z - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;) T" S9 D- D5 b2 |- B% u7 m0 }
- GPIO_Init(GPIOB, &GPIO_InitStructure);
% T4 D" m) `) p7 j8 u
5 D* Z' z, _. p* I2 H& i- //初始化TIM36 w; k& o" H+ l7 {* \* z
- TIM_TimeBaseInitStructure.TIM_Period = arr;' j( U i% e: c+ L
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;/ F* p% z8 Y9 X
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
! E& B- \, ?' M4 q/ \ - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;/ `) G0 F! N3 Z6 i! w6 M
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);, s- v9 b" t* G& Q
9 {( e6 j: `7 G5 q Y: Q- //初始化TIM3_CH1 PWM 模式
+ }8 H" G. f3 P1 ]8 Q0 ? - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
8 V3 y. p! T9 r9 e5 \ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;4 Q' D1 g. b8 |
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
- N% E- D+ W3 r) l7 O: f5 ` - TIM_OC1Init(TIM3, &TIM_OCInitStructure);
' `) E4 k& d4 u' w
) Q( G* n0 C; S. ~2 W- //初始化TIM3_CH2 PWM 模式' S; V/ ~# X; }$ y8 J* S
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;& h3 e3 y/ j* H( ~0 P
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;6 s7 K2 Y- l1 [$ b' h+ o2 Y
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
5 g2 x0 w- d+ `6 _2 ~ - TIM_OC2Init(TIM3, &TIM_OCInitStructure);
" j( h9 X7 z" m4 L3 h/ t2 b9 p/ g
8 U# j9 B5 d% a% S- //初始化TIM3_CH3 PWM 模式
# f% Y1 a! T) J. o2 x( B* w: x+ Z - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; [% D2 d8 j+ W, k5 Q8 g
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;9 z% c2 m6 j7 D) W2 J( ], j% w
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;& p7 D+ C2 j: j( m, n8 s" ~$ r, A
- TIM_OC3Init(TIM3, &TIM_OCInitStructure);
5 h/ X/ G$ Y; S" s
1 o( I) W2 V; i+ m$ d- //初始化TIM3_CH4 PWM 模式9 z R. J% J, o( h4 H @) n0 u
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
4 {- v, O2 r" } y) f7 Y2 b) S$ Z) S - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
) J4 c( J: K. Q3 e! j - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
; ?! R% o1 Y# J5 v - TIM_OC4Init(TIM3, &TIM_OCInitStructure);
( Q1 T* v# N9 P: q' c) h) t - $ j1 Z1 O7 X: J: H
- //使能TIM3在CCR上的预装载寄存器) H2 q p5 ]& g) K/ `2 h# o! F
- TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);3 U {& A& c# U+ _$ H% [$ H' R
- TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
0 Z. B1 B! _# ], W - TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
$ n; p8 Q, F7 C - TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
% P2 K! T0 l6 X4 |9 C - //使能TIM3* L( h* x5 O8 H/ a3 F- y4 A
- TIM_Cmd(TIM3, ENABLE);( e- [, p; A/ C! {+ L: y3 r
- }
复制代码
2 ~' s L( u. [, O. B/ v设置方法和定时器2一样,定时器3的4个通道对应的IO口为PA6,PA7,PB0,PB1。将这四个口设置为PWM输出模式。' M. t, H: L2 e0 [
* R0 l0 r" |: w& a7 ?( R* G. h4 \
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
q( g7 z* r% k( X; V8 R9 j, k W" r$ `
最后设置定时器4 Y5 B0 t+ I! E
* Y6 N2 J1 P6 }$ s+ n! I
- ( o# s- t$ g! c! @: i
- void TIM4_PWM_Init(u16 arr, u16 psc)+ P$ _* s. ?9 E( x# I/ ?. n
- {
2 n8 p. K, l* Y Z' E - GPIO_InitTypeDef GPIO_InitStructure;
) x7 a: u" c8 ^3 K7 B - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;' w/ @, \0 L, U- _
- TIM_OCInitTypeDef TIM_OCInitStructure;
: M9 ^+ W! H2 t) U - + X& V; C$ n5 N
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟! Z2 l" P# Q& l
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO时钟
5 c( Z" [4 |& r8 d
4 m8 ~/ i! |! b9 W# D7 P- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;9 r" h* G1 @% T% f& x
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
( V) D {% e: j2 I' K: A4 C - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
$ E/ P, @% _7 F0 O; r# Q+ w+ P - GPIO_Init(GPIOB, &GPIO_InitStructure);2 s3 _# ~& r6 E+ |
: g5 T) ]0 V2 Y$ ^9 w# R- + r) X6 c9 ~& a# ~5 Q |
- //初始化TIM4+ x; h" N* B) w+ m
- TIM_TimeBaseInitStructure.TIM_Period = arr;
1 D$ M4 N- T' b# c4 x - TIM_TimeBaseInitStructure.TIM_Prescaler = psc;' i; b. Q0 j& I/ y$ u! q
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
6 B% I1 x$ Z/ S - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; V9 |4 R' z9 k, @3 Q0 O7 h
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);
$ m }4 L1 L2 D: H. D* f - & n% I" O4 B+ Z5 `
- //初始化TIM4_CH1 PWM 模式! c: I/ M' _& t! G
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
8 D; `5 y$ [; C. r - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;0 m) P4 I* n w- x- ~5 V$ E' ~) H8 o
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
8 v, F1 \8 B, W8 r4 n0 D4 }/ d - TIM_OC1Init(TIM4, &TIM_OCInitStructure);" S$ X B1 p. |: {5 v# h
-
1 ~4 Y& F6 m E; D" [- z$ t- C - 0 S5 N5 @4 r9 w" J
- //初始化TIM4_CH2 PWM 模式) z! [% u; P+ j
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
8 M) B( o- g4 O' q# L& d - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;. _/ n" ? J1 u
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
0 |7 i" F% a4 V) z, m9 p/ A - TIM_OC2Init(TIM4, &TIM_OCInitStructure);
" n' \$ R* @( S0 H$ d; F% q9 ?
6 b6 v! o) a& n, l! L$ d4 b4 I- //初始化TIM4_CH3 PWM 模式( A9 D0 }. ^) _
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;7 B1 ]5 h: u f+ _( x8 v
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;0 ?) J& ?4 I8 R4 g* [, M
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;3 k x( r" F6 c. J6 F2 E m
- TIM_OC3Init(TIM4, &TIM_OCInitStructure);
# P+ ?5 o: r6 [3 W1 K. c7 T
* m1 Y) v- u/ ]2 l2 k- //初始化TIM4_CH4 PWM 模式
( a- A% f$ d: J. e' r+ q# t1 v$ { - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
9 ]. O2 S. H/ u2 W# E) p - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
* T: O: T, }+ f. I5 k) X - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
3 d- Q0 Z& `7 _' r+ H% F3 C) J - TIM_OC4Init(TIM4, &TIM_OCInitStructure);7 L5 R& u% Y" K J
0 j5 g2 w" H' ?1 B- //使能TIM4在CCR上的预装载寄存器
! H6 b" b3 L1 U5 p* ]! I - TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
$ i3 |1 N5 o2 { e& A - TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
! {/ g: ~# _$ d# ? - TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
$ x5 i& V- u+ F% n) I1 f - TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
( l3 u6 g! n& y! [% \/ I* W
4 s& }9 ]. t' N+ d- //使能TIM4
+ h6 b. O! i9 V5 c - TIM_Cmd(TIM4, ENABLE);% n4 C* [2 ^ Q' C7 i7 ^! K/ e
- }
复制代码
% B, b; j7 u- V, ~, a4 w- n/ ~设置方法和定时器2一样,定时器4的4个通道对应的IO口为PB6,PB7,PB8,PB9。将这四个口设置为PWM输出模式。- c4 N) i/ ?4 \4 A+ {4 D
- r2 [" I* d3 i: N# ?
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
* T6 a' v% E( r8 j, Y9 I( `4 E7 X3 h" C- o
这样总共16路的PWM初始化就完成了,下来看主函数设置
* b" @8 a5 t4 w5 Q! ?$ v% {, t, L$ r0 T% O
- #include "sys.h"
6 x, h6 E( L, ]% j - #include "delay.h"
2 ~0 p! C" `- n a& d5 Y7 L - #include "usart.h"! ]) g* b) [! N8 x- H
- #include "pwm.h"* [) x" q' B# Q( c+ r+ ?) R
9 [) o8 x/ O5 |" C3 l2 l# {. `- int main(void)1 b9 {. }! F3 o" a- L: t( E3 y0 j0 h
- {
2 M' p2 _0 k; h" W& s - u16 led_pwm_val = 0;
, a3 `7 N2 n3 [2 o! V, e
7 V4 w6 }2 f, k8 c- delay_init(); //延时函数初始化! U: `) k, N1 w, [
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);' D$ G# e! D4 a- Z' S* Q$ b
5 t, K; ?& U& a3 `. C- //不分频。PWM频率=72000000/9000=8Khz
; f" V0 j! P( v- `- S! V" D - TIM1_PWM_Init(8999, 0);0 ]3 E+ p' p5 j
- TIM2_PWM_Init(8999, 0);
% B3 o* a$ C, u2 W - TIM3_PWM_Init(8999, 0);
3 O* X1 o; U) [) z$ Y) ~; _ - TIM4_PWM_Init(8999, 0);6 g* [7 m% H# _: ~5 o
- led_pwm_val = 899;
9 X( F! F, |6 ^# P- l5 @1 R - while(1)! S: u" @" z+ k0 e, N, ^) K/ I
- {" S7 r+ e: l4 x' O* I+ s+ `
- if(led_pwm_val < 8999)" z8 n6 y2 j0 @# F1 z, F
- led_pwm_val++;# O; ?: ]& `, w/ w2 \% V$ s! X! W
- else
' T) z% p! V. V( r0 n: n - led_pwm_val = 0;6 C0 I% d3 g! x% r# g
- $ F; a' C l; T3 p- q: T
- TIM_SetCompare1(TIM1, led_pwm_val); //TIM1_CH1 PA8! p' a$ P- M6 v+ T% ~
- TIM_SetCompare2(TIM1, led_pwm_val); //TIM1_CH2 PA9
2 h2 J, l4 f c# ~1 L7 h5 b$ F% ] - TIM_SetCompare3(TIM1, led_pwm_val); //TIM1_CH3 PA106 X6 K3 ~1 h T& \4 R# h* e" X- ^
- TIM_SetCompare4(TIM1, led_pwm_val); //TIM1_CH4 PA114 r9 ?, n7 |% H6 P7 O
7 k' `6 }8 ~: m# g. k3 `! o5 T- TIM_SetCompare1(TIM2, led_pwm_val); //TIM2_CH1 PA0
& m1 R: v3 b- } m& ~+ J1 J - TIM_SetCompare2(TIM2, led_pwm_val); //TIM2_CH2 PA10 e" X, N7 D# T: x
- TIM_SetCompare3(TIM2, led_pwm_val); //TIM2_CH3 PA2* F* [$ l& o3 j* W! g8 K6 @8 c
- TIM_SetCompare4(TIM2, led_pwm_val); //TIM2_CH4 PA30 P8 H# k2 [# N3 K9 |
- " ^9 t6 i& \/ D- M
- TIM_SetCompare1(TIM3, led_pwm_val); //TIM3_CH1 PA6! f( s0 p: s3 p4 z% T
- TIM_SetCompare2(TIM3, led_pwm_val); //TIM3_CH2 PA7
! o) s9 Z. b2 l4 u - TIM_SetCompare3(TIM3, led_pwm_val); //TIM3_CH3 PB0( E, U% m4 z- ]. t
- TIM_SetCompare4(TIM3, led_pwm_val); //TIM3_CH4 PB18 G T$ a' I! x) B, q- u/ {" V) p
- 4 s: d& p! }4 y) }; \/ x
- TIM_SetCompare1(TIM4, led_pwm_val); //TIM4_CH1 PB6' B4 j1 r9 \$ R- W5 u$ L
- TIM_SetCompare2(TIM4, led_pwm_val); //TIM4_CH2 PB7
9 l, v& c0 l% N3 J - TIM_SetCompare3(TIM4, led_pwm_val); //TIM4_CH3 PB8) D9 t) O2 W; S0 Q6 q
- TIM_SetCompare4(TIM4, led_pwm_val); //TIM4_CH4 PB9+ r' Z' t: Z- \* W
: m, z* [5 @ F `8 V- delay_ms(1);
G1 N; n- C3 q y1 A9 v - }
5 i1 Q" ^+ t8 B7 E - }
/ ?2 _4 e7 v s7 c5 {. T2 ^
复制代码 4 U7 j/ n# j. D. f* U# `, V+ {
初始化时设置4个定时器的频率为8K,在while循环中调节占空比从0---100%变化。程序编译后烧写到单片机中,通过示波器就能观察到PWM波形变化了。# Y/ S, ~: e8 K' v) J; n
/ a( k: R6 T$ b2 T/ _; B; G" H这里先用软件仿真看一下效果! i7 d, u S$ K
8 S; R& [# h$ ^6 v3 a2 }: [ $ l [) y2 L$ A
: F# I* `8 P" U* R z
7 x2 v9 T; R* N9 `7 [9 | |