用定时器生成PWM波' x E5 Y, f1 E: H9 f' Q4 |) U
PWM全称是Pulse Width Modulation,通过控制高频信号的占空比,眼睛当成低通滤波器,可以控制亮暗。再循环更改pwm的阈值,就弄出了呼吸的效果。
+ o6 d- M3 R4 Y* z& q* E5 @/ r 这里采用一个比较简单的方法生成PWM波:设置定时器中断然后根据阈值判断置高和置低。
! F0 ]4 z' |0 V- void TIM3_IRQHandler(void)
+ Q7 P+ p( U: a7 K - {
0 u1 O: R$ b) H; k- D - TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
# I5 @0 e+ M( ^" l - if(counter==255) 6 A( ]$ O( Y: ] I
- counter = 0;. _/ d- c U) Y9 y
- else * [" B0 ? C* r; b/ H$ P
- counter +=1; y4 K- _* c/ I; ^, P+ p; w1 ] ?
- if(mode == 0){( B9 w5 i- ^3 m9 X- K
- if(counter < pwm) " N' k3 V- d8 ` r9 s% w+ v+ Y& K
- GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);
- I4 K* }7 F X) p - else 2 D! A5 @! E& \3 A: ]
- GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);
% ?# t# R9 [0 _* ^ - }' v5 W$ L& ?: @ R2 A! }- M' d
- if(mode == 1)
$ t& M: a: M" p4 e - {
7 ?4 @+ o, I) } y+ u - if(counter < pwm) " R- T" g4 k, c6 ~
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);
1 ]$ ^" i' L* [1 B" F - else
, D3 C6 R D. A* U6 i' n" V - GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);
* q$ D1 L; f- g# U, R - }
0 G0 H* q# j: C) `% ?' T - if(mode ==2){
5 F' B i7 \1 ?9 M2 }2 @% ? - if(counter < pwm)
2 ]& ]# {: t$ |- U% J7 e - GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_0);
+ s, S" N4 f& m1 y- Y - else
% f T1 T3 k" L1 M' s9 h - GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_0); 4 \# i3 l& h, ~
- }& `8 j ~% U& o& F+ g: N( d
- }
复制代码
; C8 a) d5 x5 i. D8 L! H& }程序流程
! }( v; f$ |; P8 m- P2 v/ t开启外设时钟(GPIO和TIM)
0 W" |1 ]* D" y. ]& m- void RCC_Configuration(void) 4 b# B2 O) y2 {/ f( q- @
- {9 V* w4 V8 |. p9 b/ |
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); 4 m; D, e+ z1 y$ c
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4|RCC_APB1Periph_TIM3, ENABLE); $ S+ k0 t5 o: Z- j% f5 F
- }
复制代码
7 d" j6 J" q0 M; Q配置GPIO7 |7 f( b6 c6 J- l; R6 B3 t4 }( }% J/ |
配置时钟, 使能中断(计数阈值,预分频,时钟分频,计数模式)8 s- g) U7 P7 P2 o: e
- void tim3() //配置TIM3为基本定时器模式 ,约10us触发一次,触发频率约100kHz
) ]8 z1 U7 \: [3 \$ i - {
. {4 L* v( } O5 }1 ~. H - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义格式为TIM_TimeBaseInitTypeDef的结构体的名字为TIM_TimeBaseStructure
6 q" h U: G3 ` - TIM_TimeBaseStructure. TIM_Period =9; //配置计数阈值为9,超过时,自动清零,并触发中断0 n: o G: }3 O8 y4 L
- TIM_TimeBaseStructure.TIM_Prescaler =71; // 时钟预分频值,除以多少8 z2 J4 @: z" U; M1 R
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频倍数
( l; [' S! N$ O - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数方式为向上计数
- M* A7 x$ l! @3 H8 b3 z4 A - TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化tim3+ D4 @7 k8 f; s1 `! J9 \& b: c/ \
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3溢出中断标志
! ]# G4 K+ ?$ j+ U7 l. b: W - TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); // 使能TIM3的溢出更新中断
* J" Q8 m- D, y - TIM_Cmd(TIM3,ENABLE); // 使能TIM3
$ F* P/ y, R* @ - }
复制代码 : N- n" z2 h% Q V
配置中断优先级1 Q. P6 W" k( L
- void nvic() //配置中断优先级
) R, [% V9 u9 O6 h7 S/ L+ [ - {
( u( ~1 ?1 X& a4 c; }3 J. a# A& j - NVIC_InitTypeDef NVIC_InitStructure; // // 命名一优先级变量
( }3 i' Z+ a B9 [1 n - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 将优先级分组方式配置为group1,有2个抢占(打断)优先级,8个响应优先级
! _% b, `) Z& S8 T) Y - NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //该中断为TIM4溢出更新中断
! S) B$ ?# Q: A; J - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//打断优先级为1,在该组中为较低的,0优先级最高+ Q+ \5 o4 V, a7 M
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级0,打断优先级一样时,0最高/ m0 J# S% U' O+ o+ l: w
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 设置使能7 V/ q! v! E" g. X3 p6 p
- NVIC_Init(&NVIC_InitStructure); // 初始化% l5 E. v0 Q+ @, t% R
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //要用同一个Group
0 k, D3 O& }1 `: [( `, ~2 y - NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 溢出更新中断
" Z' |5 P* b$ t9 ^8 y( `- T/ r - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 打断优先级为1,与上一个相同,不希望中断相互打断对方
6 G# n/ T, }* j, g - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 响应优先级1,低于上一个,当两个中断同时来时,上一个先执行! P8 }+ C6 \6 d- k3 A4 c
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
1 @8 b0 F5 c7 L# w - NVIC_Init(&NVIC_InitStructure);7 A) U$ U3 N$ d; U# X
- }
复制代码
0 T- F2 F9 P# i" ?! j写中断服务函数,相关实例请移步:STM32呼吸灯的PWM原理与代码实现。
( W0 K8 S. R5 O7 p" i0 X6 u& K, o/ b2 S$ m
代码实现为了方便按键检测,除了TIM3配置PWM波之外,TIM4用来检测是否有输入。由于使用开漏输出,这里使用5V电源。
8 S% t% M; s R% h" F) V- #include "stm32f10x.h"
7 E" H& P* F+ {8 P2 S6 H8 j- g- s - #include "math.h"
u' ^) T. c% J2 m" B - #include "stdio.h") G: T) y+ ^. j R' T# l- u6 Z/ `
. `! Y0 R2 O: U$ ?- u8 counter=0;
+ D* V$ o$ t7 v: F+ l! k - int pwm=100;. x" Z# {; y# ~0 X! t5 N2 P
- int flag=0;* \7 d7 @3 Y5 u4 `
- int mode =0;
4 p) d( A3 L/ M) g9 k# {/ U - int velocity =0;
: N: B9 Y9 o3 Y' G; A' L - int turning=1;
4 Y1 z0 z; }4 o1 D. M - ( F1 k% ] j& i3 k3 }+ Q
- void RCC_Configuration(void); //时钟初始化,开启外设时钟
5 d N# w$ M) j! f) r - void GPIO_Configuration(void); //IO口初始化,配置其功能3 B' I* P. n7 A+ @, L
- void tim3(void); //定时器tim4初始化配置
+ G/ p+ _$ r) k8 [( _8 F6 W) h/ @ - void tim4(void); //定时器tim4初始化配置
5 d' { p+ Z' N1 d4 M0 G5 F - void nvic(void); //中断优先级等配置' U) q/ p, g& `, c+ g, w( t
- void exti(void); //外部中断配置
: X' G8 w2 i! v3 @/ k! \: D - void delay_nus(u32); //72M时钟下,约延时us+ d- x6 \5 w x5 u9 f1 G7 a
- void delay_nms(u32); //72M时钟下,约延时ms- C) l8 p. N6 g& [) A/ r
- void breathing(int velocity){$ q5 x! a! b, I
- switch(velocity){
4 I% a# \ J- Y H4 x - case 0:8 z. }& g! |& L$ n
- if(flag): Q! a& ?3 [: m5 q3 R% \
- pwm +=1;. {! w$ p7 H* o H
- if(pwm>240) flag=0;9 T {5 v4 ~5 _ N- g( ~, A
- if(flag == 0){* K, i% q/ @6 F* G
- pwm -=1;8 E2 D; S0 s' D4 x4 P
- if(pwm<10) flag=1;; K4 d& R4 F3 C% Q2 Q
- }
; ?/ z4 q5 [ } - break;, c1 G8 m8 I6 z4 n6 f* F
- case 1:
1 f6 s$ E3 X! ]* x0 ` - if(flag)& O8 K; a# O) l+ O$ [9 i8 }
- pwm +=2;9 I- e5 G4 |+ N2 M& k( g
- if(pwm>240) flag=0;$ `' }: e( A7 m
- if(flag == 0){
3 R" M; a: `5 G$ d - pwm -=2;
9 H4 q$ I- _; } - if(pwm<10) flag=1;
6 ~4 h4 o1 A3 d' U7 n' H - }# E4 Y0 P. f, ^5 W& D2 f: K8 |* u& a" E
- break;/ A7 N6 A/ W" f) W* [
- case 2:2 O3 B# r: l6 U3 ~+ M
- if(flag)
9 x7 n% A4 O! x6 Y9 v - pwm +=3;
0 f) s) A* x% c9 a( I - if(pwm>240) flag=0;
+ F; Y, P& I" u! |. R. n/ y6 b. K @ - if(flag == 0){
6 p# x5 d- E5 [0 H( r: o. q1 E - pwm -=3;' t/ P# E2 V4 N# o
- if(pwm<10) flag=1;
: \/ d3 P. H: Z7 `$ y) _ - }
: O* e7 Y* i% d) K - break;
K& w, { w1 M) B2 [ - }
8 P" @- K Y! f/ O - }2 `( i; M9 N$ g' G6 K3 I/ K6 g. t
- ! m# i1 O( s% m$ J
( S6 K4 q" O/ N- void assert_failed(uint8_t* file, uint32_t line)
; M: A7 L1 b9 l8 @& W - {, C! `9 Z# \) W0 D! @, Y
- printf("Wrong parameters value: file %s on line %d\r\n", file, line);7 ?& |* J/ a* e9 r7 m& C* D
- while(1);6 H+ w, @7 P# C9 x5 K% a
- }
4 K/ b! W* H6 ^$ I2 k* ? - ( M# j& G+ [/ C
- void TIM4_IRQHandler(void) //TIM4的溢出更新中断响应函数 ,读取按键输入值,根据输入控制pwm波占空比
! I) Z+ p- [8 q, ` - {3 D' \4 b% S* H2 z% C# ^
- u8 key_in1=0x01,key_in2=0x01;8 l$ S+ B' T9 `& J. N/ q
- TIM_ClearITPendingBit(TIM4,TIM_IT_Update);// 清空TIM4溢出中断响应函数标志位
$ ]5 g. o- q4 ^- Z - key_in1= GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12); // 读PC12的状态
: m2 \( S$ S2 S6 u) r& s1 B# p - key_in2= GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13);// 读PC13的状态" `* y: G% ?, k% d9 B" v* i) j+ \
- if(key_in1 && key_in2) turning =1;& X8 K* g3 D8 R* C3 X( L
- breathing(velocity);
: F! I) x9 R9 ~7 D* S - if(key_in1==0 && turning){( i- U) i' |* G
- turning =0;- t; L& q) D: ~
- velocity = (velocity + 1) % 3;
) {* O, H! n. Y" `4 V% u0 X - }//调速度4 {7 l* `8 c6 G- C# i
- if(key_in2==0 && turning){! l q" r) g: h# C7 X/ g2 ^
- turning =0;
4 T1 ~+ ?2 O, e% n" r - mode = (mode + 1) % 3;
- V8 n1 j- M4 y( e' { - }//调颜色
- ]3 ]! F, R/ O& A7 q8 q! `* D - } " `; i$ A/ W/ X/ D# o2 w
- 8 q' [/ }6 l- g+ Y. K1 `9 b
- . I6 k) }, k/ @
- void TIM3_IRQHandler(void) // //TIM3的溢出更新中断响应函数,产生pwm波1 m3 ?+ m p3 `2 x/ F: y
- {
. J( N1 d& `& ^( @% W# e, ~6 G% u - TIM_ClearITPendingBit(TIM3,TIM_IT_Update); // // 清空TIM3溢出中断响应函数标志位
8 b. k- {6 C+ E { - if(counter==255) //counter 从0到255累加循环计数,每进一次中断,counter加一
6 B; Z; e! s9 Z( _1 c* K& Y - counter = 0;( V2 {8 F+ u- b$ e% T
- else
+ ^1 L7 h" E3 d3 x. e. H4 b8 ] - counter +=1;
% \% ~7 H, F% D1 A5 M - if(mode == 0){% {7 d% M+ R" V7 N( z/ E3 ~
- if(counter < pwm) //当counter值小于pwm值时,将IO口设为高;当counter值大于等于pwm时,将IO口置低6 \* u$ F) e! N9 q) l
- GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1); //将PC14 PC15置为高电平
4 `0 }- c$ A4 T1 W3 O - else
5 b! h. \& K5 {0 q7 r# k9 s, d - GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1); // 将PC14 PC15置为低电平
; ?3 ]9 d( k7 ^) k. o - }
" r8 ^* Y; V1 l2 S - if(mode == 1)
5 G* T# L/ [% y - {
0 d. y' a% }( o8 l - if(counter < pwm) //当counter值小于pwm值时,将IO口设为高;当counter值大于等于pwm时,将IO口置低
% }# }6 X1 D! [' C9 f. ^* o! l - GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2); //将PC14 PC15置为高电平
) v( A2 M- Y* p" |- Y - else
5 e0 _2 S7 E% v3 t9 }- L - GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2); // 将PC14 PC15置为低电平7 m3 R d: }/ J& K3 d* D E
- }
2 b: _" O* f7 ^4 u* `$ d - if(mode ==2){
3 C* F: y5 R0 b" o( G P - if(counter < pwm) //当counter值小于pwm值时,将IO口设为高;当counter值大于等于pwm时,将IO口置低
4 p; o- Y8 V% s. n - GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_0); //将PC14 PC15置为高电平1 c& A9 Y. H5 F: i' x: n4 w$ g
- else/ J) V5 ]$ I. r5 J1 O1 V B
- GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_0); // 将PC14 PC15置为低电平" j5 q0 q3 u6 N' O: |( w
- } P0 w$ j& m% ? K3 p: X8 y6 L" H8 ?
- } + z" r( \8 \, e8 u
. G2 M) O# w, u- h! W- 3 f6 r+ n! i! \. D' u
- int main(void)! d0 Q' ~$ \; q) h Q# s( {" Z
- {
9 {0 L4 Y: c& a3 @, {2 D9 ? - RCC_Configuration(); " i: m% ^0 u3 G9 x" Q
- GPIO_Configuration();
% h/ t: b, Q* ~ - tim4();
5 b5 y+ O7 i( a3 ~9 j9 S3 ^' C$ R - tim3();
) D/ _* ]* u. o7 m7 S* V: l3 t - nvic();
# u6 d) U3 W; t5 W& ]" j - while(1)
$ O1 t6 N7 A) \0 D, n& ] - { 2 W* {* V: v: q" @, _
- } 0 f( Q( e& I" p& I) y
- }
* u2 S9 B8 Z/ |3 I( U0 f
: M( v% U. F0 m* B3 _- void delay_nus(u32 n) //72M时钟下,约延时us
1 w: i9 l+ G" L Q0 i - {
- S0 ~ z w: [ H" F5 i - u8 i;+ L" H7 D/ g6 ?$ c. R5 @5 a/ y
- while(n--)2 ^# f9 @' v3 T
- {" V4 M) I O _8 ?9 V6 ^+ E6 ^3 E
- i=7;2 \2 v! C' C1 `5 g( ^' { v
- while(i--);9 q" o7 {+ a2 m% ~3 m
- }, e7 i& f2 ~ { [" l
- }
, [* H0 f# d5 n5 k - * g' v7 t0 i1 g4 r2 x; u1 I/ ]* @! u
* d: ^8 s/ T/ }9 P* d& y- void delay_nms(u32 n) //72M时钟下,约延时ms8 {+ _. o% J* b$ z
- {8 [( w) `" N( \ B7 R
- while(n--)% x9 f. ^* u6 _( U7 Y: [
- delay_nus(1000);) s3 T* G& u8 L$ _& u5 f. g
- }
% C2 O$ [: s. Z" H2 U% `3 v" {
. N t5 g* n" X7 X1 j. A, G- , T4 w5 B: Z2 ?6 n: b
- void RCC_Configuration(void) //使用任何一个外设时,务必开启其相应的时钟9 Q3 I5 ` \* w7 j9 ]
- {
2 }6 W& Z( L+ }' H4 K; R. C/ R& L - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能APB2控制外设的时钟,包括GPIOC, 功能复用时钟AFIO等,
7 @1 p1 [: |2 b$ P - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4|RCC_APB1Periph_TIM3, ENABLE); //使能APB1控制外设的时钟,定时器tim3、4,其他外设详见手册
% H" u# v5 w m# x |3 I7 } - }
4 ~7 M( O; u8 b$ J - / Q& v% ^. _# w7 i- s
- * \$ M0 M+ W- ^
- void GPIO_Configuration(void) //使用某io口输入输出时,请务必对其初始化配置 z: b% |: M/ A) u
- {3 i0 e9 P3 |4 C% a5 \* {
- GPIO_InitTypeDef GPIO_InitStructure; //定义格式为GPIO_InitTypeDef的结构体的名字为GPIO_InitStructure
9 f! Z; s, R4 o8 s! D7 N) I1 k7 L0 c - //typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef;
* ^ [! Y- x6 l4 ]: N - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //配置IO口的工作模式为上拉输入(该io口内部外接电阻到电源)
) @ p V2 S# |. ^. ]) T - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置IO口最高的输出速率为50M9 v! _8 u" M2 ]8 d
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13; //配置被选中的管脚,|表示同时被选中8 {7 B% u4 Z! m: j' v; L4 t+ D
- GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC的相应IO口为上述配置,用于按键检测
% O: g( c: z, B1 O9 C3 m4 G& h - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //配置IO口工作模式为 推挽输出(有较强的输出能力). s: I* ^1 f! K3 M) ]& v
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置IO口最高的输出速率为50M
0 K1 a$ u: M. R( u! y/ s - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2; //配置被选的管脚,|表示同时被选中
& ~* g! k* Z, j' o9 } B - GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA的相应IO口为上述配置
( j9 {9 C) o5 h1 o3 s) j - GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //失能STM32 JTAG烧写功能,只能用SWD模式烧写,解放出PA15和PB中部分IO口4 Z3 V2 A3 x ~3 |" \1 C3 `
- }
7 g. C# b7 L# t' f7 D2 C
8 V: n( ^- c i0 J
' H( r1 ` S0 b3 p- void tim4() //配置TIM4为基本定时器模式,约10ms触发一次,触发频率约100Hz
# V8 {3 r8 a, w% m: @4 @0 f - {9 v6 h( e- P1 P' J- R- X+ B: [, k$ P# E
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义格式为TIM_TimeBaseInitTypeDef的结构体的名字为TIM_TimeBaseStructure
% ]$ K4 c) M* x8 E - TIM_TimeBaseStructure. TIM_Period =9999; // 配置计数阈值为9999,超过时,自动清零,并触发中断0 z2 F9 T6 v/ O- y1 Q9 H* o- g
- TIM_TimeBaseStructure.TIM_Prescaler =71; // 时钟预分频值,除以多少$ H* u) q" w C4 N" b% F/ |7 o
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频倍数
) k6 ^6 h5 {( @ - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数方式为向上计数
/ @. O, L8 T, a$ F) I$ r - TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // 初始化tim46 A; Q( G& G& @( j$ p2 m% r
- TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除TIM4溢出中断标志
8 y. O$ Y9 L5 V; ~ - TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); // 使能TIM4的溢出更新中断
# U* \, D, ~4 Q; K - TIM_Cmd(TIM4,ENABLE); // 使能TIM4
' g8 x5 t4 K; q& g5 V - }- q. D O3 S% L C7 h: _5 a: M
, R4 M/ U5 w' S* H
p1 V9 j% S2 u) [6 }- void tim3() //配置TIM3为基本定时器模式 ,约10us触发一次,触发频率约100kHz$ _& n) _& x9 n$ @/ G
- {
5 i. I$ x. c7 ]& _2 _$ y - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义格式为TIM_TimeBaseInitTypeDef的结构体的名字为TIM_TimeBaseStructure
8 M4 @4 q% o. |) S6 Y! W/ A - TIM_TimeBaseStructure. TIM_Period =9; //配置计数阈值为9,超过时,自动清零,并触发中断
' C i, r+ w7 H& k4 P1 V6 a - TIM_TimeBaseStructure.TIM_Prescaler =71; // 时钟预分频值,除以多少
& Z4 _+ a' ^ Y5 ^2 ]5 I& b9 j - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频倍数
5 E. s, F% D0 c8 ?* d# T' k# v - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数方式为向上计数
8 c$ d5 |) o8 ?; u - TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化tim3
) _. M( q. j" B5 p, F9 \' f- r - TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3溢出中断标志! q6 h& Z/ s* B1 t) m
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); // 使能TIM3的溢出更新中断( f. M, f8 ^* G) s! R8 ~
- TIM_Cmd(TIM3,ENABLE); // 使能TIM36 g4 Z0 Y1 y6 ]. V: q! K
- }# F" E' P3 G8 l
- ( M" e. M6 n- y. ?( _, H, |
& Y, j* ^4 g( Z! t6 K# o9 F- void nvic() //配置中断优先级
0 T8 ?) r4 ?# l# y& Z/ s, U - {
; u. @: L* X/ x" h! S& i - NVIC_InitTypeDef NVIC_InitStructure; // // 命名一优先级变量7 v' w: V) g6 f& m, f; }2 g, K
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 将优先级分组方式配置为group1,有2个抢占(打断)优先级,8个响应优先级2 B% o3 ?, Y! I p# u5 D. W3 G; v* p
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //该中断为TIM4溢出更新中断% _" `2 y" K; S) a& K+ @7 V9 b
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//打断优先级为1,在该组中为较低的,0优先级最高5 N# d! u2 C% f- a" d
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级0,打断优先级一样时,0最高
+ e4 V; n6 F: g, { - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 设置使能
$ J- L5 K6 D" w0 [' _0 T1 j n - NVIC_Init(&NVIC_InitStructure); // 初始化* Z) v! `: L+ q& o. e* |2 d
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //要用同一个Group
) z% ^) O! ~' @: \3 k& X0 x - NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 溢出更新中断
! P" b [8 H9 d$ B, D$ y - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 打断优先级为1,与上一个相同,不希望中断相互打断对方' g h8 v& T7 d, c' r, [# [
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 响应优先级1,低于上一个,当两个中断同时来时,上一个先执行
9 Y# M L. }6 M3 }7 r# E - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;& w$ }( Y, p3 R3 q7 ~. K, N% l
- NVIC_Init(&NVIC_InitStructure);
& O$ ?" V- Z) H' R. \7 C7 ]6 l - }
复制代码 . v, a& `8 t# B9 r+ O
6 ~% D! F+ ?7 @* q5 l6 l9 |4 W' q |