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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类8 H5 x( o. v, g
G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
1 b: b* C  m5 `0 \% ~+ Z2 s+ u- L6 {
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
: U# r8 i$ Z% t1 _
1 a4 K8 w" l1 @& Q
20200505192122130.jpg
9 \* @! p: c0 o

+ l! i1 n) r' ?, w
20200505192148321.jpg
8 r8 F1 n; V' Q% E  J

5 o  b0 r: F6 g. |2 p 计时器时序图

" J( m* I$ b( Q  E8 j4 rTIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。* B- E1 z8 i& L7 X! L+ b+ Z

6 Y3 E6 o' y0 _/ A9 ~
20200505193407758.png
& n5 ]. s6 Y7 I9 s8 n. {3 m

1 e0 ^" T+ c& ?7 y
20200505194318226.png

. `  ?0 Q% R+ g) R. x# H4 o) W- N% T) C# |8 \' e1 ]# j
基本PWM模式,边缘或者中央对齐模式
+ A) r. E8 y, W  j% L, C4 L$ m  Z
20200505194802587.png

; `: X$ h' H, K% f) M7 u5 @: t4 I4 B  `5 c. f$ s: S
非对称PWM模式
+ y9 t3 ?& d  U9 y8 Z  K; }
5 }/ u; |' X/ @" m& q% T& l
20200505195057399.png
5 [; |( D! G: p1 W( T2 b8 M/ `6 ^

$ F( V, u) C) G8 h三相组合PWM模式
! t, t6 L0 [" u' |9 w  k, b* t! P/ }  i
20200505195420730.png

8 Q; z" H  h3 K. u0 O( _3 P9 y* B( C1 N  s% U; |* y
可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。" E$ M# Q4 e% J+ _/ S

0 j# `; O& \% ^. o
20200505195905197.png
8 v& w) R! C: O+ E1 `  [
4 B, T' E$ g  R* V+ c) e/ a
20200505200041645.png
$ h2 G, R; s: v1 J' W& d

: q2 \3 v: N6 P, m* @* _3 m% _ TIM2定时器实验# b( X! v* o( y5 |, M6 m3 t4 }
本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。
$ ~1 V! h- h% u* p4 E& R7 \2 s( Q
如何计算定时器周期?7 t8 A. A3 I" c$ z' p& N' p: A! x

+ t. @, Q8 b+ n' [* B* d0 O6 Q1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
+ x$ E  r, i4 T- I9 C2 O: s1 m; A+ J8 l- ]5 S
20200505220029633.png

: V  g1 ~3 N" i: F* c6 N
% s  X' y! V0 \) R2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,) b" I  @4 q, K0 x: i+ \

0 U' K2 A. C# j如 64MHz / 6400=10000Hz
# E' P1 v! B" {3 w! d2 o9 ^' M7 E) S2 A
3、确定ARR的值,ARR=CK_CNT* t(s),# g/ [1 S5 ^& F' ^9 ?4 y6 N
; X' [# v! W0 d- t2 H+ c
如要1秒周期,10000Hz*1s=10000。
% T& Y& h8 h' I. Q' X  ?' S
+ i& G; _, z9 j  M- r/ J实验代码& d1 q8 J! x: U$ A, A3 a* D& a  K
1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
7 d  i6 j9 o* _9 d& z
9 x# t8 W2 h$ O2 i/ z0 O: \2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
) G/ `: j2 P) _/ b& _' b3 V
3 E2 ^9 W% z% s( v9 n
20200419170920422.png

% _+ _2 }  N3 ^8 r" u
0 g0 [& F0 z2 _1 `1 ^
20200505223426701.png

- u6 l6 M4 Q$ m7 ?+ z1 @* g9 w
! P  r# R+ p# \: G  v+ C* I. X7 a3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
# S% G9 a: k  }- B+ k: Z5 W! m6 n; J( A0 M3 P6 W
20200505223701644.png
3 J) }6 S( b, F
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
" X- D& r. S& H$ [8 k$ k. Y8 K. d0 q
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
& \0 B  s* P1 u" R+ ~  c% F
4 \) K/ i/ V) V) Q, _2 s* b7 V如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT* u2 y3 j" X. t

8 a$ d1 j. d6 }2 U8 V( M
20200505225312371.png

+ Y6 M  B+ W# P2 W* e  b6 A, s# k( Y
: |1 q$ K' I. Q8 G! e0 `6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"
0 Z( U# l9 Z' l8 S1 Q" d2 ~9 @' L5 {/ D
20200505225419137.png
# a6 g& S) u) g. w& N# U
& d& p, [! [% ]% O$ A
7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
- M8 ^8 g! U; j/ p% e9 M7 {9 @! s0 i6 }" f$ A3 U/ j% Z
20200505225614187.png
' h: T) g# Q" ~6 Q4 f
- O" \2 }0 r1 n) V6 S6 K
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
- d( \8 @' f# I0 J0 e
. W. R, G% q% c' O
  1. int main(void)
    ' y' C& n6 l9 O4 L% U4 M
  2. {
    + |! S1 S% N, K8 f; [% D4 @
  3.   **9 F7 {  s8 x4 I8 R: Q% C6 _5 s
  4.   **
    : u" O* E# h9 g! j
  5.   MX_GPIO_Init();
    6 N6 q. \. C3 X, H3 M0 F
  6.   MX_TIM2_Init();' ?! p8 G7 |, T1 E& M
  7.   /* USER CODE BEGIN 2 */
    8 y+ G5 c0 i$ H' Y9 g, o
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断! r; c( {6 y/ T8 _# [% V7 ]
  9.   /* USER CODE END 2 */
    " ~: r( g. \) H6 c* @1 T
  10.   **
    / }. J4 U& |4 l
  11.   **
复制代码

8 C) s0 z9 f2 E: _2 z, j9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
/ k0 E: V3 q' j4 [: I( }: b% @/ B  k+ R" E
  1. /*
    + ?( U8 S$ J: ?7 i4 M
  2. *stm32g0xx_hal_tim.c& |+ ^7 `- k) u4 N* ?6 r
  3. */3 X" M1 W$ m' q* |
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)2 b+ F0 Q$ w% H$ f- X
  5. {5 ?/ y' s2 S4 K, w3 U) [
  6.   /* Prevent unused argument(s) compilation warning */6 Q, a' j/ k1 b+ X4 H- I; Q3 W  p
  7.   UNUSED(htim);4 Z7 Y+ D/ ^0 i; e& }
  8. ( L' T* u% E; q
  9.   /* NOTE : This function should not be modified, when the callback is needed,
    ( n/ B9 ^' D+ v5 s: B+ \: D
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file$ k( n8 X: w7 z8 u! Q
  11.    */
    8 s4 j, I# L! m# o8 z  a
  12. }
复制代码

9 x- ?- E, j: o2 f( [10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。: ~6 o! g$ T# u5 c) n% ^. V1 ^
7 D, a* l  Q3 u6 \5 j) P
  1. /* USER CODE BEGIN 4 */# t6 L1 L# E! f9 I7 z  x8 w9 P" ~, a6 X
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    & [" A4 i" _$ o
  3. {6 J8 U  O2 c8 \8 m2 x9 w; r: A
  4.   /* Prevent unused argument(s) compilation warning */
    5 O# h1 o: O0 o
  5.   UNUSED(htim);. g9 o2 B0 x% G: F: B7 h) Y
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    # E0 z$ a( {( v8 Y$ ~1 Y
  7. }- u% x- Z8 ?7 X
  8. /* USER CODE END 4 */
    ' }) G: q: \' ?8 v6 e4 K

  9. 8 r: d9 I, z: I  a$ s5 J4 U2 k- V
复制代码

) a$ g0 X5 U4 b4 [
赞 收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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