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

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

[复制链接]
STMCU小助手 发布时间:2021-11-8 16:49
定时器分类
1 r9 }! Z+ [* L2 C. sG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
! e" q) \5 ^' E8 {- K# c% c1 e  N) P! e9 o, _
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
/ m1 ]. k# c+ |$ p; k$ l5 s( T; s& J6 L$ M0 X
20200505192122130.jpg

* ]" j5 N" m& K) ~0 f9 h# W) a* L2 u: Q8 v* A
20200505192148321.jpg

' D, j& L) I0 k4 S) i+ `+ F( \3 o* J* L, M
计时器时序图, p2 k8 a( x+ S4 X) d* o/ u
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
( D( F, P7 s" l* z& {3 S9 d8 V+ I3 C/ o- o
20200505193407758.png
8 ~& h; R. B# f8 q: f& M
+ ^/ e9 O! b1 d* a% [
20200505194318226.png

% i1 ^! H/ _& [, z  Z3 }0 V( G: ~0 f
, t( H5 Z7 z$ \9 F" }4 p' a 基本PWM模式,边缘或者中央对齐模式2 g7 c2 V7 Z0 |& i9 z- I( c7 x
5 G4 K; G$ g9 F& x
20200505194802587.png

8 X% b) \$ w& Z! x+ P, P, Q+ X4 @9 |( G
非对称PWM模式4 s$ a: n6 Q- f' Z4 z0 Y5 O
  Q# [8 \; ?2 O% N7 l5 P7 T! s9 s
20200505195057399.png
* G2 E5 n) k' k
3 d8 K- _/ S% \( o: k/ Z
三相组合PWM模式' a$ A: j- m+ H" P) Y2 `  ~
20200505195420730.png

+ O0 j7 I6 |* v5 K& [6 q( Y! N2 x+ u$ h: w0 l1 Y* m
可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。' x1 Q7 D. }) P( ~. @/ A+ D
* l, ^! f* l& z$ z( Q5 J+ Z
20200505195905197.png
  S8 H% R0 N& K3 u. q
  a1 e/ J7 x; o1 K
TIM2定时器实验
; @1 v: v9 ^$ z本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。1 }% Y! z( z- L# h: i- d* M% ?

/ ]4 I' x- ~3 |如何计算定时器周期?
* _; N" r  K- r8 d: {
1 B9 `2 f+ F, X. h3 m1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
3 U' B7 L. ]* e" s7 N3 h5 e
9 N( ~' m. ?7 D7 Y7 l; ^
20200505220029633.png

( d0 c. e0 v4 @2 Z" p( H3 ?) C9 `8 N( [: q1 y( a, b
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,5 I* P  v( ?6 H5 d' I9 c/ i

) c" {3 L# u' g7 p* i如 64MHz / 6400=10000Hz; p. ?9 e  |9 S8 ^6 }. ~6 n7 i  V1 ]
. v( a3 e* L, M9 ?# h7 Z
3、确定ARR的值,ARR=CK_CNT* t(s),2 Y$ k0 v. p& S+ P

9 m" |9 A% \0 n1 C: s+ d如要1秒周期,10000Hz*1s=10000。3 y/ @4 }( P# Y9 F  V( K

6 J% ^$ M7 s/ L2 ]实验代码" \  ~5 d1 r, e
1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";2 D! T& i, S4 \
( s: `. s0 f# T& B! c! H4 a
2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低- H8 j! n2 F  X7 U

$ [4 B, H  I! c; R; H
20200419170920422.png

& g3 L0 D; j7 q2 b2 W' i8 f( k, `& u4 Q8 V
20200505223426701.png
7 }; B2 z, s4 L8 g, j- Y/ V
8 k! w  r  d; X. n+ |7 w& q9 p. j
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
, o' U8 E. X9 A  K% t/ {, e/ G( X
7 q; H. `& W+ `7 z8 L
20200505223701644.png

+ y* V( Y/ Z% ~: ]0 T, g0 F1 [* w3 q0 ?+ j# f
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"- X) y1 r- J) h$ j( D: f8 e
0 ?8 W7 y# Y. P" q3 R+ B
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值1 O% `1 y  R1 B2 x' s3 n
+ H# \$ Z7 P" ?* O
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
" p: m+ d! c# _# `: B# I, q+ r$ F: }
20200505225312371.png
6 k9 h1 p$ r% i
6 X8 u$ n' a- k, h& x) P! s( p2 ~; _) J* ]
6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"
+ w2 Q( W& j9 x2 B( K$ |0 a4 s, q7 H' A0 G1 X& k! M
20200505225419137.png
8 h% {/ k* l5 w/ `- k$ u

% s. _$ _* G  ?. y+ I$ V7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。9 ~' a( B4 [6 _6 G5 v$ Y; U. ~

4 Q* s1 r4 Z- b2 k" V9 [: J# t& B
20200505225614187.png
9 z2 f- o& F6 t6 d# m
' {% T; j& f1 F. a+ ]$ c7 N
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
- s5 @1 y; }3 k8 W+ @  g
& c2 Q- x% Y- l0 K6 ^4 b: x) D
  1. int main(void)# S* v2 o/ N) s
  2. {2 b/ l0 l! F! V+ d6 s; i
  3.   **3 j2 `/ O8 t& I* ?: l( d/ l
  4.   **+ G% ^2 A# M2 t+ W9 s4 W7 S
  5.   MX_GPIO_Init();
    . e4 ^0 O# |5 W& I
  6.   MX_TIM2_Init();
    * p/ E% g  F" r' o6 v. n
  7.   /* USER CODE BEGIN 2 */; _5 J, N8 b5 I
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    0 {0 T6 C4 E! v8 I7 n7 R7 m
  9.   /* USER CODE END 2 */, s2 w' c7 x, M+ l8 D
  10.   **: d; J! d# y0 v
  11.   **
复制代码
, h1 k4 d. r, Q; \7 E/ q. B
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中  V! l+ R- h* I# B- }) z$ h

+ J# K3 G8 b% F9 J5 d- V9 ~( B$ b
  1. <span style="background-color: rgb(255, 255, 255);">/</span>*0 @2 N3 _/ [: I" N
  2. *stm32g0xx_hal_tim.c
    3 o6 ?4 D* I3 J
  3. */
    2 R6 j1 s7 z# f  z0 Z) [! G' K* q
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)- x: `9 u% x% z( V
  5. {
      u+ Y& b! A$ j5 x
  6.   /* Prevent unused argument(s) compilation warning */
    4 D: v4 h: i% O. O1 w8 |! j
  7.   UNUSED(htim);" ^" A4 o# R* r  C
  8. $ Q5 U1 Z# F, U! ~) q1 B+ S" c
  9.   /* NOTE : This function should not be modified, when the callback is needed,3 u, h9 E8 p% N
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    . l) ]6 s. m. A/ |8 H, R1 O' V
  11.    */2 ~; n5 k2 S& ~
  12. }
复制代码

4 e9 E  r3 m) R9 K* A10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。) x/ U  ]% D6 v3 x
& g8 ^/ Y6 J7 p/ B6 z% H5 b2 T
  1. /* USER CODE BEGIN 4 */& j) A9 T# e2 \; A! t
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)# {: H: @- Z1 Z: b' Y1 ]
  3. {% W7 ~8 }1 i' _
  4.   /* Prevent unused argument(s) compilation warning */
      X$ T% X- d! I( w
  5.   UNUSED(htim);1 G7 Y6 R' ~) i2 X
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平- {0 l9 o# P; d) c! o) p
  7. }
    ) ?: |! i% j3 ^, w( `3 ?
  8. /* USER CODE END 4 */
复制代码

1 s4 Q  Y3 a! i- w4 E! |! W$ H1 n, C7 F& ^' R, e

" ~& g/ {8 v% L  N+ F1 z3 {- m0 I0 [' I1 c& r/ B0 I3 U* P

' ]* K9 n0 |: X( f4 f% j( E2 M/ [* Q( q

6 G/ \1 a) N. a) N
20200505200041645.png
收藏 评论0 发布时间:2021-11-8 16:49

举报

0个回答

所属标签

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