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

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

[复制链接]
STMCU小助手 发布时间:2021-11-8 16:49
定时器分类
' C* k% T' n  o4 g! v! aG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
% {  {5 ^' x; [( S3 ^0 z. L, f
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
0 U9 ^' ~! f+ Q( ]7 w
" B+ x! M) ^; Z1 X
20200505192122130.jpg
/ U' t( f3 n: Q- C5 ]8 ^
! a7 t6 K2 C1 k( b
20200505192148321.jpg

! Y! Q. r/ X, e' W5 F) u. y; L- q# K
计时器时序图$ G& l% t5 d7 v8 T" [+ |
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
' O, X+ z8 \$ ?% G; r( ?, i/ G  K9 Y; D. j% |
20200505193407758.png
0 u& @2 V* r5 Z$ }1 b2 A7 ?

7 A( z7 a/ z4 l. J+ v
20200505194318226.png

+ M6 Y: H: a# k% y7 @3 e, B
* `+ a. S4 E" X9 p 基本PWM模式,边缘或者中央对齐模式
4 {) {; I  }, T+ i, G6 O9 X$ s2 Q. M4 P
20200505194802587.png

) e( s* g( g9 [- Q9 o* u$ b5 h0 H  @) K' m
非对称PWM模式4 S1 \7 {5 F4 N. m) g

- P; \7 f8 Z) n& ]0 M3 I/ o# ^. J
20200505195057399.png

+ i; e% z' S/ ?: k& `) l
2 X* j7 `; R" t' e" s! W* @% t三相组合PWM模式" T) M7 T! q5 q. P9 `9 w
20200505195420730.png

- d, o+ r- e4 g; E# b" M2 `
4 \! B5 A  ~- G% @. D( k 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
6 U1 x+ W2 C$ _4 X( B8 _
" n/ ~  K( @; g
20200505195905197.png

, g: D) s6 J7 d7 X0 U* T1 u6 Q4 V6 x; F  B
TIM2定时器实验  l) h/ [# o5 t/ J
本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。0 D+ l7 Y9 k$ w2 D3 j% l
5 @0 p; l6 P4 L+ I; g; \
如何计算定时器周期?5 O& q& N: E3 f9 y; S
# z! |5 T& \6 K# r9 a/ c/ [
1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;0 B+ l; H" q% [$ E; d/ X
. E3 m9 W! v8 o/ f! }6 W+ w
20200505220029633.png

0 ~$ W& G' A# N& R+ v  p, D% w0 n1 v& P0 S6 d* d4 b, s" H
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
" \1 t7 X: u6 U' X0 ~: K, P( ~  g, E6 S
如 64MHz / 6400=10000Hz
7 ^. X, t5 J: L- f$ n/ E
" Z0 _# y4 S$ w. b) ]3、确定ARR的值,ARR=CK_CNT* t(s),6 W# l7 `8 @4 _9 W- m, R2 z. d
2 g+ W. B# x. T2 Z8 b$ _
如要1秒周期,10000Hz*1s=10000。$ U& Y  s4 y6 i; c
6 F% `( |( q3 Z" l, F9 L! @
实验代码
- k$ X5 }$ L) S1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
0 P% @9 y5 F% n1 ~, q9 u
" ^, }: V5 [; V$ p: I2 j6 S7 h2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
4 C2 V9 o6 ~- I# w5 P  }& Z% v# d( g1 P
; f. d( d# }+ x+ _- g5 H
20200419170920422.png
0 I4 K3 u( g7 B9 y  f
8 Z/ J( D: h. q4 n! K1 o/ y; S
20200505223426701.png

  H" l" {% o& v& y: W  I; t' [+ @9 V" s) l! K5 u
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
, Y' R  x5 ~( M7 ~5 N! @) k9 V
; P) W- \: i, Q0 t
20200505223701644.png

. P7 e& R% x: W! ?8 i5 J6 f+ s+ k, R. T7 C1 ~6 z# B( k. T
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"; T/ P2 }% f3 J% x

3 V8 S2 h1 D8 F- W3 ]" r' _5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
  c- S! Y. S& r( B: S# r8 p1 {. r! @8 f
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT1 [# @, ]" B, V0 W' C" G
. D: f) M+ i; p9 U; V0 @5 N) T
20200505225312371.png

8 N* f% v: [2 r" k
9 ^6 R# h3 ~3 K' d6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"# d- T7 j3 d5 G+ s0 y

: u/ ^; E9 Y5 a  e: F, m  g
20200505225419137.png

* p, `$ V9 {0 I9 ]/ X% E8 m4 A6 t/ [6 Q, \  b
7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。* {( V+ S, E" |; {' F

3 L) \% F* ]$ Q, n
20200505225614187.png
( E% d$ }8 o: t* l
9 H4 t1 K7 l+ O! g' N4 M0 Y) i- z
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数& F2 _# k# G1 m- \% @* l

8 @' M3 d$ T4 u
  1. int main(void)
    / X6 K9 A: R& S2 X5 g4 N- o5 E+ ~
  2. {
    6 k5 p1 W/ j5 `/ \, }* s( m& I8 m2 e7 P
  3.   **
    . ~2 K# \0 I7 `& U6 S. h# U
  4.   **
    $ O0 b" v& i! @3 d0 A: N
  5.   MX_GPIO_Init();- W0 a5 ~* \& |
  6.   MX_TIM2_Init();0 B. E' U# ^% R# d
  7.   /* USER CODE BEGIN 2 */
    ; E# i/ X" j& Z: T9 F: |7 c
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    2 O: t2 x0 S/ H. [
  9.   /* USER CODE END 2 */4 A) B. a4 o" e/ b8 f
  10.   **
    ' l9 ]+ G, m' ]6 F5 _) P
  11.   **
复制代码
. |3 ^- n+ z1 d3 Q9 x" C
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
# K: X2 N6 r  M& v- v% ^
8 p% _) u6 i* E2 B$ @7 O6 s7 e
  1. <span style="background-color: rgb(255, 255, 255);">/</span>*
    + H! m3 E2 j8 i5 T0 e
  2. *stm32g0xx_hal_tim.c
    $ F+ i3 [/ O$ t( F7 M4 [
  3. */5 `/ U0 t4 Q0 c8 Q$ x2 ~; p
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    , x# ?/ [# G# k
  5. {1 V" t; u' _) ?. \
  6.   /* Prevent unused argument(s) compilation warning */5 `# C2 c" q! Y: m; N1 P
  7.   UNUSED(htim);
    : V3 V. U: m8 K, ^) |( b: _5 h

  8. 1 I/ L" K: A" d
  9.   /* NOTE : This function should not be modified, when the callback is needed,6 E0 }9 a8 d  _
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    : U5 U, |" r! f  t1 a
  11.    */
    0 x1 R. {* l2 ~
  12. }
复制代码

; b4 U) R6 e, C5 ]+ ?10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。$ P4 Q( a6 h7 O$ f) t4 g0 _4 j

5 ?( {8 Q. u( K- ]& w2 ?4 l% q
  1. /* USER CODE BEGIN 4 */( L; E8 ~2 F7 ^0 X) h5 o. a
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)' d% @6 F, s4 n
  3. {
    ) U$ f7 w) k  L, Q3 {( j
  4.   /* Prevent unused argument(s) compilation warning */
    6 W) d8 x0 w* C" H6 |
  5.   UNUSED(htim);1 [5 T' A4 X8 T5 f& g9 n
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平7 T3 U( n. h% u( g6 t: i/ ]' [
  7. }
    # T9 n3 B3 o" g' W8 o& K
  8. /* USER CODE END 4 */
复制代码
" x/ J1 ?- P6 \) }. O/ F

/ a. A# `( ?' `$ \& B+ J+ V" W; @, K6 y, U8 K6 M% n6 ]
5 ~, r: M5 l& v; Q4 t4 ^/ P
0 y% @3 k' E3 B
, X0 F7 U4 P$ z7 ~! v

( m& N' y  C$ g4 M: P
20200505200041645.png
赞 收藏 评论0 发布时间:2021-11-8 16:49

举报

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