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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类- X  U' D" h5 L+ v" {* n9 A
G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图1 M! O$ L6 u* ]2 M8 m# o3 C
: \" J3 A0 k+ |6 f# j/ Z
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
: ^& n7 U" C7 {. j& R% Q/ I5 E5 S6 ?4 \# z* n$ O4 G
20200505192122130.jpg

, H6 y9 U! C7 L/ D" L1 Y. _' a) g0 `( f
20200505192148321.jpg
4 r! u" }9 F; j1 R

$ t( R; D/ e- O 计时器时序图

4 S7 Z1 m: G2 h7 q, v+ Y) KTIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。8 R) Q8 W6 R) M! D! u
0 \4 \! k2 S8 N" @& t
20200505193407758.png
. f$ i, V  C7 _! V2 n

( f9 L  S1 e. ~- Z' K0 H
20200505194318226.png
+ g" l0 P* [4 \8 |
% A! j9 p4 t4 N( M
基本PWM模式,边缘或者中央对齐模式
' }  Z: A  N1 u2 A* H7 U1 R: N& l; \/ W/ F
20200505194802587.png
& ?/ B" W) d5 q( [

" Y3 S9 q% j1 f) Y 非对称PWM模式
- u' H+ `! V( i* t1 [. j/ x* x
$ u8 [! B" E$ w
20200505195057399.png

2 d, }) B" d' i7 A& \2 u% ^/ X4 ]2 j/ U' n6 ~* B
三相组合PWM模式
/ u+ l8 Z% Y; ]5 G4 B0 V3 A
4 i9 r& l8 Y+ L7 @& Z
20200505195420730.png

% ]/ l- h) J) [3 A! v
) \$ T4 c  H) ^% V+ B) @- y6 O9 v- ` 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。1 C2 W) T' g4 x, X" K# v' [5 P
$ ~# w  F. A& c! N' Z
20200505195905197.png
: |+ _9 d2 j1 j: e1 k

( m, t* v& ^; L0 {. O) m8 P
20200505200041645.png
. x! ?4 n0 b% Q, O

2 [  f) C; t' V3 Q TIM2定时器实验
3 Z7 m) m2 Y4 f- V本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。6 S! R/ O2 @# q5 k2 ~& f

1 o: n8 {3 R3 X/ `如何计算定时器周期?' d$ @) Q3 @" `# I  N1 x$ N$ r4 C' V

. |) y$ l7 L  x, `0 n$ L, r( m1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;( U3 m  r' L0 u9 [& z" ^' ]+ V

6 d5 L, d5 h6 @6 v9 _2 f! f' s
20200505220029633.png

: n# z# s# q- z0 r+ H# w5 \* G
% }5 J0 ]: y+ e( \2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
' w6 Y$ U# d$ A3 z. X) w5 p9 M
/ X* b* A) n' X" c6 x0 q如 64MHz / 6400=10000Hz' O* c  p* ^' Q; A
4 y) |' D. C* H, \
3、确定ARR的值,ARR=CK_CNT* t(s),- O- [$ w7 ]# u7 P- h1 l

( ^' y1 i7 s/ z+ r0 G3 H% C如要1秒周期,10000Hz*1s=10000。& f1 Q3 Y  U' i3 M3 n* C- h) @# B
1 R2 b' N. C: d7 |5 ]" y- s3 F
实验代码
2 ~) e8 \5 m: G1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
7 C" D; F# ~7 U7 d- z) I$ Z' N0 v% L* c: B) t9 F0 ^6 p, O$ ^. J
2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低9 d9 a1 O) C6 X4 R1 p

6 j- ^9 V% F+ M5 Y% t- r
20200419170920422.png
$ S3 a& d  K6 ?- S
, e( {; G- |5 d: [8 g7 K; X
20200505223426701.png

+ e5 `- A0 D" F! i
5 N3 F7 w9 C6 H3 I& l3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为648 C2 P3 ~: P7 o+ E4 m; E

& t& n% b+ Y* o( H! h
20200505223701644.png

( N/ D6 n  n% Z/ I+ Y4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"1 X6 s7 b; H( I, w
$ s7 ?5 j' b: X1 D* H
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
) f8 T$ e9 i% T8 ~5 X+ e; p
7 p' |. N+ s" U& G1 E4 S如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT9 {& n0 S. N( ^* {" }/ `6 c- _' m
8 T' b: Y* M& l! T3 F5 k
20200505225312371.png

. D# f: Z' R8 n' a) L
& I: b: G  `2 W/ r; J0 N! V6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"
: x# i( j+ `. w8 s' j  a' _3 f; ]3 Y) K1 }, v8 j
20200505225419137.png
% D: u8 d' T4 ?' G8 j

8 n. g$ y9 e' `2 l. f* `3 L9 C* P# I. \7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
& Z6 Z9 ^" p) j) |5 {% U) x  t4 @
4 K- z  S. D) }) b. k" G) _
20200505225614187.png

- J3 i0 z6 s+ G; ?7 o6 \6 P/ I" }6 _# K# b9 T( F, T: B9 e/ n9 \5 F
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
. r3 Z8 X4 z# {2 N7 {) B3 u6 o6 A2 H8 s
  1. int main(void)
    # t5 d0 R: e8 ^( r% G+ L
  2. {
    8 b" W  b! c+ T2 V
  3.   **6 D; Q! N& |1 F/ @& g; G  }
  4.   **
    7 ^/ X4 w1 T  f5 v2 W8 s' M
  5.   MX_GPIO_Init();
    " p/ F& ]2 @5 \$ G
  6.   MX_TIM2_Init();
    4 i0 Q) }" q/ j
  7.   /* USER CODE BEGIN 2 */  T# v7 K' X8 L  p0 s
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    3 }, C- K$ f0 ^  k4 W5 f# i  E
  9.   /* USER CODE END 2 */8 _. l, e$ D- L8 f  s" ]
  10.   **, L7 i: ]+ `+ K- ^
  11.   **
复制代码

2 G) O+ [$ Q* o0 n+ F) v! L9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中8 v' w* c3 j+ _3 V, y7 y# ]) u' ]$ F3 Z

+ ?; r1 |. t% N, C- v, h
  1. /*" A4 o2 k' a9 O6 O& ]( T7 R: S
  2. *stm32g0xx_hal_tim.c) w& \+ c0 m+ y. r! L
  3. */
    1 q) b1 y* m5 I8 A2 t; D
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)- Z; o6 s' J) M) f% C2 ^
  5. {6 ?( G/ w/ E2 A9 @3 b, j
  6.   /* Prevent unused argument(s) compilation warning */& v, i. m8 x  [2 F
  7.   UNUSED(htim);! i( e& o" v; q! P2 ?4 @
  8. 8 P" o1 g* k0 K5 @7 @) N. r
  9.   /* NOTE : This function should not be modified, when the callback is needed,
    ; \# a& F! f# A; @
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    + O: q9 P5 C, I2 D+ s% c% x
  11.    */
    ' k# @" K4 P) n# O! @" D" n$ I
  12. }
复制代码
8 @/ u3 B. k% m/ h3 u/ p
10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
! x' V) u) V9 j5 [3 h8 Y7 u4 \# Z& s8 o/ [& m7 l9 o
  1. /* USER CODE BEGIN 4 */
    . Z! u: ~+ Z% l5 G8 u
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    / r+ P5 A! ~, H' U8 s2 E) O
  3. {) c+ X0 Z$ s$ l  S5 w# @
  4.   /* Prevent unused argument(s) compilation warning */) B+ v/ V6 }$ B* e" N
  5.   UNUSED(htim);4 \) u8 P5 o" l  H" B
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平0 \3 w7 g) ]) S- p
  7. }4 z& ?/ H' |* N
  8. /* USER CODE END 4 */
    ! w. F* T5 o4 j7 w  O
  9. 0 J) [* Z% x( \  V
复制代码
! ~  |/ o; `. e  i6 J8 Q$ U
赞 收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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