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

【经验分享】STM32G0学习手册——使用定时器中断(HAL库)

[复制链接]
STMCU小助手 发布时间:2021-11-8 16:49
定时器分类
- A& h% [/ B0 N9 uG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
4 l4 E7 r  J8 Q& i0 l, f5 u9 w
$ |' V: R1 k/ L其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器' G4 T0 ]- L* F! \7 ]5 H/ G

  w7 d, {& q5 b* z; Q. i7 I9 P
20200505192122130.jpg

- r& D0 E: x( x, v
% c, N* Q% {) N- Y7 ?3 ]. K. m' v
20200505192148321.jpg

6 x$ e( H1 I: S$ I3 M4 Y8 ^; s0 D8 g/ k  w# d, X
计时器时序图( S) \2 R3 j( T' g
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。6 P* j# Y6 Q  I
& X4 f4 k/ W: I1 b
20200505193407758.png

$ X  Q+ f/ n8 \8 M+ b: {2 R3 O' p3 z' w  ~
20200505194318226.png
0 `6 u. d& Z/ T# a( T

- _% ^' N7 r( k+ T0 L' o$ v/ k 基本PWM模式,边缘或者中央对齐模式
& @6 q8 ?5 r+ `+ f# M) v* R5 c* Z! ]$ y$ e
20200505194802587.png

1 Q8 r9 j( e8 C8 i$ u3 H; M4 D( ]  p. k( l, z7 {* _
非对称PWM模式
2 N* i5 g2 O7 U- e, K+ t# r. k4 I' u* F2 X$ d$ p
20200505195057399.png

! d2 p! @$ j7 \. Q) Q
& i- l: e" p8 k( A; L# ?3 f4 t三相组合PWM模式' M% v8 k& Z9 w5 o3 s6 e! F
20200505195420730.png
! E) w2 P: }1 }( b3 P4 ]: B; M
) o+ z. C5 T3 o5 K7 {# U" f3 q/ Y
可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。6 i; X$ K- W+ K6 Q; R
; G1 n9 v- F, L9 G% W
20200505195905197.png
1 s, D% O& Y, e5 s4 c# ^
! p1 B% U1 s. q2 J# z- p+ W
TIM2定时器实验; S' y; p  D% ^4 j* |: ^
本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。
: Q1 ~5 N4 o8 Y8 G! E* Q. Z+ L1 q& l* D. [9 N( O/ q
如何计算定时器周期?0 ~# |6 w, K& C/ R& F. H5 }/ u) ~

6 u% r6 m5 H9 F' Z3 r3 W1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
$ q# l+ |/ `) J; M0 G8 Y; @
) q3 t9 S$ y9 C4 |( S
20200505220029633.png
% i5 K5 t  ]' ?

) ^# [4 r3 ]6 n# m2 e, `5 ~2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
* }; d% f! D0 h
  [: _% l7 a; g2 O4 q2 x如 64MHz / 6400=10000Hz
4 q9 o# e  `- H& d7 C4 l- q3 ?0 Q( \2 @9 m- Y
3、确定ARR的值,ARR=CK_CNT* t(s),
) d# o3 }- x: q. ~' K
8 [3 L0 w: }* f5 L1 X- F% X5 T: p如要1秒周期,10000Hz*1s=10000。1 h* w4 N/ C9 B/ ?7 N

# R0 c- c/ s' o, Y8 v实验代码
2 f7 B( E7 G/ z' S  K4 d1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
! D% Z/ R. D) `1 _7 p" U; B4 A3 G8 S2 C7 p
2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低1 {2 N' g9 t% x$ E
8 v1 ]$ l, _7 h% d0 T2 J
20200419170920422.png
& `" b$ d2 k( |& `
% S; A, w, N% G* f6 S
20200505223426701.png

7 W* |8 [  n! d' @5 V; g; e0 M! K( S) T( r# L+ b) F( O
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
2 P# P/ ]5 t9 [. Q1 ]3 F, v- `$ A  `& c
20200505223701644.png
1 N9 C& j2 H) r3 g, k9 x

1 ^1 {0 s7 |- E4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"4 F. o' ?+ f% c3 [0 R; n
( h! S4 @0 E. h* M& r* M' ]6 R! a! d
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
5 m' E% l( `, d% q, H' S3 T0 u4 r/ A
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
" [' j8 R2 y* P+ L. k5 ^7 E7 t; \
20200505225312371.png

  f$ m% f. t* W# i  O* T: E) Q: A: A/ V
6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"8 U' g, ?3 F5 c$ G# U
# y. d- K% n* k4 w& v& X( N
20200505225419137.png

: [9 p6 m2 Q  z, q* N, r; F- I) ~; l( U1 Y' q/ B/ N
7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
+ t# m7 X$ ]  X
4 G# r/ y4 s) v8 L& ^
20200505225614187.png

  J3 k, k$ c1 g- t
+ {& C% _& m3 H+ j' V8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数1 }7 S" P; h3 R/ u2 Z5 F

3 J% i5 J7 C& M3 V1 y" E
  1. int main(void)
    2 L7 B* v' l) i- h: r! k, `9 J% a
  2. {
    . X, W) z& ^' T5 N" u
  3.   **
    4 F: h/ L5 U5 W& T* }' }4 n
  4.   **( |# ~% @4 K/ I
  5.   MX_GPIO_Init();
    . `: f, U3 H# V. ~* U7 R/ L& V
  6.   MX_TIM2_Init();
    ! L  ~' O" t( |0 r) H& E
  7.   /* USER CODE BEGIN 2 */* v* c" y; P8 y2 k5 z
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断: Y$ G; s/ k# k& y+ v2 m, L
  9.   /* USER CODE END 2 */$ m- {' L4 V, H$ [
  10.   **
    0 g7 o) z9 v* [$ e5 h* I% X9 K
  11.   **
复制代码
. M6 w1 P* d$ e
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中( Q$ C, z9 K  L  k

% |3 x/ S( \5 T( u; ~+ c
  1. <span style="background-color: rgb(255, 255, 255);">/</span>*3 Y- d% \( c' F" M
  2. *stm32g0xx_hal_tim.c5 [) q/ Y. I0 J7 H, i5 `( J
  3. */( C4 d- m5 |0 V: {. Y0 n3 [/ @% O
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)/ y& t4 ^8 ?7 h4 G/ I5 z
  5. {7 e! w2 M& X& |- s7 L* V7 Z
  6.   /* Prevent unused argument(s) compilation warning */
      c# ]8 _: Z1 u& n
  7.   UNUSED(htim);# Z8 K" o- E$ n+ Y, y
  8. % _! g( q* H: B: M* }. L2 D
  9.   /* NOTE : This function should not be modified, when the callback is needed,  R: O' g5 h$ G% c
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    # n: W" a2 }9 v3 W4 r" p/ ?
  11.    */
    2 W0 A6 w# W8 d7 v9 ]
  12. }
复制代码

7 b3 Z' D. Q; ~2 ?10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
2 q6 K* G6 S& M( b5 m8 z2 G5 M
7 Z! ~7 @8 A5 ?4 M! y6 n1 N
  1. /* USER CODE BEGIN 4 */# o: S2 g* Q! l5 r
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    9 ?  d- A7 a: d' Z
  3. {! J, ~0 D1 Q3 M- |
  4.   /* Prevent unused argument(s) compilation warning */
    + |/ i& w* @  ^# q
  5.   UNUSED(htim);+ E8 b; Q; b8 r2 [
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    : ]+ B9 T, k- A& \% E; v
  7. }
    7 T- H* r" `4 `8 d& E
  8. /* USER CODE END 4 */
复制代码

- s1 k/ h5 J" B" P+ p2 m* @) V6 V9 R8 d1 m1 l- u4 j. C: ?( E% k# c
- Z7 S% H+ i% R. C9 F
, v0 a! F; o- n) P
8 O" O1 h/ K' P. ]- c) s
2 [2 M  G  q# _

6 M& _7 b) r+ x
20200505200041645.png
收藏 评论0 发布时间:2021-11-8 16:49

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版