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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类
$ [  b' u% H9 m( |5 Q1 G4 _G0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图/ T7 i- C  J1 i
* I" C( i( V  v5 R1 D0 @: O
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
/ i7 {+ N% L7 {1 B; X- I1 c$ B9 F, h4 X
20200505192122130.jpg
; D$ R: V7 Y7 _( n6 Z
3 ]+ C4 ^6 `) K- y4 O
20200505192148321.jpg

* q0 O( w3 k; c( s: {5 x# X( z' ]: X
1 n# |  c8 I' R* R 计时器时序图
* P  w2 L* @: l( ~* ^
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
: E+ N0 g) F1 G7 ^9 o, N' q+ C$ q$ e, g9 a) y
20200505193407758.png

& S/ d. r+ g' `1 H
& R0 v: j/ e+ R2 U
20200505194318226.png
# _" U# L' v( F

5 v/ }- Y1 c1 @/ z$ f3 i2 I/ T 基本PWM模式,边缘或者中央对齐模式
7 W- v2 ^8 k) U
4 Q9 S* F$ L$ \8 D
20200505194802587.png
/ ]) c6 o* H; }5 v% x

( j  z7 O5 r" D0 s/ n 非对称PWM模式: _/ s5 f  h, h$ ]4 e

* p! ]% b' |$ N8 }+ M
20200505195057399.png
: k2 ^* p1 y1 g# G& W5 r" G

% W1 |4 Q% {9 N" x; T& h( i) k三相组合PWM模式
4 b0 Q9 y' V5 M# E1 m% V/ `
. \2 S7 M9 W& I: \& m) ]! h* y
20200505195420730.png

  K. S0 R& Q1 h, o7 q' ~
; I3 u9 G' l8 Q3 B, Y5 ]; N 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
9 k; N- [* f0 `& }$ J6 @( Z# `* C% |7 S' q8 r. M6 k9 a0 d
20200505195905197.png

$ v% p# C/ J$ B- i4 t- Q. @( ^2 R1 t  ?, p! u: U; y. [
20200505200041645.png

4 Z8 J1 Z' x; i* r
) `3 e% m: o1 `0 _ TIM2定时器实验
9 H) Q3 E! P/ v" C! `本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。* a; d, \- C3 z4 K; G0 ~1 `8 k! V

! t' N' `8 H/ Q$ g  e3 t7 ~3 j如何计算定时器周期?
# r8 q2 e, F" Z. `7 p6 t& |
. ]( w3 p, T( n* s+ R1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
0 S5 L0 Y% v, h4 U2 N
/ S4 Y1 q+ S2 S. {7 P& t0 x, Y9 Z
20200505220029633.png

" T9 O) e7 j5 W0 ~8 Q  B1 I. N& V& I  g
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
1 `  ^6 A0 D. I/ N( a; Y, Q+ {! G2 M  W' t6 a9 k6 \- `+ t
如 64MHz / 6400=10000Hz. X( U" O1 }& n: ?

! {0 A: G7 @$ y8 P; H# n5 o' |, D3、确定ARR的值,ARR=CK_CNT* t(s),
- w& b1 ^' y; e! B' R" B* U( m* t9 z6 \% X- |9 T
如要1秒周期,10000Hz*1s=10000。+ K- }% Q) D/ n! d& v
' s) d% k: J+ a1 `; n( s, Q, L- c
实验代码
3 K+ A& P$ o' c  d4 H; z1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";" \3 h5 I8 C" N! e/ Q% {. P

# |. c7 U, o, m& }% M2 @) z2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
* R. S6 q; G4 o) H9 V' e, F0 e/ w: \+ b0 `
20200419170920422.png

) y& q) C( s5 Q% K, H+ G3 D2 S8 L! [( z
20200505223426701.png
% i. i' l: v2 z# D& k, `
" E+ d" u* }" D  G, O: ]. {+ {+ l
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
2 @* j* N2 w4 o/ T/ j9 z! l/ d' p& B: p
20200505223701644.png

: O, C; y0 P( b9 W+ Z) f4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
; g$ Y5 r& z& L; c9 z4 l! Y9 R
) c: u+ j3 p2 [, `: L5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
( Z1 p5 \; w+ E* ~' K8 f8 e) n& e' x2 a7 k' G4 d
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
0 R6 ]( V' W; ?1 b" q- |, g+ x/ \& P0 v
20200505225312371.png

0 K6 C3 o% a4 v
  n' O2 F6 }* [! J6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"" ^+ y3 j' U4 f. I, y, Q

% n+ ], ^  A9 ]$ F7 U
20200505225419137.png
  l& Y$ w  H- s4 r
4 b# W( m( X& m, `- w% ?
7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。* B% [3 R0 s# ^. {9 W. z  i

  w6 }2 z+ Y& k3 M, a
20200505225614187.png

4 V: u4 S+ p! {
$ {" A/ e. [0 P9 K' ^9 q( Y8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
! }- ]% y* G/ X6 a# s4 M  V; d/ e) q0 n8 t
  1. int main(void)# p; j! g$ _: W! Y9 n
  2. {& A; s; p( ?) b0 f! y3 o
  3.   **
    , t) J, ]: g4 m/ \- S/ w
  4.   **8 G: B; J" a( M( ^8 o* E
  5.   MX_GPIO_Init();
    ( }" h. |" q7 ]2 O' m
  6.   MX_TIM2_Init();" ]: W% W4 F8 c% E0 G
  7.   /* USER CODE BEGIN 2 */
    # R: H0 @: y' ?' |7 _2 H: U: z
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    ( ^, }. h7 l* f( b; H+ W1 d. @9 w' |
  9.   /* USER CODE END 2 */
    8 m# c# k! l* y3 j
  10.   **
    , v1 n4 L& s, j1 U" Q+ a
  11.   **
复制代码

, ]$ }- n' m4 w3 U. Y# C4 `9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
  R8 v) l, n/ x! p$ K! V
. X5 e( d0 Z5 x! y: _3 a
  1. /*
    0 r; Z: q; o/ T8 `
  2. *stm32g0xx_hal_tim.c
    7 k( F! f! k( z. L# D
  3. */' L( n: Q: b0 f, n; w: n
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    : V  g% x- D0 C8 |% A8 J$ r% V. b
  5. {
    + g7 T/ Z1 C; w" x; a/ l
  6.   /* Prevent unused argument(s) compilation warning */
    0 E& s: k( ~! b5 Q" o6 X
  7.   UNUSED(htim);9 L3 z2 H# }/ C
  8. + z, U: q% q( S! j8 F6 O% E6 \
  9.   /* NOTE : This function should not be modified, when the callback is needed,: }7 j8 P) X- I4 w) o/ u
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file3 O6 ]" ?( N* T2 u* ~
  11.    */& m' s- F* O! x; ~0 t9 C
  12. }
复制代码

0 k9 S) {4 e) D! L, X, U# x$ [10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。
3 _- C# ]. B6 @5 Z. T) z7 w, E& u9 p8 |# g4 @$ r
  1. /* USER CODE BEGIN 4 */& x* |% b/ D! ?+ {& ]
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)0 S7 ~$ n% s6 T# o7 I6 j  y
  3. {& f7 }' h* A% W
  4.   /* Prevent unused argument(s) compilation warning */
    3 _- o: x+ @7 Q- Y8 H' x1 _7 K
  5.   UNUSED(htim);
    . L& V6 U& x& x. @) k: F
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    5 a' E$ q( D6 l* M5 h
  7. }
    " R- h1 [) c  K% {9 b8 {
  8. /* USER CODE END 4 */7 {& Y0 v5 T  p% _# B5 m

  9. & L6 {. x" m0 `& T* E) _
复制代码
( k9 \/ j7 h. I  D$ E1 B" O) w' k( _
收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似分享

官网相关资源

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