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

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

[复制链接]
STMCU小助手 发布时间:2021-11-8 16:49
定时器分类
+ u+ f) L; p9 C) w1 zG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
8 v  |$ i2 q8 F( A; l9 Z& h# X3 l. k
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
* ]. Y: J$ c: |$ r' U
$ i  r; s" O# R! ], m8 b
20200505192122130.jpg
2 D* x; }  b$ D3 b. G
  e2 Z; n0 P2 N0 W
20200505192148321.jpg
* D& o1 z0 F% \& a1 o  ]; ~
9 _4 F; w$ f2 C% `/ f
计时器时序图
+ H8 H" M( A$ p. w1 T) V3 P& ?TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
4 A3 y- B- A7 }( v; T! s- f/ |0 T
20200505193407758.png

+ o% H# Q; U& S4 b
- W' \. p" b3 V3 }3 h; L8 O+ l
20200505194318226.png
4 U; ?4 h) w) q! _$ C: g) ^; J: E6 f

) j5 d' G7 G6 @6 V) [ 基本PWM模式,边缘或者中央对齐模式2 d. s' ~7 m. B

+ Q+ O6 G) P9 U8 t. ^# Q
20200505194802587.png

1 T8 r- U0 |2 _2 V3 o0 H
4 R6 J. |0 v( B3 m 非对称PWM模式
5 f/ X( s' @; T8 A
$ g7 Y4 B4 h( Q( z7 U/ n+ g
20200505195057399.png
0 |. x3 f. O' J/ G; D% I" L$ Z

0 s9 ]- }  E& E( Z三相组合PWM模式
& p: `& U' ^, A& b2 q( A$ V
20200505195420730.png
5 W* n  F/ q  L7 k, n& r, h

! a7 i0 t# c5 P( P$ `7 N 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
  E  d8 X' N. F0 @1 k) V  x6 X7 e0 C* t% b  H
20200505195905197.png

& X1 m2 C3 G1 y2 q1 T
* T/ z* E* X1 ?( s( O) U, ?% v TIM2定时器实验
; w6 n6 O9 T: l  N( T2 v本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。# I* k2 e8 o: V' g# r

/ _0 {5 Y$ U. a; S; U! i如何计算定时器周期?
& x9 K3 W" s6 u! @3 H  v% o; d9 L- a. m( G. b0 k. \* `1 X
1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
' i/ I  X) I& o4 z* k
. s3 j- U% `# Y2 O6 o- G
20200505220029633.png

/ q* B0 U' W7 _! H( w0 c
0 Y3 [; t( i7 }2 H' N; L0 }) b2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
0 e4 X+ a+ M8 D' J# C4 }+ m! w  ^0 b0 `# n* u
如 64MHz / 6400=10000Hz
% _7 R  m1 o" E4 z* u0 \/ I/ _) C5 k3 \/ |. v& l+ J% {' K
3、确定ARR的值,ARR=CK_CNT* t(s),
) y- Q2 Q( b, F% F, `
* v) O+ a5 w7 P# g' z7 d如要1秒周期,10000Hz*1s=10000。8 B- X" L7 M# |0 z

9 A' y% E7 ^8 U1 ^实验代码
* E4 I, D, L( e1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
# b. a6 K# [+ a2 s' ^' Y1 w7 q6 ~" |# R* u. f
2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
# W4 o" e+ l# `- s8 q* x4 `- y
' c' U% p8 R5 v  P2 q
20200419170920422.png

, a0 l& a2 f; B( N$ [% _7 v2 Y0 i; R2 }4 o, [) a( A4 Z, j; [
20200505223426701.png

: c. o2 n" G: g: h" T
9 B0 a8 _: {0 O. y3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
) O$ k; O6 x9 L  F" b. H: X8 M! }6 Q- U1 d7 \* J
20200505223701644.png
  B/ k( X; d  @4 n

3 b4 j' Z! s- r0 W$ W* I/ j9 u4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"" I" |* V3 k: F9 {
" O) A, A8 ~2 M% H6 J; X
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值/ S- ?/ ~3 t6 W( r
6 W: k  V: ]1 S, @7 y; q
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
" s  E) A7 q0 U+ X  C0 U& b$ l) A
8 T  P0 u! g% l/ w, }# C9 Z
20200505225312371.png
7 o; f' I# q0 w7 h
. y0 W0 F( G. q) H& k* S" D+ E
6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"
' h) u3 |" L# f8 b6 i  W
/ x  {9 L; U7 g! u7 r/ N
20200505225419137.png

9 \! j  [/ B* \
% v, V1 q0 G% r7 y; Z  _) ^# k& X: }7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。2 ]% r, m3 ]9 A5 w  m

/ ~7 |: o' H# T) U& l8 K* a
20200505225614187.png

) X$ L4 s0 H: g2 t( `
7 G7 i8 v  X% ?& E  x9 h( E8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
. m" p  g! R* R% `) ]! x* ]1 R2 S
) {# Z0 ]& [5 k7 d, X
  1. int main(void)( b+ v! T4 }0 y1 V0 ~3 L7 j, s
  2. {  ~' P* i% h5 E3 V
  3.   **
    * h. p9 K5 A  o; X0 C4 C. u% e, ~
  4.   **  u$ ~! d' s( j$ }  P+ G+ ?1 k% I
  5.   MX_GPIO_Init();. f4 D! S; M/ H$ N
  6.   MX_TIM2_Init();
    - p/ p+ ?6 H# O
  7.   /* USER CODE BEGIN 2 */
    1 K2 I' p8 y6 M( O: {5 M
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    7 V4 l7 f3 M0 ~
  9.   /* USER CODE END 2 */
    $ X: e) r# I" R# k' }
  10.   **
    ! V4 B: S7 w5 [) a3 p' Q# I
  11.   **
复制代码

! A' I" N3 d( _/ \9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中% A0 p3 l! T; U* ~7 |8 f: k2 t

  ~8 i" ]. o7 Q. O# I" F
  1. <span style="background-color: rgb(255, 255, 255);">/</span>*! U) A4 I( P  E; z  S: m
  2. *stm32g0xx_hal_tim.c
    / R' S6 F' ^3 {1 R; t) I
  3. */
    / h  d# ~" v! `7 M, W$ C3 W
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    5 W5 f* B  h5 r5 U5 @: v
  5. {
    7 e% g) w' j+ {: u2 t8 m
  6.   /* Prevent unused argument(s) compilation warning */( q! Z. [. |3 \& M; I+ W, T
  7.   UNUSED(htim);+ R, H8 j0 h3 U2 B7 C
  8. 0 O0 H8 U3 N% D9 i/ B/ j, L
  9.   /* NOTE : This function should not be modified, when the callback is needed,0 ?/ {6 ]3 ]5 q' c5 s5 b
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    ' @, ~) F9 x/ t
  11.    */
    " q% ^  p& U8 m& A# Q" Q
  12. }
复制代码

8 J2 f( L2 @9 t3 R' p  g3 @10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
. I& w7 g  c1 v' `! g! W
! {  m, d* m4 B1 K- L
  1. /* USER CODE BEGIN 4 */' u+ W+ \6 G6 `& t
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)/ d8 x6 A5 @: U% t  v
  3. {0 O! ?" q/ |. W8 H8 C% H$ F/ U
  4.   /* Prevent unused argument(s) compilation warning */- K$ Z0 y6 \5 n$ W8 r2 t% }
  5.   UNUSED(htim);/ Y4 B& ], d! g/ k
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平6 X& |6 Y' x; O2 a' C; V- Y0 J
  7. }
    1 l, L# ?5 k; o5 Z! K7 Z; _
  8. /* USER CODE END 4 */
复制代码
2 U; h  K' z$ c! k0 o

5 N$ N% m2 l4 m4 |8 G" x  l# p2 b
( a1 k' D3 U5 u* }/ C- a, G: r$ z1 \2 C/ H0 C& w

' {% H+ Y3 e- V& g/ K1 o4 H6 |. J, x- f% U& u

% }0 e9 @( }0 S# w% n6 O  {
20200505200041645.png
收藏 评论0 发布时间:2021-11-8 16:49

举报

0个回答

所属标签

相似分享

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