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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类
+ A/ f1 K) D  x% l& @& p+ YG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图. s$ `" B+ q9 ~2 a' q1 d# y

5 R' M1 J$ x6 C+ W: G其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
' v; o* _" Y' M4 m8 _8 c/ w
2 ~6 B6 R4 L8 d" n; s/ o+ Z4 S
20200505192122130.jpg
  A; P7 ~/ M( m* K/ G, I- _' b; V$ L
2 H( o6 N" x- ~1 }
20200505192148321.jpg

8 N: L8 ~. G2 o! G7 ?; f2 Z1 r6 I& F1 n  [
计时器时序图
  _' o$ R! M3 j) n
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
' r4 m/ O* _# R  |1 K# H9 o) z# k# N! ?( L, ^( K7 S- J. H3 U
20200505193407758.png
1 l6 I% ]% A3 d# X6 {

2 c1 s5 k) m$ r' m; z* E6 I; T* M
20200505194318226.png

8 X2 g) V$ f& L: k; [0 t' E3 J9 g7 z' S' e4 Z2 k# ^
基本PWM模式,边缘或者中央对齐模式
2 ]( w3 M4 X- C- h- a7 T) D
  X1 O2 E/ b* i$ a
20200505194802587.png
* u# `8 m+ x  I! x/ W8 j4 ?9 i- g
8 ?! y$ }; S+ t$ S+ x" l; a
非对称PWM模式
- ?( S+ p/ R# t4 r! }& ~6 ?7 Q5 v- i& y. V+ Q% v: n4 d
20200505195057399.png
6 q- N# v  u' a( H8 Q: e7 j- O
, |3 O4 [  O: c( `
三相组合PWM模式
1 z4 H7 K+ W* @: v- D+ E$ k. c3 U" ~6 Q% q/ W* J& z5 @5 n
20200505195420730.png

7 v: \6 @* z% {. t9 o& Q" o2 b4 \
+ P! h( Q- w& E$ W' [( q6 w 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。( t1 d. D: r! i: u
9 \0 e% X' ^5 l5 g
20200505195905197.png

# p6 x2 u: y& Q0 m* _/ [8 \" M# }0 W! M, u: t) K
20200505200041645.png
# B) i6 A6 h' h- T% m, d

8 a$ o6 G. }9 ^  e' ]2 j- | TIM2定时器实验
) @0 ~0 o* ?. O5 ]+ ]1 r本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。) t3 E  I% p+ H, ?1 c9 S, |9 s

  w5 Q# ~1 U/ R3 _% U/ I如何计算定时器周期?4 p# J% |8 J, M% @: T
: B9 t! e/ ]5 D3 u
1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;7 U2 u' R5 y2 ?: c4 e
3 i( ^$ I1 M; K% f8 o
20200505220029633.png
9 O0 T, ]5 `4 D0 M% T
! p& l# [* E/ [
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
1 l, q) l8 p( A- l( z; C: n
: h) t% ^8 W1 K如 64MHz / 6400=10000Hz
4 u" X# y% H: ~+ I2 h  e  ~+ h( x: U7 y
3、确定ARR的值,ARR=CK_CNT* t(s),
3 a$ h4 C. l0 r7 c0 W. U  K0 z4 n7 Z1 ~5 W: L
如要1秒周期,10000Hz*1s=10000。4 u! p6 [+ g" r

# g' u- ?$ S& U1 B1 j7 d9 k+ O实验代码
: p7 e* I1 H  F8 F9 f" g; B; k1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
- E" E( ~6 D: ]3 N( j1 ], s  Z# L) m0 K/ L' y* m$ t( r
2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低3 l- w1 H! a  ~3 M; @
# O+ S" i5 T: e) s
20200419170920422.png

; K; q$ A+ ~- X+ {+ O7 {* B8 g7 n% ]3 U! E
20200505223426701.png
0 |/ S: A6 g4 n* \. P, W: @

& H, J+ \! y) c2 ], I& z) q3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
. B; L. p& ^, Z. T1 w7 d* f: Y( k0 J2 h+ ?3 w
20200505223701644.png

! c4 J; y+ |' F. ~$ A3 T4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
2 N/ m7 ~5 N- c8 e* E+ [- \& e  X& {! p5 ?7 q
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值  U: }9 K' a1 J  S+ u( m
  I; G1 V% q- a6 q) |! z
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
7 C" w, |) c0 x& }+ {# p, \
) _0 Z9 t  z# D& K; O5 U7 k; p
20200505225312371.png

& q* w8 f' z1 y1 M7 I+ `: v
6 t- D, \9 m! h- S' N. \9 r4 @3 y7 H6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2") S$ m2 C# _6 A3 n# i2 b6 l# A7 |$ |5 W

& |3 x' ^# I2 i) ^- S+ H
20200505225419137.png

5 Q7 _  |6 x; B" _* j+ n6 K
9 ~0 Q* W$ t' i; K2 ^6 i4 i7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
. }3 p' o/ Z* V* O3 _# M, r5 M+ i( S0 K, Z8 V) `
20200505225614187.png

6 j& o9 A' @6 O/ u
  ^5 K- l( [: C4 o8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
& X9 M4 ?( E+ J. T2 _' N- c. a0 m1 m! ?7 j
  1. int main(void)1 ?7 q; M4 B  Q7 X8 h
  2. {( B; y2 H6 T+ g, D
  3.   **
    . @8 |; t: E- r% f$ y, i3 f# W
  4.   **9 d# e/ z, R6 b( G2 @: T, c
  5.   MX_GPIO_Init();$ `& h9 i0 t7 b! i7 H
  6.   MX_TIM2_Init();
    7 |5 M( {' A/ h) d( f& }/ `
  7.   /* USER CODE BEGIN 2 */
    / x1 L+ a) \8 N* a) F, m1 j6 Y
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断! t( O4 g5 T( D; K$ ?: c
  9.   /* USER CODE END 2 */) @0 I: {  n$ S% G
  10.   **
    3 u2 d3 o) z( K7 `) q3 B
  11.   **
复制代码

" t+ M' z# L% x/ D( n3 o9 E9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
0 f" V8 O# T- l2 E' ]
. _: E4 p. R6 T1 b3 [
  1. /*
    ! o9 ?  I7 a" H; i: R: P; d
  2. *stm32g0xx_hal_tim.c0 ~  ~( D2 v2 D7 q" N4 y
  3. */
    : P( Z6 B1 e( g0 j
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)" W1 w: j$ _" W6 n1 n' F* k- Q
  5. {
    # M. n+ R9 m$ F6 A) b9 B9 C
  6.   /* Prevent unused argument(s) compilation warning */
    ; H$ W/ D7 `9 {0 x# Y" }) h
  7.   UNUSED(htim);
    5 R$ Q1 i: f) S
  8. $ f; R* y- F& k) E
  9.   /* NOTE : This function should not be modified, when the callback is needed,: \5 C- Q+ w' {
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file, j! w2 _6 o" d) {/ r9 i
  11.    */
    0 C' a+ Z. {9 H8 O
  12. }
复制代码

* t. A! g% C7 Z% B$ H$ m( n) g10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。; J9 U6 l  T8 a* g5 d6 W, @: q; B

" Z4 h5 z3 ], Z- L; v  C; s' [
  1. /* USER CODE BEGIN 4 */* d! k5 N8 C7 X( m# J+ N
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    . s# O* [2 j/ U5 M. _) `
  3. {# x; L# _$ ~  K
  4.   /* Prevent unused argument(s) compilation warning *// O2 f5 f7 n. A0 L
  5.   UNUSED(htim);& h6 X7 Q* K& r7 m, \. h- D' Y
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平5 H# H& W0 G" s$ w6 ~/ J
  7. }
    ! G4 J- v* g1 }
  8. /* USER CODE END 4 */! l$ [3 Q# ]" x! O8 `
  9. 6 C! m. B' R3 N3 I. w
复制代码

5 t8 H/ D" o, ^) {2 X) Z, f# V
赞 收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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