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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类6 W) k: D/ \# O! _/ j
G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图5 T1 ~; E3 K# H) H( \
- N0 `' V8 V- x2 r0 F- I3 a3 U
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
- A% j. F4 V& [0 q9 v8 Y% ~( c. s/ g, _7 P
20200505192122130.jpg

$ G1 E9 M; L. ?" _
! ^  [/ Q6 }" i+ c+ f3 A
20200505192148321.jpg

) y1 L& K& n( e; K, x6 G
' g+ @9 ~& s3 w 计时器时序图

* m6 Z6 ?. M  Z0 q# S: TTIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。, ]3 L" {. J/ J% {  D
5 x% @  j: x4 a2 ~1 g+ k3 k4 n
20200505193407758.png
; G1 ^* _. g: v3 L1 E. I$ _
  G" C2 [) x4 w: u
20200505194318226.png

; N2 n8 p$ o9 Y! {) t" t0 g4 V  w! Y2 Z
基本PWM模式,边缘或者中央对齐模式7 I" J6 p. D8 i0 }
& I6 S1 e0 P3 ~2 q8 i  n
20200505194802587.png

7 V* K0 E2 J* [* \) k! a( V- e. s. x, D( C
非对称PWM模式0 m  q) y, ?* E6 Q3 f
( @3 K- `, g# Z/ M. H# Q* u; D- ~
20200505195057399.png
- G2 F5 e* p) w3 W0 t' S
$ F: y& H9 E. Y4 M( W, X5 x% }
三相组合PWM模式
5 S( [% N( @# w, x1 }
! P/ W' e, U) K& j) ^/ L+ D
20200505195420730.png
/ `' C7 W5 _' P1 Y- y

9 ]' ?' q% e- b- P! ? 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
) f+ u4 i# I( G4 r+ a4 Z! q0 i9 r; F2 F$ v
20200505195905197.png

& v- i7 `6 Z/ w* ?% A* S, ~2 Y. m0 |6 }
20200505200041645.png

- u0 n' [* G# r# G. }- z! n  U) h7 Y* `  W9 ?5 T
TIM2定时器实验
) u' Q9 T, f: k" x本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。
8 D! X9 p$ i6 [( e: R' `' S6 {, ^; t" a
- i# P/ i- E, Y, {4 S7 ?如何计算定时器周期?( u! L3 ^+ D$ B! S

+ i$ E) _+ G( Z# Y, A9 V1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;6 h0 ]' `# k8 B' b
; v3 c4 ~  g7 e
20200505220029633.png
0 e) ?# I6 `; e: e
1 ]. _/ z. a; H, x7 |& L# }
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,- E5 X0 l6 P2 ^  q
) K/ N' C6 Y, l, V: F- m7 A
如 64MHz / 6400=10000Hz: m9 P* [4 c  t  J% o6 m
# @  a9 o4 h# l. V
3、确定ARR的值,ARR=CK_CNT* t(s),: y5 X% _, v( v9 K* w- _

7 v, R- T  H! |/ V3 U/ n* ?- e如要1秒周期,10000Hz*1s=10000。
: o, \1 K3 V8 S' o5 T% w: q; o1 C& E8 }9 n+ L# q
实验代码
+ q6 R& V, [) g) h6 W% i) w" |$ i2 `1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";! R6 A5 {$ d  w4 R

5 {6 l" w0 }8 V9 B$ v: y/ k+ K2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低) P3 L) X+ f* z, v* R# ~4 R
( r( q' n  _+ c8 x$ ~2 ]) `+ Y3 l
20200419170920422.png
- e% l: o0 ^5 j% I, ^9 \0 ^1 M

: K' U6 k% a$ i0 \) p# s) c( p( Q
20200505223426701.png

5 v9 K( l. n: Y3 U4 l( e% p2 P: H8 I: q3 w
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为645 `# [  C. D% U5 `3 L
% u+ B& _# Y0 C5 c
20200505223701644.png

! {' n8 j6 O/ \% O4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
0 }: H. b& U* t6 D: x
( u1 z9 y3 c4 ^0 L. |# c4 ]) p5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值! [% g4 v7 n& K9 C
, b" i0 ?$ o. h. C, ^6 L4 n
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
, M; h, j5 Y0 f7 d7 |! O# V' F7 |  Q5 o
20200505225312371.png

2 e9 S3 P5 n9 i% a: t% B, g4 w5 q6 W6 |( f
6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2") L$ X/ e7 t" w

- Z5 x5 d$ O# B7 [: x
20200505225419137.png
8 ^7 r2 F% k" O/ f

- ~# M  w- v* A2 h$ Z) a4 v0 E- s- W7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
* T7 N( F. s. U+ k
. H2 f* A% v* B
20200505225614187.png

3 y; z! V# O5 V/ |/ x' j3 Q2 Q2 w8 u% _' {5 b8 M' E, k, e
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数5 j) u/ G$ W# G5 _: K8 H
( O7 r7 M# ]; p( ^9 }0 M' _& H
  1. int main(void)
    5 |1 ^9 {  V+ O" d) [3 k3 n9 A
  2. {: [6 T/ U7 P% H
  3.   **) g$ p9 ?# e% D6 a6 Q# t, I# L
  4.   **3 f4 A' Z( M1 q2 R9 ^. l
  5.   MX_GPIO_Init();2 x3 a' D1 v5 C# |/ R
  6.   MX_TIM2_Init();
    5 E  w& d8 l) s3 J" k" R
  7.   /* USER CODE BEGIN 2 */; l# N8 q5 P' W5 W- J' |
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断# s! w" L- T3 L3 M
  9.   /* USER CODE END 2 */- B$ B3 g( ]. _
  10.   **. O4 F1 P5 x: `7 G, ?$ x- n. A+ K7 T
  11.   **
复制代码
7 K: k) L) {) y) T
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中" y+ D! ], n. D! \/ y; O/ g
* C; g4 [1 u$ X6 p: T
  1. /*9 E% v" Y* D2 z" ]  t9 v* X
  2. *stm32g0xx_hal_tim.c
    + r+ h* c' u" H1 A8 T; F6 K
  3. */
    2 N& x2 e3 g4 y3 g
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    ! c9 a  ]; @: V; o6 z/ P6 X' N
  5. {; F: e( b$ A5 @% b6 s
  6.   /* Prevent unused argument(s) compilation warning */
    : d4 {: |6 p3 K* ?$ `
  7.   UNUSED(htim);
    ; J( G8 t7 S) \! w3 N$ T6 v
  8. 9 Y. f/ U6 i$ a0 X& A
  9.   /* NOTE : This function should not be modified, when the callback is needed,
    " P9 R0 Z% D3 w
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    % ^9 B" v7 i' N0 k" G" l
  11.    */2 h: K8 x. }" `# |+ f
  12. }
复制代码
7 g9 y; @8 W$ x( i
10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
0 t6 ?2 e4 C" Z9 x" y/ ]6 R1 @4 f. W$ @# C% x  L
  1. /* USER CODE BEGIN 4 */% K6 w! ~  ]: L9 p8 Q
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    - ^. I/ y1 o( X0 v, j  @4 g: ?9 t
  3. {: ^4 b# ]1 T6 b6 z# U  v7 L
  4.   /* Prevent unused argument(s) compilation warning */
    $ L4 _( q9 @: |+ N& P5 L
  5.   UNUSED(htim);
    # V( W/ p7 N: T' Z% ]  Q/ k. ~
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平2 C7 m* `$ i- p1 L4 p. o
  7. }
    & L  i( b, p/ l- f, B
  8. /* USER CODE END 4 */7 w& Z4 i; G: \- I

  9. ) V5 t. _6 v5 d0 y8 B
复制代码

' T- S4 Z  Y" o. U
收藏 评论0 发布时间:2021-12-9 11:21

举报

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