STMCU小助手
发布时间:2022-3-25 12:38
|
前言: 今天我们来学习定时器,32的定时器有着非常丰富的功能, 输入捕获/输出比较,PWM,中断等等。是我们学习STM32最频繁使用到的外设之一,所以一定要掌握好,这节我们讲解定时器中断,本系列教程将对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用' Y9 e2 h, C! b7 t& e( V " U: G, T! ?* O9 q 所用工具: 1、芯片: STM32F407ZET6/STM32F103ZET66 J" [1 \* c) H( o - c1 }( [) t( V, x" H0 B R 2、STM32CubeMx软件% w( @2 ` a6 F - }, ~7 s. \: v. A 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 2 Q- P- ]) a5 W6 C/ N: W / @+ Q3 k1 {& T2 t6 a' r 知识概括: 5 ~+ Y* z8 }+ _7 Y# Z# g 通过本篇博客您将学到:; [% ?% i6 f5 e( ?. k SMT32定时器原理& f: j) L4 A; o STM32CubeMX创建定时器例程$ Y; `$ V+ a" m- `. E HAL库TIM定时器函数库" [/ C' S6 |; @- i( u 定时器中断的创建与使用" a2 B, O/ V- R( v5 ?7 D- G 6 v: [ f; Z/ a 定时器简介:9 X" K$ ?9 E& g/ R SMT32F1系列共有8个定时器: 高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5);基本定时器(TIM6、TIM7)。+ K, `: X F. _. U$ i1 \# k SMT32F4系列共有15个定时器: 高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5、TIM9~TIM14);基本定时器(TIM6、TIM7)。. \. m. p4 @/ X8 c: } # k: A5 J( F7 \* s0 g% w D; L7 U( @& c 基本定时器功能(TIM6、TIM7): 16位向上、向下、向上/下自动装载计数器 B" r( d& R& C" Q# g 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值* k/ {2 K) p5 {3 L' p; i+ Q( C 触发DAC的同步电路 注:此项是TIM6/7独有功能. x& O5 b( _) Z 位于APB1总线上 7 E6 b. L, e- G l 通用定时器(TIM2~TIM5)的主要功能: 1.16位向上、向下、向上/下自动装载计数器 2.16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值- g/ p/ E" g9 W" @ 3.4 个独立通道(TIMx_CH1~4)可以用作: 测量输入信号的脉冲长度( 输入捕获) 7 a9 F+ @# y8 J/ s5 r 输出比较$ `* j# Z, z. E$ v7 `$ q. | 单脉冲模式输出 5 T2 N& x2 s# `$ `4 P PWM输出(边缘或中间对齐模式) % g6 c$ o+ K# t 4.支持针对定位的增量(正交)编码器和霍尔传感器电路 5.如下事件发生时产生中断/DMA:/ J' L2 ~: C, r* q. U2 O 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) / ], u7 e7 \8 Q3 m: N# k 输入捕获 输出比较 ' f( }" X; N2 u8 [# m) q2 a) o% { 6.位于APB1总线上 0 m* W) u; _( @6 d2 M& X 高级定时器(TIM1,TIM8)的主要功能: 高级定时器具有基本,通用定时器的所有的功能,6 V: j& @! w9 ?' n7 { 还具有控制交直流电动机所有的功能,; Z! r+ R0 M' ?* Z( ~3 z 输出6路互补带死区的信号,刹车功能等等 位于APB2总线上$ x. e0 g1 W& r' D" v6 U 总括:基本定时器就是单纯的定时计数器,通用定时器多了四个通道,相对应的增加了功能,高级定时器具有基本,通用定时器的所有的功能,并且添加了其他功能/ Z2 X+ e8 y& @1 [7 T! Z( { & J% ^( c5 n1 Z0 J
2 r' g& F! l; b- g, { 定时器计数模式 通用定时器可以向上计数、向下计数、向上向下双向计数模式。 % i' A$ ^% K% N 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。 向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。 中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。 7 @- c5 W2 j" l0 ?8 I 简单地理解三种计数模式,可以通过下面的图形:& P; w G9 ^6 s9 i; Z) A
# G. D s( T2 p, A+ g0 |1 _ 计数时钟的选择2 o+ p6 f* F; O6 x! j( U' b% [ 计数器时钟可由下列时钟源提供:& ^: m; L: P; ?* i 内部时钟(TIMx_CLK) 外部时钟模式1:外部捕捉比较引脚(TIx) 外部时钟模式2:外部引脚输入(TIMx_ETR) 仅适用TIM2,3,41 S; A5 p! g8 p( }/ y5 o# W+ Q: h& I 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。 定时器的主从模式: (选看)4 h. Q6 y, u" w 定时器一般是通过软件设置而启动,STM32的每个定时器也可以通过外部信号触发而启动,还可以通过另外一个定时器的某一个条件被触发而启动。这里所谓某一个条件可以是定时到时间、定时器超时、比较成功等许多条件。) z3 X: A& c) r5 g - K1 P a* V* [7 c 这种通过一个定时器触发另一个定时器的工作方式称为定时器的同步,发出触发信号的定时器工作于主模式,接受触发信号而启动的定时器工作于从模式, z. `: \, {0 b: N 触发条件:/ H( R1 v% X' p/ u: y 4 T- \6 [# t* p! \, q) t# C2 t
定时器的四种主从机模式: 外部触发模式17 q9 G7 Z- e) p) \% U IRC重置模式 门控模式 触发模式/ F% f# J7 C0 R( |$ A0 n ?6 _/ ^' ~1 A7 s5 C 工程创建' ^4 a7 P+ i `: r8 o 1设置RCC3 k m* R5 g" X1 [& i+ K/ d$ S 设置高速外部时钟HSE 选择外部时钟源
4 q, j4 O- S& T8 v 2设置时钟. x) W; n" E; Y4 d : X# D1 u( N2 E
8 D% J# x) t' M 我的是 外部晶振为8MHz 1.选择外部时钟HSE 8MHz ; @( o( {3 X F/ Q 2.PLL锁相环倍频72倍 3.系统时钟来源选择为PLL% o3 o( J! R& ~/ [' l6 g 4.设置APB1分频器为 /2 5.这时候定时器的时钟频率为72Mhz 7 O% w/ N6 P, p2 T @' F: E2 Z 3定时器设置/ e. b3 k1 Q. Y. n: C+ R
1.选择TIM27 P9 d1 k: F3 ]5 { N. N0 Y8 H R ; V' m! ~7 y' s" O 2.定时器时钟选择内部时钟4 C8 k5 J6 D8 L9 ]5 r6 | Clock Source(时钟来源) / L" D' z, q7 t! _$ N, ?" m 选项1 :Internal Clock 内部时钟 选项2 : ETR2 外部触发输入(ETR)(仅适用TIM2,3,4): H) ^- ?! d+ N. |9 b8 ?' O , p F3 W7 c- }. E! }8 \1 }6 L
. L: n6 C# K% ]3 W Prtscaler (定时器分频系数) : 7199 Counter Mode(计数模式) Up(向上计数模式) $ {3 D$ o5 T7 g Counter Period(自动重装载值) : 4999 CKD(时钟分频因子) : No Division 不分频 9 l" y0 m a D1 _ ; _6 @( P* Z, t 选项: 可以选择二分频和四分频 auto-reload-preload(自动重装载) : Enable 使能/ l# S3 T( ]+ i9 Y- W TRGO Parameters 触发输出 (TRGO) 不使能 与本节无关,之后做详细介绍 . `( H2 K1 R6 K0 X% {1 D6 U0 T4 K# F3 K TRGO: 定时器的触发信号输出 在定时器的定时时间到达的时候输出一个信号(如:定时器更新产生TRGO信号来触发ADC的同步转换,) # N( m( x! t" t" f5 R: m1 ?0 j0 ~
这两个为定时器主从模式配置,很少用到,我们用不到,所以全部关闭 使能定时器中断:
' r! P2 z( ]# S( a+ E% t 定时器溢出时间:
1 J6 W: w6 ^) H8 b$ O 这里我们 arr=4999 psc=7199 Tclk=72Mhz Tout = (5000*7200)/72 us = 500ms- a/ e! z: ^+ t! a# k! ^ 4项目文件设置5 J6 L2 p1 v0 W$ e4 N: ` " E8 k$ S& u% w/ ?: m
1 设置项目名称 2 设置存储路径( p& K' D' {* @ |3 G/ O$ V 3 选择所用IDE ' J. y. N0 ]% f; T4 r! `) V
5创建工程文件 然后点击GENERATE CODE 创建工程 8 u" r; P& v$ q" N$ b5 t5 c% d! T 配置下载工具( h7 e& m( V5 X) b 新建的工程所有配置都是默认的 我们需要自行选择下载模式,勾选上下载后复位运行 : H9 f! o& }' d9 O3 V9 V% ]
3 `3 v" `7 U6 o5 m. z 函数讲解: 3 Z T+ a" @" j' S8 O$ `
定时器中断处理函数 在stm32f4xx_it.c的 TIM2_IRQHandler()定时器中断服务函数中# h6 F1 j$ R2 d, e 2 e% C, J/ n+ _6 l( \ 这个函数的具体作用是判断中断是否正常,然后判断产生的是哪一类定时器中断(溢出中断/PWM中断.....),然后进入相应的中断回调函数0 q' i/ c1 ^; X! m
在HAL库中,每进行完一个中断,并不会立刻退出,而是会进入到中断回调函数中, 3 f, u) |0 a/ V) p 这里我们是使用定时器溢出中断回调函数& n* ?: `* |3 b# M: ]1 p8 g void TIM3_IRQHandler(void) 首先进入中断函数. l" Y* u3 a1 p HAL_TIM_IRQHandler(&htim2);之后进入定时器中断处理函数 判断产生的是哪一类定时器中断(溢出中断/PWM中断.....) 和定时器通道 void HAL_TIM_PeriodElapsedCallback(&htim2); 进入相对应中断回调函数 在中断回调函数中添加用户代码 你也可以在在stm32f1xx_it.c中找到中断回调函数 __weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 9 _: A- J1 Z+ b) E/ {2 S" T 例程:2 |1 A7 Z% \1 Y9 X' V4 f1 V1 G 定时器溢出时间为500ms,LED点亮延时500ms闪烁 在main.c主函数上方初始化使能定时器2
在main.c主函数下方添加中断回调函数" ?6 ^8 ?6 W& C! F! F1 A5 w d# o
' R8 w. P/ ^; @, @( ~ |
想找个ST芯片
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
技术手册stm32f1xx中的一个小问题
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
OpenSTLinux 6.1发布:M33-TD加持+安全升级,STM32MPU开发效率翻倍!
微信公众号
手机版