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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类2 u/ h# _. j! G. |8 j. R; r- d
G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图; d2 l: w9 h; m9 I4 @# {
5 c& G! a' B' A
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
& t" J0 r6 M1 @! }5 {2 a4 @" C& Y6 r& W
20200505192122130.jpg
2 W& c4 r5 j) Z1 M
; w8 G" ?$ q6 N% a
20200505192148321.jpg

6 ~* O# p) v) g/ g9 q8 i0 @5 N: Y7 F7 L/ N
计时器时序图
% O# Q2 w/ I$ j  ]4 ~/ }/ T" p
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。0 `% g; q0 v' \+ Y3 S
* I: S9 c# A$ f% H7 O$ a
20200505193407758.png

0 e! u* m! n! w3 I9 _" B! W5 w
6 w) M1 e8 y8 ^( ]9 v! \
20200505194318226.png

( F3 K5 L! {6 T) F- {3 W( @% h( u
: _! U! h  }+ F- t# C 基本PWM模式,边缘或者中央对齐模式
( c# g5 b3 J& M4 l" D, {
6 V6 f" ]) M6 J8 X$ u
20200505194802587.png

/ h( ?( d6 I4 [
9 D. x. }: I( |  q) X0 K  a! C# q7 m 非对称PWM模式9 F) _% I4 s6 I& y( `

9 E9 C2 B+ y) {, t% `' w  m! v
20200505195057399.png

9 s2 G: S/ D1 x& ]: ]. U, s8 |5 |4 @4 l7 }4 v
三相组合PWM模式
& P: j! ]' K6 n: l. d, `2 \. N8 z( I# s
20200505195420730.png

! G5 c, S& T) M$ v/ |. U3 f0 m
9 Z7 C( n& N" V  A: G 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
+ t  V! V; F& `- a3 |4 A4 i9 a' b# ?7 U' Q. }2 U8 R9 S
20200505195905197.png
- }' }! n. e/ `4 l* u4 E/ T7 z" e
& H! n% A( f) H9 m8 B! s2 q
20200505200041645.png

6 v5 `' O) E( `8 Z- E8 o' u* Z' G. ~& ?. h  s. ?
TIM2定时器实验
% I2 s, d9 k# t本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。/ P5 |2 A1 ]6 r8 C7 h

* H, ~7 v0 M- M如何计算定时器周期?
( x' x- l# x1 W  \/ P* ?; e
3 J$ E- ]9 X8 u, }% O* h  }1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
( N4 e/ z: ~( z$ ~3 K
- P2 B% W/ t: |2 A' u4 f
20200505220029633.png

3 ^( b& T, t1 U* g/ u1 e. V" t% K% j: v; N
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,3 Z$ ?, x0 a3 V+ P$ j
) Q& K% r5 [4 i
如 64MHz / 6400=10000Hz( A- Z& A& i7 W/ }6 Y- s$ T

& c0 Z# D5 ?. z+ Q  d3、确定ARR的值,ARR=CK_CNT* t(s),
0 n! }, L: q( A6 D" |, `" l, G: S3 ^  C' l
如要1秒周期,10000Hz*1s=10000。
2 |7 e! m4 s' _1 ~( R7 n- p! B  k( E2 S
实验代码
, W6 o) W/ [: ^* F& R1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
% b1 a. _) X, G$ O$ d* E& v* r3 l$ a/ U  N/ ~! ^/ _- {7 t
2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
5 a$ C% m$ A5 {. n5 f8 Z* |  Y/ Y' n; p* Q
20200419170920422.png
1 Y+ l" v. r& I5 I4 Y, a

0 g" K, y* v" ?" `
20200505223426701.png
: c1 a6 Z2 j) C6 }# |/ V, E8 Y
5 L1 \3 `& e# `. j, s
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
: Q  R' W! d: E( H# j! b- {# A) l4 x6 R" G: u6 L
20200505223701644.png
! p0 o7 C7 |  u# r9 v
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock", e4 c) L5 \; N# D1 g" m3 b- w

0 \# m( B3 h' |* f5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
1 N7 ~8 V5 R. L: ]( j; p' Y0 Y! d# `" Z+ L
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
6 f0 F/ C# i8 H* K& Y8 G
7 u1 D- ^$ }; u8 U- ^* h; p
20200505225312371.png

5 }0 o' Y8 O2 q4 o1 e2 X! U) F/ e$ x
# I; c5 T1 w) G0 P- I9 v6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"" }& u2 T- d/ G9 I& @& O

6 p% O/ Q% a( U1 n7 O  I; q
20200505225419137.png

) a* K  g1 f" B, |8 f$ S% q% {9 U8 D$ t
7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。: i$ d* z# O3 ?4 j- _

$ b8 Q: k. ^5 k
20200505225614187.png

$ w" v( O: t( J* [7 `
* |- x% `8 j: D" x8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数. k; b" a: j' S

6 ^- k( O! B3 G* l" C7 k
  1. int main(void), b; U# f. ^* U4 G/ R
  2. {0 {) A/ P' @" y* m2 T
  3.   **
    ! {# X/ F9 x% P1 O6 t0 N
  4.   **
    0 n6 \! N% K) E) S# ^' p
  5.   MX_GPIO_Init();) W* U* W8 w' h
  6.   MX_TIM2_Init();- n0 s  T# Q0 s5 Q3 F) H6 ~- N
  7.   /* USER CODE BEGIN 2 */
    + _2 j& h' e' y
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    4 A) y! ]4 B& \1 U# O: w
  9.   /* USER CODE END 2 *// [9 j3 x# ~, F# d3 L; r1 j
  10.   **
    # e, @! T0 ~. ]) c
  11.   **
复制代码
9 H" d2 S7 k7 |& q
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
6 k5 W5 N4 }# B0 C" K9 A7 U3 P4 u% G3 u  t' q9 E6 V
  1. /*
    . _3 t5 J8 w8 t$ o* B1 W& w  V
  2. *stm32g0xx_hal_tim.c7 @8 O- R/ @6 Y5 S; C4 x
  3. */
    7 k! Q! J0 C5 `( J" e
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)- {% U$ O: T8 f/ k* v3 Z
  5. {
    6 Y: D0 u1 }( D0 K
  6.   /* Prevent unused argument(s) compilation warning */1 D1 S: I9 ?: Q
  7.   UNUSED(htim);
    ! r3 L1 U% k! A. e  c- x

  8. ; d: p, h/ Z0 ~. _/ R+ o
  9.   /* NOTE : This function should not be modified, when the callback is needed,- H  X# Z' e+ k: D
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    8 f4 R2 c: T0 t/ X4 c
  11.    */. _  r! a1 b$ F" y7 s7 ^" b
  12. }
复制代码

$ m: j6 y, J4 x10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。$ b1 l3 n; m8 e1 A  ?
* i0 Y8 R  B9 ]0 G' U
  1. /* USER CODE BEGIN 4 */
    ; S8 E( F5 p6 u. H! ]
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    - w+ f. q$ ]! O: t- V* f
  3. {
    ! T/ {9 f+ Q2 H; Y2 v0 N* O
  4.   /* Prevent unused argument(s) compilation warning */) X+ X* [0 ?, |. W* s
  5.   UNUSED(htim);
    5 y6 P  O% J! C& F' Z  R
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平* L! q* I0 F6 v  `2 v
  7. }0 C( S& |9 L5 ^' ^1 ?( L
  8. /* USER CODE END 4 */3 S- t+ c9 F- g

  9. * m" S5 X$ r2 S
复制代码

) Q% ]. k% `$ M- m# ^8 l$ I3 ]
收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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