单片机输出pwm波在项目中是恨常用的一个功能,今天就总结一下用STM32F103C8T6单片机输出16路 pwm波。* J" c) O( E# l5 K" }; d
" m; L1 ]2 p( { z1 Y2 W! l! \: y使用keil5软件,用标准库函数来实现。7 e% z$ Q. O+ ]
+ N8 M; w; g" n4 w
首先看定时器初始化' a9 ]3 q% w/ I) {+ L! W6 O2 S
- void TIM1_PWM_Init(u16 arr, u16 psc)
) }3 W! d( e$ u* f) Q - {5 h2 c$ x5 y5 w6 m* d7 |2 e: ^
- GPIO_InitTypeDef GPIO_InitStructure;
9 D; S1 \1 L& z3 g, D4 O - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;" h$ a, p+ F1 ~
- TIM_OCInitTypeDef TIM_OCInitSturcture;+ n+ n- ?" H# v) ?$ L
6 o4 q9 b5 F" ~. d9 T2 _8 x; [- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
& z6 a+ k( z% \: k - //初始化IO口
( l8 K8 m6 |9 Z1 N$ S% b - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;; W, i* Q. o$ c, P
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
0 M' C4 l9 p3 p& I. Z% l- [ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
; |8 W2 b8 m0 l7 v1 d) ? - GPIO_Init(GPIOA, &GPIO_InitStructure);
) L- d( ?- M( Q) i8 C1 q
% ~6 ]& G2 o9 l2 S; a- //设置 TIM ARR PSC
% L m `. ]) ]9 T+ c, T8 ^- l - TIM_TimeBaseInitStructure.TIM_Period = arr;
* Y& {/ j. Z% n6 | - TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
O u Y. a. W8 d. y- R Z - TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;# \( @$ f1 o; l9 [; A e6 D
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
3 n" I$ ]% _+ X' e$ M$ j" D - TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
( @6 v; f) X: j7 B7 [" { - TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
7 d) ^ q( z n0 A( z* {9 S4 T
. y0 c/ o2 [3 y" x1 }6 P- //TIM1_CH1 PWM1 模式! G& [. U- Y9 U8 w) H) t# l: Z0 R
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
. o0 A8 E) y6 v" G& W2 P) n/ v - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;; U O2 J0 q) d+ c* L( H6 `# V; t
- TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; //输出高电平有效) b. e4 x3 W/ R! ~) ~3 D9 _
- TIM_OC1Init(TIM1, &TIM_OCInitSturcture);
& i; B) R" U3 U. f1 Y0 M5 c
$ N( t2 v |4 X, B$ K6 d- //TIM1_CH2 PWM1 模式
0 n% Q; G8 r$ O% K/ Y S - TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
* z7 ?' L/ n( w3 i. } c" c - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;2 \: ^2 Q4 v S( K6 \6 K% b: C
- TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;
' W+ Q: u. o, h" Z9 q! }1 v/ U - TIM_OC2Init(TIM1, &TIM_OCInitSturcture);( R( i( ~; f2 T1 @" f2 k, _# f5 o
3 T7 x% O, b8 C" ~+ L5 i
8 k/ C( Q6 [. |5 q" V; t' L- //TIM1_CH3 PWM2 模式- x( J) A* F7 d2 Z! l* s
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
8 a" t9 f0 Z6 V: E! H9 G+ T - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;- g H6 x$ J" ?# t& d, W( v. F
- TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; 7 n6 x& U2 ^( Z3 L! d( r1 M" D
- TIM_OC3Init(TIM1, &TIM_OCInitSturcture);
% l3 E7 \' Y" A4 O$ x - 4 _% a% ?/ e! V; y: h
- //TIM1_CH4 PWM2 模式+ W, I! N0 w! J9 p5 c0 x8 l
- TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
9 S2 K( H9 _4 @& o3 h2 H% W - TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;( E+ d5 Y% d6 [' S" Y3 {8 }% `
- TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High; $ _% u! _" n6 Q+ v2 _
- TIM_OC4Init(TIM1, &TIM_OCInitSturcture);
: g! f) y0 ]: S& F# L5 Q7 a j9 q
' t* e! g5 p) P! Z) Z! k
8 { [1 X( I/ T4 d4 i- TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH1 使能预装载寄存器
& V" f9 O) J* R" g9 u - TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH2 使能预装载寄存器' Y6 r/ Y3 S: c1 W5 X8 _% F* d
- TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH3 使能预装载寄存器
8 d/ P4 U# c4 y" Y! H8 G - TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //TIM1_CH4 使能预装载寄存器7 V, E# {' R8 M; g% y% [+ v/ ?% X/ P
' N8 S0 j" g& P: F
$ r9 L: ]$ z* n% B7 P4 C- TIM_Cmd(TIM1, ENABLE); //使能计数器, u0 x z( ~+ H9 H5 C( ^
- TIM_CtrlPWMOutputs(TIM1, ENABLE); //主输出使能
" v( _. h( ]& ?- X! r7 o$ l4 w' K& S - }
复制代码
2 s4 f3 c$ z, `4 T5 h$ E初始化定时1的4个通道,对应IO口为 PA8,PA9,PA10,PA11,将这4个口都设置为PWM输出口。入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。0 \ k. p0 E( c3 g( e6 f$ E
9 o c/ s6 U, B) X1 r
下来初始化定时器2
( `9 Z' v. `$ o# O) r+ _5 d, y" C. S
- void TIM2_PWM_Init(u16 arr, u16 psc)
( _ ?/ O: Z7 I( c, X8 o { - {
' G0 D' M0 m8 |' | - GPIO_InitTypeDef GPIO_InitStructure; X- P( y: M, P6 ~% ] d7 _$ N2 }
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;9 z. ^+ a6 Y( B4 D! y+ A
- TIM_OCInitTypeDef TIM_OCInitStructure;
5 t/ z+ c( a- e- r
/ B+ V* I: Z! i8 {& @) F- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器2时钟
% [4 t: @( p' r0 p0 e - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO时钟
6 i/ a* X, z3 T" E - ( }* S* _4 h Q; _& h4 V5 D
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
4 @7 ^/ c, P4 [& i - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
) ]5 G0 M8 p- i& \* B5 Q4 B - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;' D. S# v+ U& `+ M, T
- GPIO_Init(GPIOA, &GPIO_InitStructure);
& C8 u3 D6 B9 M+ F7 D+ l+ z7 B - $ L8 u/ `6 d& w1 j
- //初始化TIM2" S7 _# m; x. G/ O
- TIM_TimeBaseInitStructure.TIM_Period = arr;$ d2 W- H. [1 N) c4 [
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
^3 F' Q! L4 a" } - TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
2 m1 ~6 E& I: W ^9 R3 Z - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;$ M0 ]. h j& I: [" p
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
+ e: M" a7 h, S) [2 C# k) T
, g) y8 \, Q }( q3 u0 e9 ]+ B- //初始化TIM2_CH1 PWM 模式
" Q4 w+ p# n$ W. J( i! l" j- f - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
) a b1 f2 c5 F% j8 Q - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
6 H! e! N6 ]0 w0 ]1 W' t* Y - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
; u! S, b7 F$ X - TIM_OC1Init(TIM2, &TIM_OCInitStructure);
. d9 W+ q6 h$ @' S+ n3 U3 P - # r5 Y& F: \& u/ T e5 X% Z
- //初始化TIM2_CH2 PWM 模式. m. J/ D+ C4 U2 r+ P0 Q* E
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;7 R) Y2 u# S" ^4 y5 b
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
0 g! C/ p/ O' _& q4 w1 T* w - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;0 f) |: w4 G, I W6 U! S" f
- TIM_OC2Init(TIM2, &TIM_OCInitStructure);3 |# P8 ^' s( v% v: i0 a& @2 u% O5 k
4 X/ [7 n6 E1 u; a/ Z7 V3 Z5 m8 {3 `- //初始化TIM2_CH3 PWM 模式
" U1 ]/ J+ k' ~- Z) y - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
5 s4 L; ^" ]) U+ {" P - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
2 N2 c0 Q0 O3 [) X - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;3 E9 B$ X5 U2 E4 O0 T
- TIM_OC3Init(TIM2, &TIM_OCInitStructure);
1 y9 t6 }7 T; v
4 Y! j/ t' L8 @; f: f% s- //初始化TIM2_CH4 PWM 模式3 I a5 e2 W+ c+ k9 j9 V! k) o
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
! [2 j- c6 p5 ]3 ~; s4 h0 Q) j - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;9 k8 @- g/ e i% J" V- b' h) V0 R; a2 B
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;' v! R1 N% L% B( o! k9 Y
- TIM_OC4Init(TIM2, &TIM_OCInitStructure);
! n9 j( o% w( B; L# W" k# M' J8 p - 8 T& q+ T [' r( b
- //使能TIM2在CCR上的预装载寄存器6 b2 d9 w1 G" t5 x! ^
- TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
* i! X8 g' T) T _# I4 i - TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);+ _8 ]: O$ d/ z" B5 a q* I
- TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
8 N0 c- W# e8 U5 p - TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
* z; X' f9 K3 ~+ [8 c+ b0 t0 Q% v' S - , z3 n+ a3 M+ o. d4 C3 z
- //使能TIM2
/ X) ^! ] K, F, K - TIM_Cmd(TIM2, ENABLE);& H/ ^/ V2 X% V: n! N6 h4 f# D
- }
复制代码
: G4 m6 @4 Y( v A8 e- c这里要注意的是,定时器1是高级定时器,定时器2、3、4是通用定时器。只有高级定时器有重复计数寄存器,而通过定时器没有重复计数寄存器。定时器2初始化时,比定时器1少一行代码,这里要注意一下。
0 z* g+ _- R* L! [% |+ A; Y$ X; F1 H5 _2 x6 e8 y3 ^
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
复制代码
6 g2 T$ B7 B% i# }2 W) D8 P/ N, l重复计数寄存器主要作用如下:
0 J* R- M' M4 ]0 N& |: {/ a7 ^# T5 T5 H+ }0 J& U) ~
; S9 d/ `8 R, [
8 q1 ~! o9 D2 W+ x' N2 J其余设置方法和定时器1基本一样,定时器2的4个通道对应的IO口为PA0,PA1,PA2,PA3.将这四个口设置为PWM输出模式。7 O' A$ z, m( ]$ v% M
! Q% c6 u* t7 Z! e/ G' L; ~入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
, P4 h1 x3 B9 s+ F) O ^, [& J S# u0 _" w; `$ d
下来设置定时器3
7 a) d+ p8 p$ E5 G$ b% ~9 o5 I, P
K: R7 i5 c+ L7 c6 W2 a1 l- void TIM3_PWM_Init(u16 arr, u16 psc)
1 p: p$ a% m. t0 l; U P& t - { R, e8 a9 X0 R @6 D+ |: Y
- GPIO_InitTypeDef GPIO_InitStructure;
]! X7 k _! c! [5 _* S7 ] - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;* A0 L; `- z) C( e- X- ]7 D9 j
- TIM_OCInitTypeDef TIM_OCInitStructure;# |; N0 f6 c" q; j
, N9 Z* e- W- i- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟8 B9 e) Q" }3 G- N% `
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO时钟; w; o; w8 ]# _' R0 ~" l% W
9 g: y8 Y9 @; d7 K, d& E- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;& t: A" |0 K5 Z7 t# Q
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
% Y3 c( ^$ X2 F9 D+ C$ C+ }; K - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
8 y4 Y/ L/ a! Y7 P7 {6 I1 }5 I - GPIO_Init(GPIOA, &GPIO_InitStructure);. ~! Q6 ~! {, D( W8 V5 l
- ! v/ [: ^ N2 @4 y7 ~% {
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
5 T( \. q$ T: b5 v5 e$ X - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;% f6 i# v, ^, O3 F0 B, M# J! |
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/ }" K% [6 f+ k$ J9 j" V
- GPIO_Init(GPIOB, &GPIO_InitStructure);4 a( F0 ~0 L; T7 j/ C
. u! k5 e+ `0 B- //初始化TIM3
' L) d( g. u$ Z) N. S) ]' T4 O$ e2 g- ? - TIM_TimeBaseInitStructure.TIM_Period = arr;& w- [6 P! }0 y0 z9 B9 q! w
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;' l( `2 \% U% V" U; Q: S
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
2 _' j# O) L! l" g( a: ] - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;8 J1 M, \) ^% c0 }6 E! |
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
& }# ^, f8 s+ E$ d8 b
8 ^) A6 `! b; X& q/ z! j. u8 V- //初始化TIM3_CH1 PWM 模式
* m7 T9 l D9 g2 D - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
$ t& X2 b0 C3 |5 Q/ G$ g" O - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
% m; ?0 H' C- ^( y; l# g - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;9 _" y1 L. R# o; L& H
- TIM_OC1Init(TIM3, &TIM_OCInitStructure);
; m' g) ]: x+ n! |9 z - : j; V$ [* [/ p6 H" ^8 z* F
- //初始化TIM3_CH2 PWM 模式( d* h/ Z. _3 q$ U, t. X
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
/ n) c6 e% K0 N, `' p5 x, \ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;2 o" ]2 u: H" B. i
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;, r, ]- e& q! H* t
- TIM_OC2Init(TIM3, &TIM_OCInitStructure);
# a/ S; A& N. l) c* _; X - + H) S. ]3 r, h: ]( d2 a7 T* c% ?
- //初始化TIM3_CH3 PWM 模式% s# u$ w5 ? t% H* Y" F) z6 J$ ?
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
. m N3 ~ w4 ]3 r& E3 m - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;: ^3 ?" Z9 l0 v4 G
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
' T( M; J+ }8 |/ o3 W2 a1 L" B - TIM_OC3Init(TIM3, &TIM_OCInitStructure);
3 `& Q/ }4 C; {" }2 G - ) N0 f+ K! r+ g( M, ~( D# \
- //初始化TIM3_CH4 PWM 模式# v, _ b1 v5 k* l+ E+ A
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;3 @8 I% y( J) X. l8 s: n
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
0 U% n9 Z. }: ^ - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
0 w" l; o7 |: U4 X/ k g - TIM_OC4Init(TIM3, &TIM_OCInitStructure);$ }9 t: f) s) P7 B
8 X2 M+ W; m# W% f6 n: L4 j" g5 N- //使能TIM3在CCR上的预装载寄存器# a! ?/ {: r7 X$ O* O5 w" H0 N/ G0 t4 L
- TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);* p$ W; h$ q- W9 f+ l
- TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);$ p6 N: _) P* m! b. r% w. {
- TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
) `% ?6 ?/ C: Z& }* ] - TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);- H0 F6 e& Q$ [7 t! R
- //使能TIM3
3 U7 S) ?9 O2 p8 f9 V! m3 y# g - TIM_Cmd(TIM3, ENABLE);& l2 D4 b) a \& p: `" |
- }
复制代码
+ h }! W0 s4 [1 U2 l' w8 b设置方法和定时器2一样,定时器3的4个通道对应的IO口为PA6,PA7,PB0,PB1。将这四个口设置为PWM输出模式。0 m+ }$ V! B: y5 ]# z9 s
+ [% T" A' N" f ]4 e# x
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
& `2 R8 ~; b! \1 a- W
+ O, i* [" [$ Y% p最后设置定时器4
' Z4 k, U w9 L( f4 ^/ J1 \" V4 @5 ?4 D& `+ ~# q/ A
- ! k( F4 D1 }9 F: ~# L& }) x
- void TIM4_PWM_Init(u16 arr, u16 psc)9 H }" s8 l2 a
- {9 L: k: i0 f0 Z' u0 I8 ]: r; l, i
- GPIO_InitTypeDef GPIO_InitStructure;( H# C' y* X8 O" J: n+ s) A# o
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;' N9 `: W0 a( G$ _3 L% p9 a7 \
- TIM_OCInitTypeDef TIM_OCInitStructure;
; W% [3 ?- z$ l. V
6 J# A. e- ?& s5 r! x' {- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟
( N/ t6 ?" ], H: \! @ Z# V9 k - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO时钟) f; U! p3 }7 @- |" y2 j- x# J
: G! W' T$ C) l- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
! W6 V& i; Y, U* k5 X& f. u1 N+ J - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;' h8 ^ o. l3 ~ d5 t$ }
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
7 r& ]% M4 N9 W3 @' y- E4 }) l - GPIO_Init(GPIOB, &GPIO_InitStructure);2 I7 @* Z8 i B+ E. M
- " E1 a3 |9 n( n
- X* m) m4 p, L, P; S& c
- //初始化TIM4
* Y0 R7 }/ _. G v0 ?0 Y* U6 ~7 G - TIM_TimeBaseInitStructure.TIM_Period = arr;
3 e* ]* c4 [9 \$ d( A4 j Q! f - TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
. e) E, s# c) R$ a. v - TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- m# @/ G6 v% j2 G' z& K( D. ~ - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
, X3 ~% v5 F K+ b5 D1 \ - TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);! }1 C3 |' }0 j B: I
- % A1 b# [ z" s9 V- x
- //初始化TIM4_CH1 PWM 模式
. T4 H5 U1 V1 P6 I( a* n2 c: f% O# z# E$ G - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;3 F3 c! r! [5 C& q
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;9 N4 E" Z' V: R r! R- E
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;2 a' |% F# q" d0 `- m
- TIM_OC1Init(TIM4, &TIM_OCInitStructure);
% X/ c/ Z0 S& t: Z3 X7 m4 Z -
7 U+ }# c+ y; D: J8 X& W6 i - , L2 ?, n5 |% H9 f! W
- //初始化TIM4_CH2 PWM 模式+ F0 k" V( H( m% d, U; u
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
& H# A6 h5 ]; @6 M E - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;6 |$ g. o; J# f" T: X, E z$ \
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
( s% H# U2 i( D8 {8 Z; Z! [% | - TIM_OC2Init(TIM4, &TIM_OCInitStructure);
! P2 K. ]. z. E# s& f
/ s2 ~$ z6 W* B- G- //初始化TIM4_CH3 PWM 模式+ w( j! W+ H9 B2 e0 z4 o# n/ _
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
) V% i- l9 Y: k% W( I5 ]: c- O - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
3 S+ v; y: D8 a& L) x% k - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;3 T8 f6 u i' d8 W* y* ]
- TIM_OC3Init(TIM4, &TIM_OCInitStructure);7 {' c- j" [- A* [8 ?# q
" f' J+ M. e2 I" e- //初始化TIM4_CH4 PWM 模式/ r; }3 x a% l9 F( l5 t
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;* O; f) V! [, X c1 m' j; F
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
( Z( w- ~0 l# f; i1 \' X - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
3 j) o/ H: n+ I* c( ]* u8 j& Q) p - TIM_OC4Init(TIM4, &TIM_OCInitStructure);+ V. I' X1 }& T( | ]
- 5 W/ g9 d$ ~! b3 H
- //使能TIM4在CCR上的预装载寄存器
; N- r6 w# V+ ] L8 t: [/ ~3 e |2 K/ i - TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
' e) v- P4 d7 j% r" e4 t7 u4 J$ Z - TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
/ p$ G+ ?, m. J$ _! \ - TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);/ @" O( l3 n G: x) O0 Z
- TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
' N( k* j3 `" `* n } M
d6 t/ ?) j7 r) Y- //使能TIM43 w; @2 P1 e7 q4 ?" B! f
- TIM_Cmd(TIM4, ENABLE);
1 k6 B! E/ R2 A - }
复制代码 1 _0 g9 P- E: F- p! W" B
设置方法和定时器2一样,定时器4的4个通道对应的IO口为PB6,PB7,PB8,PB9。将这四个口设置为PWM输出模式。( J8 e8 `7 J! d0 M' n1 x3 |6 r3 F
" D6 n# N: @+ T# N7 v% V( e) Z
入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。
& h7 s% _* b9 u
6 Q3 E5 J; A5 g1 c9 B这样总共16路的PWM初始化就完成了,下来看主函数设置
0 e) t7 x9 S1 o; C" q" B
8 X- O0 E- H% s" v" {( {9 I& S5 t- #include "sys.h": d9 E/ W/ n5 ?% j$ X& k) J0 f
- #include "delay.h"
5 z/ _2 `' Y, Q2 R - #include "usart.h"
& l% L4 N' ^1 ^! R1 p8 ^. G - #include "pwm.h"" t. w6 ]) R/ `5 I9 R) D) V$ w
- I& B! c: `4 H# ?7 r) F. U& @
- int main(void)" }/ D+ c! x. c
- {
9 ^2 ?( O1 F. G4 b0 j) v - u16 led_pwm_val = 0;8 ]% h7 m' p( y& v2 p3 P
7 J4 o4 Y0 C& m& u7 C- delay_init(); //延时函数初始化
% d0 l: s/ ~3 Q5 Q0 u; B$ s) x - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
1 E8 `4 [- }9 \5 C; m
( c. Z9 N+ Z' U1 C- //不分频。PWM频率=72000000/9000=8Khz
) r; S6 N5 b& F: a, e - TIM1_PWM_Init(8999, 0);0 w0 [! v8 A, p/ p( c
- TIM2_PWM_Init(8999, 0);
( T; T% J) u" Q7 U/ u' z1 G - TIM3_PWM_Init(8999, 0);
& o+ j" y2 u2 _8 y, }5 E - TIM4_PWM_Init(8999, 0);
( d( J7 |9 E/ I4 x! K( n1 c1 C- w+ L - led_pwm_val = 899;
+ N! p* c2 j/ K* b: a - while(1)9 w0 D, W7 P1 |$ u+ `; {( [) L& S
- {$ O2 Q5 }4 A) M- l+ i* g8 L
- if(led_pwm_val < 8999)
( p m2 ?& y* |( @ - led_pwm_val++;
1 C9 Y( S& I# C4 ~' A9 r d) [6 f# t - else; |8 @+ @( g* S M/ C1 K+ `4 D
- led_pwm_val = 0;
% J a: ^ N e {0 n- f7 V* I
! [* U. z; m' V5 I9 h; j- P- TIM_SetCompare1(TIM1, led_pwm_val); //TIM1_CH1 PA8
! ]. Y+ c5 R% e& z5 Q7 n - TIM_SetCompare2(TIM1, led_pwm_val); //TIM1_CH2 PA9
8 z8 \0 K7 l+ s - TIM_SetCompare3(TIM1, led_pwm_val); //TIM1_CH3 PA10! \ j5 V% @( U D7 H' r3 s) g& v1 _
- TIM_SetCompare4(TIM1, led_pwm_val); //TIM1_CH4 PA118 }/ A7 V1 w- l0 d8 K C& [+ j
+ `1 n+ A8 o/ d/ I+ W0 ^" X- TIM_SetCompare1(TIM2, led_pwm_val); //TIM2_CH1 PA0/ @0 ^7 t X, x/ s, K( k% V
- TIM_SetCompare2(TIM2, led_pwm_val); //TIM2_CH2 PA10 _! [! X. p& v k
- TIM_SetCompare3(TIM2, led_pwm_val); //TIM2_CH3 PA25 T* l# a1 Y: e4 w$ U+ N; D$ ^
- TIM_SetCompare4(TIM2, led_pwm_val); //TIM2_CH4 PA3
R# }+ M% U9 z
( _ X7 @/ G! a# C- TIM_SetCompare1(TIM3, led_pwm_val); //TIM3_CH1 PA6
e( Q+ ~" }2 x! x - TIM_SetCompare2(TIM3, led_pwm_val); //TIM3_CH2 PA7
) [2 p/ d1 e, B; ~* W! Z3 u - TIM_SetCompare3(TIM3, led_pwm_val); //TIM3_CH3 PB0
$ b9 h% k0 f. I7 {' x4 c( ? - TIM_SetCompare4(TIM3, led_pwm_val); //TIM3_CH4 PB1
2 ~# m6 N0 X# O* A - ! E7 Y G- C7 S: o* j3 C
- TIM_SetCompare1(TIM4, led_pwm_val); //TIM4_CH1 PB6
4 y/ t7 j8 L i - TIM_SetCompare2(TIM4, led_pwm_val); //TIM4_CH2 PB7
$ ] ~& H- D( p- o0 I# L" W - TIM_SetCompare3(TIM4, led_pwm_val); //TIM4_CH3 PB8
! i* e2 z( M4 U( k - TIM_SetCompare4(TIM4, led_pwm_val); //TIM4_CH4 PB9- @+ i" ~6 K7 `* b7 l
- ) [" l }" w0 @1 p e |" l" e
- delay_ms(1);) c1 V* f: i/ B% d: ^1 [$ O
- }
3 q/ q6 N- p2 F - }& X( g4 A9 L d& W1 a: b5 u
复制代码 ' m1 Z# v5 l8 C0 }8 Y
初始化时设置4个定时器的频率为8K,在while循环中调节占空比从0---100%变化。程序编译后烧写到单片机中,通过示波器就能观察到PWM波形变化了。
" O) u$ @( f, m7 a0 {8 N$ I
4 E% y6 t2 N! f( ]0 b& w这里先用软件仿真看一下效果6 w6 n$ l N3 I: u- m/ q
/ z _% d. \( T

9 H$ v+ @' R5 f, q/ J o6 U1 h! h1 q. S4 l6 F8 q# v( A6 O
8 t7 M9 b* L1 T$ ?5 B! J |