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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类: p; i0 I) x) m. w7 Y' ~* Y
G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
' Q& x" N! i; r+ L- q: t2 F4 z
; y3 K- k1 G. g7 M1 \! S其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器+ v( p1 |% }% k9 D; s! N- [) ?4 X
* _- M) W  C8 y  O" A' o5 q5 G
20200505192122130.jpg
) v) M. Y  [5 e/ S

! Q8 X( \% F  {, H5 Q. }
20200505192148321.jpg
* ]/ o$ X9 S: ~& y

5 G; }; Z3 r, C3 c 计时器时序图

  A  h0 G8 [& J; ]5 C( }, s+ R& ATIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。- t7 ~0 b! k! G! V
2 r/ _( ]& ^) e
20200505193407758.png

+ S+ r5 I1 U2 q/ |" _; s; p5 |9 Q
20200505194318226.png
/ Q0 _1 J: S1 }* [& }4 u# H$ g

: \( d+ c$ O9 K2 | 基本PWM模式,边缘或者中央对齐模式
. X/ t7 Z/ c1 K' m. Z% o
& O: R9 N) r9 Y6 b- e
20200505194802587.png

8 ]: `5 W) ^) T" K& q& w2 C0 [2 Q+ B; l; }2 K% y/ K+ ~
非对称PWM模式
- A  `6 M( @- V$ f! X6 {5 V' c
0 m: m* z  ?! s$ a( c0 c2 \
20200505195057399.png
* `# V/ b1 k2 j: F
( j4 L. F4 f' C" _
三相组合PWM模式
# M( b- F) q1 c8 \. n, S2 B1 b9 K) N! z. A7 I
20200505195420730.png
" C: q) ^' |: n
6 H# y, B+ R& o- `4 Y  Q
可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
6 G+ d% }3 q/ J4 O# g0 y( l* `
) E" ?9 k5 B0 v/ T6 N7 p( S
20200505195905197.png
* M7 w/ Y6 r7 S, C7 z- z: r0 E
# O9 ]+ D  B- t. [& J" g0 W
20200505200041645.png

) h. f6 v- H+ g) J7 l- e! B0 r) G* ^" e0 k
TIM2定时器实验9 V* t& ]  {9 P( q" q
本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。
, p! j% {5 j' N- y2 s' u* Q
$ w5 d( n( ]/ h如何计算定时器周期?
& V$ N6 x$ ^0 A6 d  H6 I. @5 a6 _* M7 x4 H
1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;" R: l" a2 T7 K( x% _6 A
0 `. l4 ~" h8 n2 j( P
20200505220029633.png
# k7 e) a# S4 _% C5 l# ^
) b' Q! F. U) T  w
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
2 h5 I8 ]8 C9 t9 ~
; ?0 b% |) H5 Z# A8 B) C如 64MHz / 6400=10000Hz- b  u8 n3 J/ ^( y! X

8 V: W, U) w: J  v5 Y3、确定ARR的值,ARR=CK_CNT* t(s),. q: Q" Y+ \' {2 _; ]- K9 v  n
) D) S4 f( \" }; {9 x
如要1秒周期,10000Hz*1s=10000。8 L) c8 b8 A( L0 \2 R0 W
/ J3 b* {& F7 C
实验代码- Y9 X% G; @. t6 e  e8 x  n
1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";, q, W3 B, _* @7 r, q

1 @+ n6 u/ W3 b- |' W& R3 ^2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低3 ^) {- Q) o! |) q5 _  _

, n- G+ n# B6 W: [: Z" L% |* R
20200419170920422.png

: S' C2 c9 `$ n6 U2 }4 }* ~  Q) }
20200505223426701.png

& g( r( R7 P5 M( n+ A, A
0 j3 ?. u4 c  g8 e3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为649 c$ T. Z8 _; F) h4 o- p, a. _
$ g3 A& E; @4 S! m
20200505223701644.png
( L& Q: ]; L2 ~: U
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
; x* _# f: C* k2 i: k7 o5 t$ B) z" R0 w( U( ]- Y1 e% U5 Z0 z/ U' {
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值" I6 J% U+ I: `

- q. r7 V6 x- [9 f0 e如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT5 j/ y; Q4 {% j# y2 S) g

" t( }% [9 Q$ F  _! V
20200505225312371.png
* ]/ {9 i1 C, ?( C' @% F0 ~

7 L7 c' g  ?4 f3 p- u6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"
, j! [$ W, N3 H
$ f, Q1 ?' ?( ]5 U
20200505225419137.png
1 l$ q9 @  i+ G- W3 M+ j

$ C) z) u/ g6 C3 g7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
, R6 ^( T& I6 Z& [+ y, ?9 v/ e$ c! \- ~/ ?# D* g3 }
20200505225614187.png

1 s* i9 s0 x! {/ Z  w
0 m3 C9 `1 P" i" `8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数4 g. ], x6 Z# a
0 S7 b1 V; [1 e+ ~
  1. int main(void)% r/ @  z+ W% @8 {7 @* u
  2. {  A( u; N/ g& B# v+ a
  3.   **# i* m1 a4 D: B* X  y
  4.   **
    2 k7 B0 l- G) Z5 Y% x; s( K/ F
  5.   MX_GPIO_Init();4 c" Z0 e. k5 J5 M- t& s
  6.   MX_TIM2_Init();" U/ L' y# P/ r3 F5 d1 A  _% H* I
  7.   /* USER CODE BEGIN 2 */
    5 |  U" q0 r' J; H2 a+ t5 Z
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断/ _# c- t5 g# a1 A% y" e
  9.   /* USER CODE END 2 */4 s% U/ {! B5 O
  10.   **, |9 f/ u2 }. H1 \( o: O
  11.   **
复制代码
9 S' P) K. z1 |  X
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
& f# Q2 \2 [8 v2 k" C7 T& k0 j* K& `! ~
  1. /*
    9 [! Q6 E* X1 J$ j+ ^9 }
  2. *stm32g0xx_hal_tim.c& R, z! y, m$ F1 w5 W$ J: z
  3. */
    3 T  a1 ~' V' J
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    ! T. Z- M' y( F4 X% G
  5. {
    7 P- {' x1 l+ R/ F$ v$ ~) D5 X
  6.   /* Prevent unused argument(s) compilation warning */
    8 d9 B5 f# p" v2 {/ O5 L+ M9 M
  7.   UNUSED(htim);
    - |% `) y% R- S! N  K' W
  8. 7 P. l: _# T* y( J% ]) f
  9.   /* NOTE : This function should not be modified, when the callback is needed,
    - ?- K+ B# P/ I# c5 v( n, {
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file7 g3 B" J. S0 S- {/ ^6 l
  11.    */) H8 o9 V$ S( ?
  12. }
复制代码
7 ^6 n0 l' n4 k$ r; ?) P! Z
10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。3 q( ?( j- T( R# |* ^1 d. T) t

$ I8 k; i5 v% a  U
  1. /* USER CODE BEGIN 4 */; t- _# n0 C2 g0 j% E! h
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    + H+ |0 q* U* ~3 O0 c
  3. {
    0 ~6 W$ F7 f7 s! p% J2 W& \! U* q
  4.   /* Prevent unused argument(s) compilation warning */. S; p+ h+ Q  p
  5.   UNUSED(htim);
    6 R+ s! Z; `* E$ I1 ~
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    4 u+ h* Z; q7 }' p
  7. }
    ) r. x- x8 E! g! e6 v: V- D: Y
  8. /* USER CODE END 4 */5 \  h8 E& t! v! ^- A6 h3 ?

  9. # u1 }3 P9 k3 g: l
复制代码
( R$ c  A4 ?- F2 u- m2 J6 w
收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版