你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32呼吸灯的PWM原理与代码实现

[复制链接]
STMCU小助手 发布时间:2022-6-22 19:00
用定时器生成PWM波
    PWM全称是Pulse Width Modulation,通过控制高频信号的占空比,眼睛当成低通滤波器,可以控制亮暗。再循环更改pwm的阈值,就弄出了呼吸的效果。
    这里采用一个比较简单的方法生成PWM波:设置定时器中断然后根据阈值判断置高和置低。
0 S+ w/ U; _2 ~" A/ e7 m* ~

: z. p7 A4 u, d  o' A7 V8 ^
程序流程
  • 开启外设时钟(GPIO和TIM)

    4 s, f, |+ [* x
  1. void RCC_Configuration(void)                : R* F1 T* T4 h
  2. {
    & O# L( U) W# g( q
  3.      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);                                                      
    , }, h& T( x5 i( B  R- f! A# k
  4.      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4|RCC_APB1Periph_TIM3, ENABLE);
    / c& W; F4 ~$ H# m& h. Z$ c; |
  5. }
复制代码
5 Q0 K$ I: j2 Y2 b5 s2 J$ w

- A# B  N9 q9 C3 W% `- v6 M+ l, x
  • 配置GPIO
  • 配置时钟, 使能中断(计数阈值,预分频,时钟分频,计数模式)
    1. void tim3()                           //配置TIM3为基本定时器模式 ,约10us触发一次,触发频率约100kHz
      0 A* d& l/ L0 {* e& I7 B% @
    2. {6 [7 e9 ?4 K4 @
    3. TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   //定义格式为TIM_TimeBaseInitTypeDef的结构体的名字为TIM_TimeBaseStructure  * {; q& @9 ^" `: b, b9 N6 }
    4. TIM_TimeBaseStructure. TIM_Period =9;         //配置计数阈值为9,超过时,自动清零,并触发中断* X  n- u0 k5 _3 Y# i# s5 w
    5. TIM_TimeBaseStructure.TIM_Prescaler =71;     //    时钟预分频值,除以多少
      % l( j& d" Y* M# p0 c9 P
    6. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分频倍数
      ' H2 g% [+ x* S1 V
    7. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // 计数方式为向上计数9 H7 V, S0 S! X! E5 j+ a
    8. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);      //  初始化tim3* t8 O$ Y& d% c8 _  _
    9. TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3溢出中断标志; W3 ~$ }' A% [" U3 Z  q
    10. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //  使能TIM3的溢出更新中断$ v; Z* ?& n& J3 v; X7 x6 E
    11. TIM_Cmd(TIM3,ENABLE);                     //           使能TIM37 L9 Z% z" y# D% u
    12. }
    复制代码
    - q- {- d0 X" {& H* e: d/ C9 x+ e
$ ^! h' Z1 @5 `# r9 i4 m
  • 配置中断优先级

      O! A4 A# }. u" R& g, n
  1. void nvic()                                 //配置中断优先级
    # Z5 f& C, d6 @$ U
  2. {   
    ) H) w; y0 n) E
  3. NVIC_InitTypeDef NVIC_InitStructure;  //    //   命名一优先级变量
    $ T" l- l; \; R3 q# X2 m" r' g
  4. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);    //     将优先级分组方式配置为group1,有2个抢占(打断)优先级,8个响应优先级
    0 Q$ e- E  W8 k/ G- Q
  5. NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //该中断为TIM4溢出更新中断6 w% B& [  ?( f
  6. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//打断优先级为1,在该组中为较低的,0优先级最高
    9 b$ ], G: v- z
  7. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级0,打断优先级一样时,0最高
    + O/ L1 x" E$ g6 V+ _
  8. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //  设置使能" ~; D/ b" y+ D0 `, [8 a, F0 s7 c
  9. NVIC_Init(&NVIC_InitStructure);                        //  初始化
    " g& z! @; K% H" F
  10. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //要用同一个Group
    1 l* K# E) F* t  @, w2 A+ a
  11. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 溢出更新中断
    0 x! W* K8 _! k3 R' H
  12. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//    打断优先级为1,与上一个相同,不希望中断相互打断对方- M; S) Q$ F' f7 b
  13. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     //  响应优先级1,低于上一个,当两个中断同时来时,上一个先执行
    ; T9 [1 [9 G2 \6 ^/ F. w  x
  14. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;* a2 F/ j) Z/ t' [' _! L+ i
  15. NVIC_Init(&NVIC_InitStructure);/ i5 T0 b: {) u: W
  16. }
复制代码

4 b, A* _8 j6 ?4 w
# y$ f) S5 u) W& |+ V
  • 写中断服务函数
    8 n# O$ K4 K. f6 I4 q- ]( u3 c
代码实现
    为了方便按键检测,除了TIM3配置PWM波之外,TIM4用来检测是否有输入。由于使用开漏输出,这里使用5V电源。
  1. #include "stm32f10x.h"
    # v2 w, Y5 z; E/ V( r
  2. #include "math.h"5 A& l9 @# V, J
  3. #include "stdio.h"
    1 ~6 f3 S0 P. v$ w( P
  4. : m' A' t' x" p6 O4 V3 ^9 ^
  5. u8  counter=0; : G! v3 k( F5 M# U, T
  6. int  pwm=100;4 s# I# Z( M* a' n8 U# N0 o% w
  7. int flag=0;3 r  W1 C. O/ U7 T" P. r
  8. int mode =0;
    3 q& A! C0 c# ~' ]9 e
  9. int velocity =0;* x, \6 @+ U" a" H' q5 r% h' T
  10. int turning=1;+ V) e; V) j" a
  11. & @" l$ A2 d# y/ f2 R4 I0 f
  12. void RCC_Configuration(void);    //时钟初始化,开启外设时钟5 o# K: X* O5 V* P
  13. void GPIO_Configuration(void);   //IO口初始化,配置其功能/ C( V4 a# S/ m, ]
  14. void tim3(void);                 //定时器tim4初始化配置0 }2 N. Y- x% A
  15. void tim4(void);                 //定时器tim4初始化配置
    4 e! ]4 y6 p. O/ n. d) y  [
  16. void nvic(void);                 //中断优先级等配置; I( o& a/ K" y
  17. void exti(void);                 //外部中断配置# x! b5 ~6 M# C7 [* {; ^, J
  18. void delay_nus(u32);           //72M时钟下,约延时us
    . ?1 T# W6 u# h7 s  i
  19. void delay_nms(u32);            //72M时钟下,约延时ms
    & s) C5 }) K- f1 J; |. g
  20. void breathing(int velocity){, U0 }! g/ D# W# z! D7 l( j" d
  21.         switch(velocity){; t: y6 A- |" _
  22.                 case 0:
    9 B% o2 E5 q# y; {4 R4 A
  23.                     if(flag)' `0 X1 k0 w; P5 W- w
  24.                             pwm +=1;) p0 ?) P! U' d* q
  25.                             if(pwm>240) flag=0;
    ! q- s, z7 p' U1 Y& i4 r' h' ?
  26.                     if(flag == 0){3 ]% J1 G- S: o! e
  27.                             pwm -=1;  C0 x& z6 ?6 w2 M7 D; F. h$ U9 z# F
  28.                             if(pwm<10) flag=1;5 P* a3 v- }* f2 S
  29.                     }
      a, J3 q" A2 y+ o
  30.                     break;
    6 N2 s5 g& P' p$ n! G/ Z0 Q5 k8 X
  31.                 case 1:
    9 v: ]/ f3 m/ P  X- o9 r
  32.                     if(flag)- A9 _0 z! Q3 L. h* [
  33.                             pwm +=2;" W2 F. g6 e( r! Z; ^3 |, j
  34.                             if(pwm>240) flag=0;
    5 _3 R. N4 u* ]9 N
  35.                     if(flag == 0){! `" S8 w/ s0 @) z( C, S
  36.                             pwm -=2;
    2 P' t3 F# r7 C) n9 Z9 h- B
  37.                             if(pwm<10) flag=1;, A% q9 ~2 A5 Q$ M3 i; t
  38.                     }$ \4 n, @( e. i
  39.                     break;
    ! w5 S- b' l8 t' H  X
  40.                 case 2:
    1 u, \. S' _3 ~$ h4 W9 `! Y
  41.                     if(flag)
    3 W9 S* [/ E1 N9 O3 n0 z" [1 j
  42.                             pwm +=3;
    , P0 w- B1 |" D5 b1 {9 k/ [
  43.                             if(pwm>240) flag=0;
    7 }, Y; \5 X2 |( G& O! A
  44.                     if(flag == 0){. g, h8 K" M' m% y
  45.                             pwm -=3;0 p$ {: I4 [8 L
  46.                             if(pwm<10) flag=1;6 Z9 R# J. Z; {: ~1 z8 W" ~& O
  47.                     }
    9 s" j1 A5 L4 K* W0 j; D" c! x
  48.                     break;
    5 V6 s: q  q6 k4 j
  49.         }
    : S" N% n$ I- X. J" V5 N
  50. }8 A* W" h) ]; `, e  i( n$ G

  51. : \9 Z  s" W6 w9 a5 w' s* u

  52.   x! _% r2 H% k
  53. void assert_failed(uint8_t* file, uint32_t line)
    ! F. ^6 H! q7 V0 h
  54. {0 A9 g" P" E9 [1 C- v& ~1 H& I
  55.     printf("Wrong parameters value: file %s on line %d\r\n", file, line);) ^6 f0 @% X# {) D  e3 Z8 Q
  56.     while(1);
    + {- y' m1 q, V- J( g; r
  57. }1 U. C& z8 l* O
  58. ; m9 i5 j  n% w3 p4 n3 b3 o
  59. void TIM4_IRQHandler(void)   //TIM4的溢出更新中断响应函数 ,读取按键输入值,根据输入控制pwm波占空比9 @: a& A* J0 f. D& X8 u' t
  60. {
    - g2 \0 i+ p' {: X
  61.         u8 key_in1=0x01,key_in2=0x01;
    $ c/ p6 n/ ]9 R* @; _7 U
  62.         TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//     清空TIM4溢出中断响应函数标志位2 ]) H9 ^1 ]0 \) ~* P0 V  B
  63.         key_in1= GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12);  // 读PC12的状态
    0 M) D: A4 G, R: A8 t0 {, ~$ M9 z
  64.         key_in2= GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13);// 读PC13的状态, d+ H+ |! c0 A( L
  65.         if(key_in1 && key_in2) turning =1;" u* m/ {/ [  U- }( ~
  66.         breathing(velocity);! F, U, O) b& U! ~9 n! ^5 D) \
  67.         if(key_in1==0 && turning){
    2 L# v( V1 B8 d, S
  68.                 turning =0;& K$ _8 e4 J/ Y' T5 Q
  69.         velocity = (velocity + 1) % 3;
    7 K2 I3 J  Y) g$ k: J2 Q. m
  70.     }//调速度
    , q8 T! w: |! e3 z0 c
  71.     if(key_in2==0 && turning){1 x( A) O5 v+ \% p: |
  72.                 turning =0;
    0 {0 @+ F' r+ o
  73.         mode = (mode + 1) % 3;
    $ P  c* u. e# B
  74.     }//调颜色
    2 F; G! g# R' u- F: t' P8 U
  75. }   * ~: Z! d! Y8 P0 D4 X9 A

  76. & M2 J; b$ Z, O* j

  77. * \4 J9 X* ^* v7 B* c8 g
  78. void TIM3_IRQHandler(void)      //    //TIM3的溢出更新中断响应函数,产生pwm波' i/ A  R" d5 q, ?
  79. {% X( {6 @( {" W- k; G- o
  80.         TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //   //  清空TIM3溢出中断响应函数标志位
    . P$ J% ~4 i+ c! A, u
  81.         if(counter==255)            //counter 从0到255累加循环计数,每进一次中断,counter加一% @2 m! e$ D% I- v- v3 g% m
  82.             counter = 0;* N0 E3 A/ C5 h, I' C
  83.         else
    ' |. M. B2 `: w
  84.             counter +=1;: l7 j9 ]0 r! }: k# f: Z# R# A
  85.         if(mode == 0){
      C' H+ b- j5 V  k( q
  86.             if(counter < pwm)              //当counter值小于pwm值时,将IO口设为高;当counter值大于等于pwm时,将IO口置低
    ) v. b2 m! T& v: V) Q2 K* O
  87.                 GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1); //将PC14 PC15置为高电平: ~" I0 h8 T/ k. y/ E# h. l
  88.             else 4 k9 H) i3 g; \# K8 @
  89.                         GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);     // 将PC14 PC15置为低电平- p, x+ o2 z  a! B
  90.         }$ L, r: r" E9 {" F9 @) C
  91.         if(mode == 1)
    ) w& G& C5 R8 ~  |, d& Y3 p7 ?
  92.         {: d8 [1 \( h9 ~4 l0 T
  93.             if(counter < pwm)              //当counter值小于pwm值时,将IO口设为高;当counter值大于等于pwm时,将IO口置低
    & H. j& E7 ~) j# ~6 b
  94.                 GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2); //将PC14 PC15置为高电平* h, c% a' g& G! V4 z0 n
  95.             else $ @* Z6 t0 r6 s- f- e
  96.                         GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);     // 将PC14 PC15置为低电平) b( a1 ^! e" w" t
  97.         }  
    0 ~5 L! m3 k$ D1 T% U& s
  98.         if(mode ==2){, l+ M6 {( x# r# b
  99.             if(counter < pwm)              //当counter值小于pwm值时,将IO口设为高;当counter值大于等于pwm时,将IO口置低
    7 ^( ]1 x- v! O2 F6 v- E
  100.                 GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_0); //将PC14 PC15置为高电平
    " d1 O; B0 J+ \- u  R
  101.             else ) h% n, L  g) W
  102.                 GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_0); // 将PC14 PC15置为低电平
      c; D" f$ C/ A: v/ m4 x$ l( `
  103.         }
    + X! g  ^2 {7 X$ M: |
  104. }   
    $ _, S/ {9 _% Z- l! @% T
  105. 7 C9 B; j  M. r8 |
  106. ( q8 W' M- a' [3 r7 j3 t; c
  107. int main(void)
    $ \# L+ ^! {  B$ q7 |& u
  108. {
    ; h) t& m% ~. n& o( d: u+ o5 s* C
  109.     RCC_Configuration();                                                                    0 Q; [$ C( F+ x3 T
  110.   GPIO_Configuration();                         ! l5 O- R: b) r: y5 j8 w; J
  111.     tim4();
    , O+ [1 ?# x! G1 T. c# v  H
  112.     tim3();
    0 M5 f3 U% ]0 x$ C: Q7 E
  113.   nvic(); + M6 |6 Y* s3 n' R+ M2 T+ c' A
  114.     while(1)
    7 o( c9 b) P2 ~* m- R% z
  115.     {
    - ^5 o7 A* F4 m+ h* s# P
  116.     }   4 W" q* V- A9 V
  117. }   # S# z( `3 l8 z) A

  118. . W" \5 P, z/ `' j! W! K
  119. void delay_nus(u32 n)       //72M时钟下,约延时us
      e! O1 g5 \. R6 a
  120. {: ?" {5 b8 t! M2 W
  121.   u8 i;% C& C0 B5 P% A9 U3 M2 |
  122.   while(n--)5 U( l) S$ Y0 I1 Y
  123.   {
    % b$ m  I# u: U5 m$ O) J
  124.     i=7;
    9 g+ y# Q- @, [# W
  125.     while(i--);; l! p1 s7 T3 c. R6 i5 [( }
  126.   }! Z4 y! M# ^1 I5 t* _  W  I, F6 T3 D
  127. }, H3 V! k" u5 M" k7 v

  128. 5 Z& h7 A8 ^4 g" U# C
  129. - `" r. M6 V6 D+ @% {
  130. void delay_nms(u32 n)     //72M时钟下,约延时ms. J6 ~1 F' g; ]# M- }  I! b
  131. {
    7 N" H! D- Q/ ~- B
  132.     while(n--)
    % I% K1 v$ x4 T. R
  133.       delay_nus(1000);
    3 g1 U3 R7 r: S  x' V. @; ^; ~
  134. }
    ; T- w5 A1 q4 w9 H+ W

  135. 7 m0 q5 s6 w. P- n3 a2 ~' K( ^5 A
  136. 2 G: e, i) h6 C2 H; F
  137. void RCC_Configuration(void)                 //使用任何一个外设时,务必开启其相应的时钟
      ~; Q  @1 ]- x! C
  138. {
    * ~  R- |7 ^4 B: S  V
  139.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);    //使能APB2控制外设的时钟,包括GPIOC, 功能复用时钟AFIO等,                                                                              
    ( G9 u$ {) \( e% }" P& n& m9 s) Q! Z. R
  140.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4|RCC_APB1Periph_TIM3, ENABLE); //使能APB1控制外设的时钟,定时器tim3、4,其他外设详见手册            
    $ x* S" g* y; y/ d* ~, o2 Q- p
  141. }
    7 @! Z" l3 d; y1 }7 M1 Q

  142. ! D$ D/ `  Z! A7 y3 H, {, D% a, ]
  143. $ D& b' S5 S/ ^$ o9 Q! w) W
  144. void GPIO_Configuration(void)            //使用某io口输入输出时,请务必对其初始化配置
    5 x( v+ N* x3 e9 D
  145. {9 ~: }& a. P6 @8 |+ S" k" s- c
  146.     GPIO_InitTypeDef GPIO_InitStructure;   //定义格式为GPIO_InitTypeDef的结构体的名字为GPIO_InitStructure    ]2 ~: r4 r9 F$ b
  147.                                           //typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef;( z9 |1 N1 z6 w2 Y
  148.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //配置IO口的工作模式为上拉输入(该io口内部外接电阻到电源)
    0 @( F( x. W% l! v# f. y
  149.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置IO口最高的输出速率为50M
    9 Q. M3 y/ ?  R& i$ S
  150.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;  //配置被选中的管脚,|表示同时被选中+ t& z1 a& n7 t- k& F) N) E9 y$ @( y& c
  151.     GPIO_Init(GPIOC, &GPIO_InitStructure);                  //初始化GPIOC的相应IO口为上述配置,用于按键检测4 n4 W1 c3 A6 _- P  G( y$ w. F# |
  152.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;       //配置IO口工作模式为 推挽输出(有较强的输出能力)  ^9 f$ J/ |: U& A! I- w1 ~& J; C3 W
  153.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      //配置IO口最高的输出速率为50M
    * [7 s) d# c. ]. {  \
  154.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;  //配置被选的管脚,|表示同时被选中+ H0 s5 C  [0 o7 J# |
  155.     GPIO_Init(GPIOA, &GPIO_InitStructure);        //初始化GPIOA的相应IO口为上述配置
    ) d5 O$ Y( b1 t$ D
  156.     GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //失能STM32 JTAG烧写功能,只能用SWD模式烧写,解放出PA15和PB中部分IO口
    7 v6 i( J  u- R% p. a
  157. }  e5 ]% e6 o+ Z8 g

  158. 2 _$ X5 L. Z' w8 c6 ^+ E

  159. # G; W3 w* M- E) e2 y
  160. void tim4()                           //配置TIM4为基本定时器模式,约10ms触发一次,触发频率约100Hz
    " k4 r  ]+ g. A
  161. {- W- ^  V0 p2 ?! f) Q1 ?& v$ }
  162.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   //定义格式为TIM_TimeBaseInitTypeDef的结构体的名字为TIM_TimeBaseStructure  2 q- s* S1 X$ u% A8 z: ~) J4 {
  163.     TIM_TimeBaseStructure. TIM_Period =9999;          // 配置计数阈值为9999,超过时,自动清零,并触发中断4 W: b, L& z& X- j* J
  164.     TIM_TimeBaseStructure.TIM_Prescaler =71;         //  时钟预分频值,除以多少  D, M; Z( ]2 @3 x( M# {  S
  165.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频倍数
    + ?3 ]" R9 Y7 P
  166.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数方式为向上计数5 G1 K2 N0 [; p. p& x  r
  167.     TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);      //  初始化tim4
    / S  X% Z5 Q, w2 z9 k/ r; ]
  168.     TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除TIM4溢出中断标志5 ^" v+ H% R/ e# ?  i
  169.     TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);   //  使能TIM4的溢出更新中断* a' W+ q; m6 z% N1 m; ]
  170.     TIM_Cmd(TIM4,ENABLE);                //        使能TIM4
    7 L) H6 n4 w3 @
  171. }/ e- r& ?3 {5 x( l

  172. & }3 R' u6 B4 Y* q2 [

  173. 2 s0 d5 Z& O" l$ ~0 T6 U
  174. void tim3()                           //配置TIM3为基本定时器模式 ,约10us触发一次,触发频率约100kHz
    ) T: v0 `- H" A; F! k) B
  175. {
    . i( ^# q6 F" [3 g+ |5 {# o
  176.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   //定义格式为TIM_TimeBaseInitTypeDef的结构体的名字为TIM_TimeBaseStructure  ; x/ @8 \" [& y6 b' i& z& w
  177.     TIM_TimeBaseStructure. TIM_Period =9;         //配置计数阈值为9,超过时,自动清零,并触发中断/ x+ t" _+ J# K  u! f9 k6 q
  178.     TIM_TimeBaseStructure.TIM_Prescaler =71;     //    时钟预分频值,除以多少8 H- u) X8 Z: ]
  179.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分频倍数. j9 T% ?$ y6 n) `7 e5 Z4 |+ j* D" h
  180.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // 计数方式为向上计数( b  N, R* `3 }
  181.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);      //  初始化tim3  |, q. P/ a  E' Y/ c1 l
  182.     TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3溢出中断标志
    0 l3 y# D- m' j. W
  183.     TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //  使能TIM3的溢出更新中断
    ' }9 Z9 E5 {, u9 G
  184.     TIM_Cmd(TIM3,ENABLE);                     //           使能TIM3
    2 n( r9 y" ~3 f" O
  185. }' C' s: ]" Y7 m. K8 r! g- L
  186. . X4 I; e0 K% `9 P' m
  187. ) \2 V! J; R7 H) K
  188. void nvic()                                 //配置中断优先级
    : R' Y9 x2 g  [
  189. {    ) ^' @+ p4 P1 {
  190.      NVIC_InitTypeDef NVIC_InitStructure;  //    //   命名一优先级变量" X$ s5 \+ r0 B1 u: \* G$ ^# _5 }
  191.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);    //     将优先级分组方式配置为group1,有2个抢占(打断)优先级,8个响应优先级! _+ }; o9 k3 d5 R6 f0 ]
  192.      NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //该中断为TIM4溢出更新中断9 R$ C" m3 a" \6 |
  193.      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//打断优先级为1,在该组中为较低的,0优先级最高
    : K. ~% ~# M$ i
  194.      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级0,打断优先级一样时,0最高
    & ?! e1 Q1 D8 |, d3 y
  195.      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //  设置使能
    ( N. F7 t4 O5 \( O
  196.      NVIC_Init(&NVIC_InitStructure);                        //  初始化
    ' ^  b) ^0 j$ g) ?
  197.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //要用同一个Group
    6 E$ ^! b1 t! j# ?0 [# a6 P6 K: F
  198.      NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 溢出更新中断
    ( F% v* O/ o- h1 B$ L6 T2 `2 u
  199.      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//    打断优先级为1,与上一个相同,不希望中断相互打断对方
    ) I( ?4 n8 E" x: r1 Z" I
  200.      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     //  响应优先级1,低于上一个,当两个中断同时来时,上一个先执行2 x) \; R" t4 O
  201.      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  G8 {1 l: Z4 S1 w! z$ c
  202.      NVIC_Init(&NVIC_InitStructure);. H8 s7 `$ G4 z
  203. }
复制代码

* X* o+ F& p9 f

! }# B$ Z+ y- m# J
赞 收藏 评论0 发布时间:2022-6-22 19:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版