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

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

[复制链接]
STMCU小助手 发布时间:2021-12-9 11:21
定时器分类
! _' e5 h( j3 SG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图' n& Z4 J, \2 Y! {

7 j' f4 `- E/ ~4 ?其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器
9 [& n# K5 W8 H0 R0 X: f/ d8 |$ K7 K# {( w. e, H
20200505192122130.jpg

" V  M) W3 c9 u/ c+ D0 i( E5 L/ U- J* \3 \" @2 \& a/ s
20200505192148321.jpg

* v  C0 _" ]$ D  i8 O9 e+ {. A7 ]9 c
计时器时序图
5 E) y- J1 t4 S# y- d1 {) C
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。
9 P; v7 ?* g' j8 K6 O, h/ u* v1 \( K8 n$ {) H
20200505193407758.png

9 m. Y8 i2 s8 H0 i' A$ C6 D
7 Z, r" N, k9 @6 ~. C. _6 q
20200505194318226.png
; }' U( D8 Y0 i* i8 U$ t

7 _. d, w( F' I$ }( n" s/ t 基本PWM模式,边缘或者中央对齐模式
6 P5 e( q8 O  L  u, ~; q% V* c  T* ^  C9 I
20200505194802587.png
6 [1 x" F6 l- _' x* L, ?' F$ F" q
: M4 h' K8 f$ n& E% ]8 A
非对称PWM模式
# r  Y, J+ }& V
( e  ^/ N0 r* m4 V
20200505195057399.png
7 `/ m7 _, p4 |: J- a0 D9 ^# p
- Z/ m- H6 X+ N6 w
三相组合PWM模式
/ Y7 m6 B& x$ L" G; {
2 ^1 N" q9 l8 h3 `" x( ?( c
20200505195420730.png
# G: J; J1 r( ^( z. U

% t  t2 }% ^: F7 L. P. A 可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
$ T( Y( ]. m% m% V( X: Z- E3 L! M& C( s. x  N/ X7 F, D* d" X
20200505195905197.png

  l6 ?$ F/ \4 j2 f6 \& |% f; V3 I6 r/ d) z1 E8 ?* A5 S- g1 J2 {( N) a
20200505200041645.png

" C2 C! @/ r: O0 f8 N% v
1 v. _1 x6 E+ C/ Y6 \' w TIM2定时器实验
7 s0 ~9 Q$ ^' m9 |本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。
% i: W/ w4 M  U/ p4 h
( t0 Y8 o' k. V% y5 A9 Y如何计算定时器周期?
% d7 E4 F) Q4 S) C+ Z) a
/ w9 a& R, W) d$ R% ?: R: V1 Y! x& A: O1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;
/ y" O8 A5 A/ E" u* v0 j& E- I, P. V: d2 ]6 B
20200505220029633.png

4 a1 E3 M- U: U% o! y) ?! f& ?$ }; A  u& a4 M. _/ T* X% [
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
; d6 Y, V- d- r0 ^  {) z7 K- D5 t+ {) s# G! `4 s8 o1 S
如 64MHz / 6400=10000Hz( b7 R' _4 ?" P& R
: Z4 k! M; {" u
3、确定ARR的值,ARR=CK_CNT* t(s),  D! L! F" e2 |6 @6 A( C

/ t) p/ E( q& T+ K8 I8 [9 G6 L+ \如要1秒周期,10000Hz*1s=10000。
% l! C1 ^; U+ b0 }' o  h5 j  r& H+ a' L7 l" o) h
实验代码
- m6 V; I2 t) R# x1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
8 C- d  j0 B- w( k: q7 b6 G1 i  X" o! N0 s
- k3 _5 o2 ]* n2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低2 Z$ s9 R% N& M
1 t" w: p& H$ ?2 v. v
20200419170920422.png
% |% P9 ]1 Y- M
2 N9 w6 J2 O- \
20200505223426701.png

' V: g* _2 ?( N8 Z0 p( E2 T; R/ P: n$ C$ X
3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64& R- @6 U0 W, b7 Z+ a, |  u

! D1 y. a; x. d# i( m( P8 I* G' d- ~
20200505223701644.png

. @' r+ S1 d% c' \! x9 M4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"
; q1 a; ~* w; X; C: A" o1 I( r. N
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值; Y( m: ^3 i$ {, X: T& r3 x

6 m1 i8 K" z' _- t9 u* ]$ Z% ?$ T& A如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT
# Y( C2 u0 `! u( p, D! {8 }; b4 g/ W0 P3 A4 e
20200505225312371.png
4 c+ @' w3 D) B  t) ~( C
3 v8 p2 t6 N% L7 B% n5 v" l
6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"/ \% m" F: w5 x( t% C0 J% E/ H

8 w6 c" O% m* Y; j6 N3 |
20200505225419137.png
# x: I* F& D# M( Z9 D

9 {% K. z) w. ], ^  S, `7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。7 x( ]1 R: s& I3 Z  p7 Y$ }3 J
' v  @( ^) d  w( v1 [0 F2 o
20200505225614187.png

0 x! f$ p/ }, o1 r
% Q: i6 r; I5 N8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数0 ?5 M7 ~3 S) U3 `, C
* f3 P; _% b  i$ H1 q' A. p5 H
  1. int main(void)
    ! m8 D' C. E2 h* n( H
  2. {
    ) r/ j) T$ ]! o) S8 @$ w# [
  3.   **& i0 P) c7 n( N# |! v% \9 \
  4.   **4 T9 \0 O) o& ]' h: }, x3 n/ y
  5.   MX_GPIO_Init();
    , @. b6 e# W, S" ?) t8 d- @
  6.   MX_TIM2_Init();
    , f0 p: Z) Z$ u* x
  7.   /* USER CODE BEGIN 2 */
    & |0 w! o- y8 p
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断3 U2 ]. C# z& S  u
  9.   /* USER CODE END 2 */
    9 s# O5 ~2 N& K4 [
  10.   **
    * Y; `9 Q* l$ h2 j+ J
  11.   **
复制代码
8 o& C' ?$ U) }6 ^7 O6 n% f
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中
" N* ?. H9 p& Y" @$ O$ x$ e
3 @" I  C( k- L. C* z+ X1 T
  1. /*
    ; Y1 o+ g: w$ ]. n
  2. *stm32g0xx_hal_tim.c) v+ h) x# }5 G* E, I0 E
  3. */
    " B6 ]- D( L! V& b" c( C- v
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)# F' K! @5 O/ k) S5 {. j# v
  5. {
    2 j) x( n3 z4 T
  6.   /* Prevent unused argument(s) compilation warning */
    ( d: e* g" y' y0 a/ \3 q
  7.   UNUSED(htim);: y* `) i1 D1 D
  8. 9 ~2 i: m: N- P) H
  9.   /* NOTE : This function should not be modified, when the callback is needed,8 H, z$ Z/ [! |9 P3 w
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file' _1 N% y- N0 Y' \9 Y/ T
  11.    */
    * o$ }- r: x5 V) w% h
  12. }
复制代码
3 z  o% d: C, L) v5 b
10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。% y* b8 h8 _, d) }* Q) S/ w
( y# K. n5 \8 H* q$ p0 Q" n
  1. /* USER CODE BEGIN 4 */
    0 g; k& F! Y& X  Z9 s  e9 t2 ]
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)1 ]8 N1 u- `7 x. a: l) g; @/ H
  3. {
    ( X* Z6 @% ~$ s! j1 x
  4.   /* Prevent unused argument(s) compilation warning */6 o# R! R' M: D) k+ |
  5.   UNUSED(htim);  p# }% U8 q$ R! J' X
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    $ |0 G8 y( G* N
  7. }
    ! Z9 n. z5 ]8 D' I! Y/ Y& K
  8. /* USER CODE END 4 */) C, w2 j+ ?2 D: f% B9 S
  9. ) K$ O8 c. I$ j
复制代码

8 z" E- |/ r$ F# T( @' }/ t# C
收藏 评论0 发布时间:2021-12-9 11:21

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版