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

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

[复制链接]
STMCU小助手 发布时间:2021-11-8 16:49
定时器分类" F) P3 t3 H4 F  n& t$ Y0 _
G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图- _8 @3 b2 N. W8 G% r$ g+ e, B! C
  s6 ?. Q0 P9 Z9 _- P. E$ D; W
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器1 D1 k( I% S- Y

; V* O! e! ~+ E( r9 M- r- e0 f# V
20200505192122130.jpg
: e# l3 T( t+ o% r9 C
" r/ }3 k# _, X: \! u4 j9 c
20200505192148321.jpg
, E# ], Y( t0 ]: }+ v; P& R" w2 ]

% i0 u4 A$ x% [; n8 l6 ^; ]% e 计时器时序图0 b; G3 \2 M' v8 R# R
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
! `% d. O4 H$ v) n( X2 G- L. v7 I6 d. ]+ N5 h& y' c$ x
20200505193407758.png

& u8 d. g. L5 m2 K2 b7 k
/ T/ A8 j8 a' C2 ?  o
20200505194318226.png

0 `5 G/ h" F" P6 }! T
  W4 A3 b8 C1 X( p0 V2 ~  k 基本PWM模式,边缘或者中央对齐模式  S5 p# M( z% z9 ^$ K5 k

  h! q' V" e9 ]
20200505194802587.png

. g+ B& C8 q5 W- S
# d' F9 B8 w# z/ C8 L0 [' u0 v 非对称PWM模式
" l1 |2 }5 b0 g  c  m6 R$ M3 a$ @+ o
20200505195057399.png
$ q: ~7 j2 Y& a. q8 Y  I6 b

3 h& B& y# N2 c% z4 q) m三相组合PWM模式- s, q. C: t, h# m
20200505195420730.png
5 B" y; b( Z0 ?& p: b

6 U( s4 G3 H$ ~2 t) B. V9 g5 m 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。) u! G& ?' z9 F/ C6 N8 S
! R+ J  Z) r5 p* A' k: u( Q
20200505195905197.png

' C) \' ~) i" k
0 Z& J$ V' i5 }2 V, t2 v TIM2定时器实验5 d  e1 z7 |" E; Y: `
本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。
: O4 u6 y  g1 x: w+ A& e! s
2 B; i9 h+ ?9 K' t如何计算定时器周期?' v* X8 {9 r1 p; R
/ L- A- C8 q* E; h
1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
+ G: e" E5 e2 p+ H
( |3 W+ l# |7 d1 H8 `
20200505220029633.png

- G- N! _. S3 ]$ m$ j6 w  u/ B" e) S3 h! i4 v# Z0 n8 |# T+ @9 X
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
0 ], _" |! B* A7 S, I3 K' S" k+ j) A0 y( R8 Z
如 64MHz / 6400=10000Hz) v& d- T* U. E- z

5 I, G- H0 \  d3、确定ARR的值,ARR=CK_CNT* t(s)," o* F% O0 W  Y
+ Z# z4 O1 A4 Q
如要1秒周期,10000Hz*1s=10000。) V$ `8 r- P: J5 T) V! k
5 ^8 m3 Q: n& f3 h( {3 a& _) ]
实验代码
! O3 e% A6 E1 x- U. ~2 B& p1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
8 l1 k- ^# ~. f; Y* Q# T
- V  W( c+ Z) f6 d$ [/ w+ f2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
7 o4 {" W( _$ g- V1 |0 f* k" U6 [
20200419170920422.png
" c6 @. D, I5 q( M' G7 M5 O

0 J& F" r* H* ]6 \- ]' c6 F
20200505223426701.png
0 A/ [& o8 [) R  `* f# M# w
+ u# }- e+ l- V" i
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
/ g) A# H( z: Y- s) M3 r, \% q8 c8 B. ]0 B  n3 ]* D
20200505223701644.png
! o; R# {# A* _' L3 g
  w; ], g, E: p$ u! S7 i$ A
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
3 m6 C0 T: v, s# ]2 i2 V/ L% V. {
  e- {  m! f+ u* p1 @- N; N5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值( s& T6 @0 k0 s
  S8 p# d% v3 c$ C( n- _8 ?2 N
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT% e0 o# o! N- n4 D# n/ C

: T) l' k: t- c# g: u5 i
20200505225312371.png

, ~1 k0 E) Q4 R1 i
9 a7 \) D* e& Q4 m. S( j6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"2 N* Z3 X& s; X, h
8 \, }9 ]# C) w9 o
20200505225419137.png

5 |, d: r1 l* M7 \
9 J* z$ L! L% O. P. A; b7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。7 i: I1 r6 b. ?1 i

" |+ b% o% y5 {# h/ `) l$ e
20200505225614187.png

6 u* X9 R: A" o; \6 R  Y" z9 Y0 p  ?) r
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
2 T3 f: N( G! N# L0 f
6 _: F6 F& F- D( v: Y  a# v1 D
  1. int main(void)
    ' w5 g: T% X% [, M$ Q* J# U* C
  2. {9 o  O/ F" p9 V5 `
  3.   **9 U9 e9 y5 t2 |5 d) J, u% q
  4.   **
    & i* q1 n4 ]* D5 T0 Y5 i
  5.   MX_GPIO_Init();  f" i& K8 E. K* k
  6.   MX_TIM2_Init();
    & c8 P* h8 r8 _( ?! J( j( T: P
  7.   /* USER CODE BEGIN 2 */
      e1 B- R8 v$ k) C4 ]
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    ; H# N4 W* }( l
  9.   /* USER CODE END 2 */
    . r9 f) D" D! a9 V3 N% J9 p
  10.   **5 Q# O$ ]  ]/ z1 M5 a2 _
  11.   **
复制代码

8 V. V; x9 y% H! \1 m& g9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中, W! h# o; _: s
* N" _% U# b) C0 u' e2 G4 K
  1. <span style="background-color: rgb(255, 255, 255);">/</span>*
    * u/ A' V: r; i* w2 A
  2. *stm32g0xx_hal_tim.c. u' |/ ]' g, l( a
  3. */
    . c  w' h: Z# `4 H/ G6 ?6 H2 C
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    + {. g* ^8 d, D* N& M5 u
  5. {8 @9 ^4 t! C+ B- z9 |
  6.   /* Prevent unused argument(s) compilation warning */  I1 H* U1 l; k) H/ s
  7.   UNUSED(htim);
    + ^! S7 }3 {6 C! T% U
  8. 2 q, w7 z$ P' i. i8 i
  9.   /* NOTE : This function should not be modified, when the callback is needed,
    9 V% f, v8 y* \5 D! `
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    + h/ K  n9 H+ @6 _
  11.    */
    0 s$ `- j; S* L( u
  12. }
复制代码

9 X9 f6 _4 m0 V10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
; D1 f5 V( \4 S6 P$ G! T+ V, f! y, F) R; X. C; i8 C
  1. /* USER CODE BEGIN 4 */7 ^$ g+ s3 ~- `
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    ! s  \  I  q* Z. J: U' D
  3. {
    5 h$ q) ^' c! F# X- e0 L
  4.   /* Prevent unused argument(s) compilation warning */
    , W( s8 f7 M4 n( ^
  5.   UNUSED(htim);
    # i& U8 Z1 D6 a2 P, H5 K
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平2 V3 C) ]! W; q& G
  7. }# c# k5 s' f$ p1 K) i3 x1 K
  8. /* USER CODE END 4 */
复制代码

7 F8 f; y/ @9 L- M( A2 {2 e/ ~; G& i9 U) _4 T4 A! g7 j

5 z1 y* s% `3 [1 I' B- s9 h* @" f; D4 J. m: S1 Z

4 ^3 c; S: T  Q6 u7 t5 s
$ X+ E& `6 y+ ^
+ R0 u. ?9 Q$ k7 I/ ~, a+ a
20200505200041645.png
收藏 评论0 发布时间:2021-11-8 16:49

举报

0个回答

所属标签

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