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

玩转STM32CubeMX | 定时器中断

[复制链接]
STMCU-管管 发布时间:2020-12-1 12:45
玩转STM32CubeMX | 定时器中断
1.定时器中断0 x9 G% E1 L0 r3 _8 [3 R; F

& K! \" F' h5 H! b, T- ESTM32的定时器功能十分强大,有高级定时器(TIM1和TIM8)、通用定时器(TIM2~TIM5)和基本定时器(TIM6和TIM7);本实验主要介绍难度适中的通用定时器,通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。; Y0 c* f3 M5 O4 B
通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:6 Q# U: h6 p# \" b. L2 ^

( U6 k) \3 \/ H; E' h$ _
9 j* z; _+ R+ Q1 U
可编程的自由运行递减计算器4 O: x/ i) E" x/ W
. ]$ K, b, y7 H" K- e: W4 g0 w
9 d; `( K& v! l+ `7 c
条件复位:当递减计数器的值小于0x40,则产生复位;当递减计数器在窗口外被重新装载,则产生复位. W& z5 W- q6 O

6 y) a) o% w( N3 e1 A+ u
) H8 Z$ u7 ]6 G5 Z5 ^# p: \- E5 j) P
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可用于重新装载计数器以避免WWDG复位
' I# n+ n, R& M. D* W( z. x* h) r; r9 Q( w

# D% D$ I& r* e) P! h& Z16位向上、向下、向上/向下自动装载计数器, u! _, r8 d8 v: \3 i+ }- S: f* O
5 i9 ^9 ^, G& o/ d. Q9 e; R
! `' ?7 _5 V8 f7 A
16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值1 U( j- _4 \! ~  G$ X
" T+ y+ Q# |: @% I
8 |/ a% X" _- A) K) \# F
4个独立通道:输入捕获;输出比较;PWM生成(边缘或中间对齐模式);单脉冲模式输出$ W! T: _2 A' T  m  ^; R5 t& b) j
5 t9 u: h& T9 T' s. K5 g" `
/ {6 g* ?  ^# s* P0 H/ i' S& l
使用外部信号控制定时器和定时器互连的同步电路  t  h$ z4 z0 A- k* X# C$ h
; E3 j! n: D$ e/ f% P+ B: O

9 ^" g' A5 [9 T* L9 c# |如下事件发生时产生中断/DMA:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发);触发事件(计数器启动、停止、初始化或者由内部/外部触发计数);输入捕获;输出比较9 E" ?0 s2 M$ j) l, g! P8 u' l3 r
  N5 T1 r1 n/ o  s* X) d

3 S9 N, X5 U3 ^  r5 t支持针对定位的增量(正交)编码器和霍尔传感器电路
; J  e/ d+ a2 e2 h7 S" I$ v+ `) L( B9 K: _* s  H

6 B6 }, q- W$ X$ z+ q" J触发输入作为外部时钟或者按周期的电流管理3 H- r: Z+ S: r; ^2 C  \* S
& k+ K' U9 g* `1 j0 }& `' w

7 G3 J. b, m  }8 {- a1 O9 R通用定时器框图
, A- C$ t/ d# @
1.png
定时器时基部分& v9 V: {* V8 C/ k
2.png
2.硬件设计
# T0 i+ ]# N, q1 y' e  M! M( `/ A# @1 ~2 E( C3 Y! m$ Z
- Q2 d5 s* y2 N' m  J* I
1 q! g! m; ]4 S# c

$ @& i2 N" h, y$ R- D- M5 F+ G本实验通过TIM3的中断来控制D1的亮灭,需要用到的硬件资源有:) g8 q+ T; |9 R: H) Q; g; F# ?: h

2 Z* a, }( I% U( J" l4 I/ p

. M0 {8 T+ t2 x+ a# S% N' P/ T·指示灯D1和D2# r; o) \. ~4 }$ o0 e
·定时器TIM3
+ M! Y% x# K% b( ^" I6 W
3.png
3.软件设计
8 \0 O' q$ T2 F
, B, W# |+ X+ @6 M

8 {/ g0 w: d: V# w: \+ w3.1 STM32CubeMX设置9 O5 R4 z4 x$ N$ u2 y' b

9 {: l- h5 X2 y8 s& B
6 w8 ]3 U3 ^% W0 f- g
➡️ RCC设置外接HSE,时钟设置为72M;TIM3的时钟挂载在APB1 Time Clocks上为72MHz" U. I% z5 E# |; F1 `* T" {

1 i; ?) V! ^) I* n( t

9 \, ~3 G+ z: v% F6 N➡️ PC0和PC1设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
* A* @0 h, r  P6 _( I% n/ N* S1 p
( I  O+ W* {9 E- G' N
! x& I/ ]8 E2 _8 m) T
➡️ 激活TIM3定时器,时钟源选择为内部时钟,PSC预分频设置为7200-1,向上计数,自动重装载值(ARR)设置为10000-1,在NVIC设置中激活TIM3定时器中断;根据公式可算出:计数器时钟CK_CNT = 72M/7200 = 10000Hz,计时器中断时间为 ARR/10000 = 1s
4 I3 x' e0 P$ u! c* t
4.png
➡️输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码) e0 S5 J" G. W* h

. `$ x0 D& q, h
, c& a" x. F! l) N' H2 p
3.2 MDK-ARM软件编程
: u' W" B$ ^: b: a( K: v➡️ 在tim.c文件中可以看到定时器的初始化函数
0 m, N. o) W& S
  1. void MX_TIM3_Init(void){
    . N5 T1 g7 ~) U* S
  2.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};- S5 u8 M; p, d2 q# [
  3.   TIM_MasterConfigTypeDef sMasterConfig = {0};5 }' ]  W2 `6 S1 x

  4. % l" Y) A) W( s6 l! q8 `
  5.   htim3.Instance = TIM3;, ~7 l( Z% j8 G* w6 a
  6.   htim3.Init.Prescaler = 7200-1;
    9 ~1 f2 ~" v/ n% |& [6 Z: u( u
  7.   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;7 Q/ B, M- A! ~0 P7 u: g. F" z
  8.   htim3.Init.Period = 10000-1;, X6 b7 B5 B2 k+ p$ V
  9.   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;( a# T: g0 [8 e9 |( \+ e
  10.   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;3 d  R; m. E" V* U; x; G
  11.   if (HAL_TIM_Base_Init(&htim3) != HAL_OK){
    9 m" N7 Q/ H- P' A+ _
  12.     Error_Handler();
    . g6 Q; C" G2 `6 s0 @8 [
  13.   }9 N. f  }; i* U. l2 G
  14.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;( x9 ?2 i4 s5 Y8 k3 G( t
  15.   if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK){: v1 E9 c0 h/ M( c" g! K1 M; T( a
  16.     Error_Handler();- J9 q5 j- T# i
  17.   }- h/ N* R0 j  P) w5 ^5 v
  18.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;3 I$ p$ h' V+ m. p2 E! i( N
  19.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    + H" B+ x" ?  M/ ~
  20.   if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK){" k' m- W) }0 @' O+ |
  21.     Error_Handler();2 s3 D4 J! C/ C( a: e
  22.   }
    ( u: _# ?2 g: Y  b/ T0 H
  23. }
复制代码
找到弱符号周期运行回调函数原型,并在tim.c中自定义该回调函数5 h2 e: `6 _6 G! _& _1 B2 |
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim), a; t7 y& e8 T  a& {
  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    : `! j7 L0 s6 J1 x4 f+ }  k$ O
  2.   if(htim == &htim3){
    : X/ G5 `* \" e" d4 h' C0 |
  3.     //LED1状态每1s翻转一次
    2 N+ @0 x+ ~8 x  H. p& Z
  4.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);       
    9 A9 l- ^& I, c2 p% {  P8 O
  5.   }
    9 @' Z5 D8 ^3 V, {1 N
  6. }
复制代码
➡️ 在main函数中编写相关代码,在while中使LED2每500ms翻转一次' M0 b+ J9 J  G9 h
  1. int main(void){
    $ ?) H7 W" f6 j/ T' H
  2.   HAL_Init();
      n) N' B9 o4 E/ N5 }
  3.   SystemClock_Config();8 g. q& J* s  I/ h1 h6 [' P. n
  4.   MX_GPIO_Init();
    / D+ W: M; h1 S; r2 |6 ]
  5.   MX_TIM3_Init();; e0 c5 b( y; \- O# H
  6.   //启动定时器中断模式计数
    0 O8 G  C0 ~. v7 S# e# d
  7.   HAL_TIM_Base_Start_IT(&htim3);                  g5 E" Q* k' ~7 X) f7 n9 N
  8.   while (1){* E8 d& V2 j& D$ f5 O- B
  9.     //LED2状态每500ms翻转一次
    % o2 `4 P! r+ A( d
  10.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1);       
    0 Q3 M" ?( j/ I; V& c
  11.     HAL_Delay(500);/ L4 L# p2 x/ A
  12.   }, r4 i: ?& t* \( g
  13. }
复制代码
4.下载验证
$ J4 W+ Z. b6 j2 U$ b  T编译无误后下载到开发板,可以看到LED1每1s状态翻转一次,LED2每500ms状态翻转一次3 h- u1 X  {" f( {: f: U
- d' B* d; ?  C' z6 r4 O
赞 收藏 评论0 发布时间:2020-12-1 12:45

举报

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