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

STM32G0学习手册——使用定时器中断(HAL库)

[复制链接]
STMCU小助手 发布时间:2022-10-31 10:47
定时器分类
4 p* w$ Q+ \- J3 z7 c0 }4 w- ]( ?( o$ pG0系列有TIM1、TIM2、TIM3、TIM6、TIM7、TIM14、TIM15、TIM16、TIM17,它们区别如下图
, }7 Q7 \4 l% r4 U: S) {# J. r7 l2 c4 }0 Z
其中TIM1为高级定时器;TIM2/3/14/15/16/17为通用定时器,TIM2支持32bit;TIM6/7为基本定时器% B& I  B% g4 K/ c6 ]
: y* }# C/ L- A) O
20200505192122130.jpg & Q7 ]$ J0 `5 C- ]2 {/ ]: A: b) u

2 ?+ m3 z# k1 ^# ^ 20200505192148321.jpg
  j6 Z# K% _# F' o0 u+ p! N$ j9 n* B9 n4 L* H1 n4 v& F7 P. ]: E
计时器时序图4 M, L% S4 I! s7 g: R
TIM1,TIM2,TIM3支持(中央对齐)向上向下模式,方向在向上向下时发生变化,减少对电机的噪声干扰。! g" G3 j, A- S* M8 J
9 K) q2 R& i0 Z8 K& H" \' ]1 p0 p
20200505193407758.png 6 m: Y; t( \# I
# V6 J3 G, Q( @
20200505194318226.png
3 b- o% }+ \1 d. i! [# T& O9 i5 h  \4 i0 a- w# O) o' ?6 Q
基本PWM模式,边缘或者中央对齐模式4 B- }- W7 S; B: Z
% s" G2 P6 f* S" _- {1 H
20200505194802587.png 7 r6 I- q$ F7 x/ o% e! q7 u) q5 }6 v

8 r, p) ]1 u  s( d* H& [5 F% f% E 非对称PWM模式
; v# w6 f3 d! t1 a, V3 b, q! V4 Z5 Q0 F! Q$ z' ]3 y; [9 T! B
20200505195057399.png
, Z: p- w9 v9 L9 K# e* L
: N, E/ S1 E2 r5 g+ J& U三相组合PWM模式4 _' k; h: ?, d. R1 U& P1 A
20200505195420730.png
: n. X( a1 b$ y$ X8 ]  Y; \% b* z) g" N/ E
可变频率pwm,由外部信号驱动。                                           逐周期控制的占空比。
) W2 _" U- V; e& r9 }
' b6 p, E9 H& ^; ?4 U2 B 20200505195905197.png
( `( O+ o% M1 D# j; c5 X$ l
4 D& {; A" g- D8 e1 K 20200505200041645.png
# t( g0 U0 y4 h7 `6 _; s6 K" F( l8 c+ K7 W8 Q6 n

: Q8 b( `  e' C0 y/ p! Y. w* G1 s TIM2定时器实验

% {/ G8 N! i+ O8 n) i. O本次实验,我们选择TIM2定时器,通过设置预分频系数(PSC减去1)和计数器周期(ARR减去1)的数值,来控制整个定时器周期。让定时器周期进入中断,在中断函数中翻转PC6引脚电平,达到闪烁的目的。! F+ A" t6 f% ~1 p
9 P% h3 L, w. k$ V- r9 k* ^
如何计算定时器周期?
- B& f- f8 y# `
' i! e/ ~& U* C& v; y+ X! A1、在时钟树中确定好TPCLK频率,这里已最大化频率运行;2 t. u5 T$ l. G% Z# A8 z

5 \2 i( F$ O( G 20200505220029633.png - j9 y' h8 B0 E! a
8 f. q8 Y) P  n6 t% R4 e. V
2、确定CK_CNT的值 ,CK_CNT=TPCLK / PSC,为了便于计算我们一般都是将CK_CNT的值化为整数,
% R% T- l1 Y6 S4 d8 q* s& Q% f7 d1 {1 T' p: E
如 64MHz / 6400=10000Hz
! V5 D* F3 w) z! A- R. Z7 m! X, |9 Z$ I/ d7 f! H$ \! O
3、确定ARR的值,ARR=CK_CNT* t(s),
9 Y: ]7 Q; k" p6 J, z" q4 L" \2 f4 t6 u% \: f- B4 I
如要1秒周期,10000Hz*1s=10000。
9 G1 h- I# M) w/ y" p) {2 O3 _: Q' C5 ~
0 d  R* E9 H  I& q8 @/ b
实验代码. e) X7 X6 h! ]' |7 w9 k& Y
1、新建芯片工程,"SYS"打开"Serial Wire"调试接口,"RCC"中HSE使用"Crystal/Ceramic Resonator";
  ]8 L0 a9 Y: M. k* i! \6 v
' \4 ^! g$ ~' m' c2、在"Pinout view"中设置PC6为GPIO_Output,默认电平为low,开漏模式,不上下拉,速率为低
& c! Y! o. y5 M* [) t
3 _! h) {7 q2 {7 ]& a. f6 O6 ] 20200419170920422.png ! v% g+ I# n+ T3 L. S, p; r/ {
) _' ^3 w1 d% a$ h( h8 N0 b  Q
20200505223426701.png
0 W0 \2 c% p+ O5 a
8 ]$ N7 Z: Y% t# o% n, ]" q3、设置时钟树,使用HSE、PLLCLK,HCLK为64,APB分频系数为1,APB时钟为64
* X" v% s0 ]1 g, u6 r3 H8 \9 m4 d$ H5 |1 y* S; J6 m
20200505223701644.png 1 m5 o# ~" x' L. g& ]2 G
5 m& Z, V+ m  }; V$ e, z
4、 设置TIM2,在TIM2选项卡中,"Clock Source"选择"Internal Clock"* W" o; v, r0 Q( p
& V4 x0 u$ H( T3 \9 \% J
5、下面"Counter Settings",Prescaler填入"6400-1",Counter Mode(计数模式)"Up",Counter Period填入"10000-1",其他参数默认值
1 Q. Z! ?+ ]) C" N: B' ]9 D/ R$ a% z. h* A# Y
如想要1秒周期,ARR=10000,PSC=TPCLK / CK_CNT* C2 f4 F( `% ^3 I4 j( N4 u
( ]7 ~3 O; Z* c( ^  Q7 E- u7 S* j
20200505225312371.png 9 G" _. c( Y$ Q/ ~
% _9 j+ q- ~% b. N& t& ?: i8 A8 j
6、在"NVIC"中,配置页面中找到"TIM2 global interrupt"使能,优先级选择"2"
2 E% E% }5 H" g" c) F5 C- x7 h' p" ]/ r( I% L
20200505225419137.png
) @4 w6 B, T. l& a2 @% B6 O5 y3 x- X- F5 ^( @' s
7、在Project Manager中填入项目名,IDE版本“MDK-ARM   V5”,在Code Generator打上勾,生成代码。
# d6 u% L) Y& Q9 _4 Y4 l5 q/ ~6 ?( H# @0 s6 u0 h$ b4 p8 ?
20200505225614187.png
* r4 f( O2 V( ?6 M' N  Q4 y/ c6 R% Q0 e2 W3 K" k+ e
8、在main.c文件,int main函数里面,在代码MX_TIM2_Init()定时器初始化后面加上定时器中断初始化函数
! D$ _! q: m" t  C- G. F
6 c2 E1 F9 G/ x1 L2 M
  1. int main(void)% [; p9 z# v8 D, Q. v. J
  2. {' d4 }+ q- e' @
  3.   **
    % {% h' i" ?: Z5 C/ z# p
  4.   **0 F2 H7 ?5 V% ^% h$ J/ Q7 V
  5.   MX_GPIO_Init();
    9 m5 O4 B; o/ W, c7 M
  6.   MX_TIM2_Init();+ n7 W4 ~- S0 G& x5 r( u- ]& Z/ Q
  7.   /* USER CODE BEGIN 2 */
    5 m( e! a1 c6 ^
  8.     HAL_TIM_Base_Start_IT(&htim2);          //初始化定时器中断
    8 @0 z, S8 c- [2 K8 W" q
  9.   /* USER CODE END 2 */
    . {! a  B% h9 U$ x9 R# a
  10.   **  ?) \# a& ^( G. a
  11.   **
复制代码
2 R( k# ?2 y3 G, ]4 O
9、定时器中断函数原型为void TIM2_IRQHandler(void),里面调用了HAL_TIM_IRQHandler(&htim2),该函数有很多个中断回调函数,我们这个定时器更新中断,找到我们需要的函数HAL_TIM_PeriodElapsedCallback(htim),需要手动写这个回调函数,把一下函数复制到main.c文件中1 {% W/ k, Q4 l; K
% k6 ~; G" r( M) r
  1. /*
    7 G3 O# M( Q  p2 }* w) Q* m
  2. *stm32g0xx_hal_tim.c
    . z9 C2 z+ v3 x
  3. */
    ! ?" O$ L( M2 m$ U# h
  4. __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    ( q/ y% M: e: e2 g4 `
  5. {; O; G8 i$ L: e; ]5 Y
  6.   /* Prevent unused argument(s) compilation warning */
    6 @# @) N. \6 A  H! w
  7.   UNUSED(htim);: `( D$ ^9 g( H
  8. 8 S6 k+ x2 L5 @6 J
  9.   /* NOTE : This function should not be modified, when the callback is needed,
    % N# c# j5 m+ x- h2 b# V
  10.             the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
    : e9 T9 u- D: A6 C$ Z2 @5 v
  11.    */6 _; q2 Z* K: f4 ]6 {
  12. }
复制代码
% ]* n5 [* D; Y* b7 P% b
10、在int main(){}后面编写代码,编译,debug中勾上"Reset and Run"烧录固件,就能在开发板上看到输出闪烁。% t1 E4 i  i1 f

' K' G* Z; a% b1 H: }+ z8 \
  1. /* USER CODE BEGIN 4 */
    ( u% l0 k) r3 s
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)# b# Q1 u) O- O
  3. {
    ' B0 h( z) Q  q8 }! }
  4.   /* Prevent unused argument(s) compilation warning */
    - E2 f) x$ E) o' R$ X: \
  5.   UNUSED(htim);; l; P: v' j" |: ]
  6.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_6);            //只有定时器有中断,就翻转一次引脚电平
    . |& \0 t2 P' ^4 w
  7. }
    % Z; c* t1 w5 u$ d
  8. /* USER CODE END 4 */
复制代码

9 L& M4 N$ o' q7 w————————————————
2 x* W# j# u% n" F4 P/ s8 o版权声明:SCCELE
; f0 s  q8 ]/ P" _
# `" \2 @) ]  x3 p5 A" ^. S" J6 x2 U* {9 d* i) G, D
赞 收藏 评论0 发布时间:2022-10-31 10:47

举报

0个回答

所属标签

相似技术帖

官网相关资源

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