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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类
9 P/ n0 W9 @6 t2 |' b( KG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图' Z) x. D' h* a

! S! R0 u  Y2 {$ w2 L其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
4 F" O7 x% z- b0 a; m
/ }" p7 }( l! c2 S
20200505192122130.jpg

3 @+ G/ r, ]  T- Y& p' S4 C
, m! j, V. C) s0 e2 I% k
20200505192148321.jpg
, W/ g* a, g3 V- R& [
5 H8 h  l! b9 I& g& N7 `
计时器时序图
' D+ x) O9 D- `0 M+ D
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
3 ^& t! u* c) T+ D% j. o. h+ q/ s& i
20200505193407758.png
9 {1 i& `5 h: X& Z7 V
# T7 L! _6 f( P& _0 H
20200505194318226.png
# B, w- f& u" S. @( j9 p: }

4 ]# v# G6 t4 C 基本PWM模式,边缘或者中央对齐模式
) X3 p# I% a$ b0 j# T8 v& n* m$ _5 a# z0 a: v* ?! l( z7 a
20200505194802587.png

. [, B' {0 w4 r1 i1 L% Q% l
9 J  L) {+ r: P8 E 非对称PWM模式
, v# _1 t. ?' @( P8 z, v7 t" W3 p! w. o/ T0 t- p
20200505195057399.png
3 E7 q) r' [# E7 Z, j* q

! S" s7 P, {, B4 b) O三相组合PWM模式3 s* d8 _! N( @
4 W4 W6 r5 D; @$ d3 _$ R% G% S/ P9 K
20200505195420730.png
1 |; f4 O1 f3 z* A+ S) T' ?2 D# f

; q6 S  O+ O6 U8 o- W: | 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。$ `9 K2 J& o) L+ V
8 u% y( b6 N0 O( b! g* s8 i3 w" y
20200505195905197.png

5 i7 R; J5 g* |# p" [; o3 I8 P; E4 y" N" B. f
20200505200041645.png
. P: n% z; d7 G7 M# P2 [8 q
3 F4 B) z4 s' {8 Z* i
TIM2定时器实验+ ~" c% a1 z5 H9 ~3 D
本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。( l7 @: r$ Y! D5 C& V' V
/ F( W# e5 V) C4 g4 N  L8 L$ \. D
如何计算定时器周期?
) H4 K; W7 C3 }3 t
' ]" Y6 T8 ]' C1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;; T/ u+ b1 f  R" h% M
; s# r1 Y2 U2 q6 `, h2 D: V/ W
20200505220029633.png

9 j* E0 L6 I( Y/ L
5 G6 T) q# [9 Y, i- |* D) x2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
: G  H- b" z4 G+ ~
% m& A7 u$ w; R) o+ z" q如 64MHz / 6400=10000Hz
: x* m3 v5 p0 ]) b
. b1 ~7 P" G5 ~8 T3、确定ARR的值,ARR=CK_CNT* t(s),
# e( P4 S/ E! V5 C  R8 A, d: I* I/ F
如要1秒周期,10000Hz*1s=10000。
% d% R% O" x" J1 h- H6 r- L" l# ^  F
) ]- j& m: i5 }" p1 H实验代码
+ B! l* ~- ?( N' @% h- W1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";$ J2 V5 k  B% g7 U3 b8 A

6 M: D9 E0 o0 E! X" R( ?, n& b) [2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
* R$ Q8 W  ~6 z8 Q) F1 }& t$ t  e* J2 A* s. C: l2 w
20200419170920422.png
/ g: H- |4 D+ r
: P* Z- D) s2 [
20200505223426701.png

' t4 `% L0 b3 c! c- P) X) J' }9 i; d  z( u. p
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64+ e: l( V2 U3 q9 Y3 l/ Q: V+ \
& o9 @; @5 O1 z5 g
20200505223701644.png
) M+ |& U8 }3 m: x2 f4 n
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"  E2 g' P: n7 q
* Z+ |7 R! B% q
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值' d% x$ t5 J( i; x) L$ p- j

. w  U& N' D1 |. C如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
4 W# V! J2 n7 a6 l# m9 t8 F, r0 ?) ^# [. x4 d" V$ G8 s
20200505225312371.png
9 h& i  E% v8 o( `) L

5 }) m; T5 `) D0 u; z: O6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2", H+ R5 v1 {. L( S! a7 C

! _' T' Z- |7 D8 I4 i. @) G9 R+ R
20200505225419137.png

9 O, ~' v. [. Y$ y& X  S
# R; O, l+ N) H0 l! N7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。" S. S, P9 V( a* p  l1 m* x, Z
" \) `6 A2 F& y- u" m, {
20200505225614187.png

8 J- m* z5 O, _; w; a& I
5 b* ?( Z! ?+ J: a8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
5 e0 m- z& e8 o. g9 ^
+ S7 B7 |: Z: x6 s$ @
  1. int main(void)
    1 e5 ?! ~4 O" N$ t4 w
  2. {0 b7 X$ Y/ ?- @
  3.   **  S4 ?- R; T% ~+ V, ?
  4.   **: g* _' \) ^5 z/ \% M/ |& K" l4 k
  5.   MX_GPIO_Init();9 O% S0 Z; A/ c5 x: }! T' u
  6.   MX_TIM2_Init();
    - C) ?3 W1 D- A# O. q* L
  7.   /* USER CODE BEGIN 2 */- c3 y' L+ A4 w. `; O1 b* @
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    5 L6 w! d! P2 ^
  9.   /* USER CODE END 2 */
    ' n: a3 d+ `8 h% T/ K: H& s6 p
  10.   **; r; O2 f  ?2 z; z% v. m* Y$ S
  11.   **
复制代码
: U6 u5 P+ D" t: j6 j8 m+ N
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中+ c& P" h) l3 d4 ]2 R' l
5 }4 D; x# B( }6 t$ `
  1. /*' }4 @9 K: k# J  ~+ C% L0 i: f
  2. *stm32g0xx_hal_tim.c
    7 t- K# W& r/ D4 }/ C1 J; @- j
  3. */
    1 t: k: w% U  E& \1 |2 r0 B9 W
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)$ Q# d* w/ k! q5 p- ^9 ~  n
  5. {4 N  E8 J- B; k5 o, Z
  6.   /* Prevent unused argument(s) compilation warning */+ K. g. z' _& d; e/ _7 M
  7.   UNUSED(htim);! v8 {; U1 C1 @1 Q: ]  c

  8. * Z/ q1 ]! {+ C, f6 [
  9.   /* NOTE : This function should not be modified, when the callback is needed,+ k9 O, p- {* z  H- I
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    8 c5 i% u% k# O- X
  11.    */' q  o" t8 E# q' P7 ^5 r/ @5 c: r2 u+ j
  12. }
复制代码
, w/ f3 Q4 I+ v* A' \
10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
% D9 o: {0 z% h# A8 d- N
* A2 l- z/ r0 R7 R; Z8 j
  1. /* USER CODE BEGIN 4 */" I0 S9 N2 T7 W7 _, r/ _/ X4 _9 _
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim). c8 C+ S5 u: b' [) s( f5 K  e
  3. {% u# {& B  o: l8 `$ R
  4.   /* Prevent unused argument(s) compilation warning */+ n" c' K* ~6 {6 e
  5.   UNUSED(htim);
    " w; k5 D- t! o) ?9 @5 y, u5 v
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    / E$ T1 @, X( C1 e
  7. }* w. V% O+ m7 F% g
  8. /* USER CODE END 4 */# |; d& T. k7 D

  9. 1 \( K# ]( A6 y! r' |
复制代码
6 O: [8 T1 o+ a! [: w
收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版