STMCU小助手
发布时间:2022-3-25 10:29
|
前言: 本系列教程将外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用) C Z+ a8 @' K # m0 D% q$ S& |% F# n 所用工具: 1、芯片: STM32F407ZET6/STM32F103ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 : _4 U) ]) Z# l6 C- l 知识概括: / V: k, q+ H4 e# d) y( a. Z 通过本篇博客您将学到:3 C: H' f7 J$ s" p, Y w ) G( z# r* A3 @! W9 ` SMT32定时器输入捕获8 w! N7 n2 G& V, \7 @' n 1 h4 Y8 A6 A, @$ J h 测量PWM频率和占空比 + ^3 o, ?. T7 T1 ?% e) M% M5 p 9 Q9 ^% E6 a9 b, m; v# [) G 输入捕获 输入捕获概念 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6、TIM7,其他的定时器都有输入捕获的功能。 / ^" n/ B! K/ A! |! r% ~1 k 输入捕获的工作原理% W7 a& |8 z3 a
①先设置输入捕获为上升沿检测,: \6 n. H- F9 k6 g# c( r$ `2 N . f4 n8 |, Y0 c# R8 _9 j. ]! _' D* y ②记录发生上升沿时TIMx_CNT(计数器)的值 ③配置捕获信号为下降沿捕获,当下降沿到来的时候发生捕获 ④记录此时的TIMx_CN(计数器)T的值- R! S1 B, I9 b " `4 Q( w1 o# r1 e9 Q ⑤前后两次TIMx_CNT(计数器)的值之差就是高电平的脉宽。同时根据TIM的计数频率,我们就能知道高电平脉宽的准确时间。: O9 _: a7 c2 d 简单说: ' M) F; A5 ? C, _4 u) n 当你设置的捕获开始的时候,cpu会将计数寄存器的值复制到捕获比较寄存器中并开始计数,当再次捕捉到电平变化时,这是计数寄存器中的值减去刚才复制的值就是这段电平的持续时间,你可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获, 输入捕获的工作流程(对应CubeMx的四个选项)
设置输入捕获滤波器9 B% Y! T* w( o0 z- q STM32在很多功能中都提供了滤波器,滤波器的功能简单来说就是多次检测视为一次有效,达到滤波效果, 数字滤波器由一个事件计数器组成,假设我们是检测高电平,滤波N次,那么记录到N个事件后计数器会产生一个输出的跳变。也就是说连续N次采样检测,如果都是高电平,则说明这是一个有效的电平信号,这样便可以过滤掉那些因为某些而干扰产生的一些信号 * b* V- b* X) C 输入捕获滤波器IC1F[3:0],这个用于设置采样频率和数字滤波器长度。其中:fCK_INT是定时器的输入频率,fDTS是根据TIMx_CR1的CKD[1:0]的设置来确定的。 设置输入捕获极性, |7 i" S- F& o* b* W2 q " r5 u! o/ u! X" t$ w" Z# d 设置具体为那种捕获事件 可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获 设置输入捕获映射关系 STM32为了更好的优化使用,TIMx_CH1通道1捕捉到的信号可以传输到IC1,TIMx_CH1捕捉到的信号也可以连接到IC2,TIMx_CH2捕捉到的信号也可以连接到IC2,也可以连接到IC2 / x( d: L. y9 r) D6 k
/ \1 A" n- e( a: G" v ; P* |9 |& n. c! l 设置输入捕获分频器6 w) k. n( Q1 N$ c; v; \ 设置每N个事件触发一次捕获,可以设置为1/2/4/8次检测到电平变化才触发捕获 溢出时间计算:0 V* p! W% X) z/ w
t1时刻检测到高电平,发生中断,在中断里将计数值置0,开始记溢出次数N,* k! N* } E- d1 m8 r* \8 z' r 8 @, M$ E( {' C q E' w 其中每计数0xFFFF次溢出一次,直到t2时刻跳变回低电平, S7 ~ v1 ~: l' d; U 获取最后一次溢出时到t2时刻的计数值TIM5CH1_CAPTURE_VAL" K% ]0 ?7 |1 j " }1 B4 a' i2 M; v/ A 则 高电平时间 = 溢出次数*65535+TIM5CH1_CAPTURE_VAL us ;根据定时器初始化时的频率即可计算出溢出总次数所占用的时间,即为高电平时间。 8 b6 N/ N! I& B1 R! f; s7 {' s3 ? 如果计数器值为 32 bit 那么最大为0xFFFFFFFF 9 p e* T& B' u$ G) r 高电平时间: 3 T; w5 ~$ n* p& C6 W
0 ?" @& _4 B# j6 W- c; k 输入捕获的工作框图 8 Y, c: v/ M- D7 F! }
工程创建 设置RCC $ g8 K' p- y7 H H 设置高速外部时钟HSE 选择外部时钟源* }; p8 }& S1 J. l, K 1 M7 h. u) z. C4 z; B2 V& Y
2设置时钟 / |/ ]# i7 ?* X0 f- n
我的是 外部晶振为8MHz 1选择外部时钟HSE 8MHz 2PLL锁相环倍频72倍 3系统时钟来源选择为PLL 4设置APB1分频器为 /2; o1 ], y7 s, i- |) ~2 c 5 这时候定时器的时钟频率为72Mhz" F3 P0 S# n8 K) H+ _( q 9 J+ q8 O0 a: x# J% n 3定时器配置
这里我们选择TIM5的通道1 " \. H7 Q9 {# K7 { S 预分频系数为71 计数时钟频率就是 72MHz/(71+1) = 1MHz 此时1us计数一次. q5 m) M4 x6 M9 d: f# C Z 自动加载值设置为32bit最大值 0xFFFFFFFF 上升沿捕获0 ]+ ?6 A7 m! i# C+ g% r; m 不分频 滤波值为86 U) |0 |! U) O ?. L 8 L- ^4 O" y- L5 T1 d; L 同时在NVIC一栏使能TIM5的中断 : Y ^8 c0 R9 Y/ { 对应引脚设置下拉电阻,保证没有信号输入的时候电平稳定 d6 C& m% b$ \% H z
/ i; d" N; h, D8 M 4项目文件设置
1 设置项目名称3 k. B; b2 K2 y+ k 2 设置存储路径 3 选择所用IDE2 W$ z: J, b. {6 _0 U& _! T' M x( x* B* Q8 a, N1 f
, ?# a/ r# c& R0 v5 @' e) { 5创建工程文件6 ]3 v9 J f: t4 x2 J 然后点击GENERATE CODE 创建工程 配置下载工具 新建的工程所有配置都是默认的 我们需要自行选择下载模式,勾选上下载后复位运行 3 t3 ?: G- T% ^( g
, x# ~* W* R1 e# G 例程实现:- y g' G" L9 | L 定义变量:
在 while(1)中的用户代码区 3,写入TIM2 CH1通道的输入捕获控制和数据处理; O$ O0 |# R" D! W, j8 \
在main函数下方添加中断回调函数:& t1 a2 R% Y% J+ t/ l8 \& w 7 n) Q: x. P8 B% k( N
具体流程: " X+ }. C: f% S; Z 1.设置TIM5 CH1为输入捕获功能; + v& W2 o' S1 { 6 Q+ w4 y2 ?% H* F* m7 V 2.设置上升沿捕获; / }# f( L- M' @ 3.使能TIM2 CH1捕获功能; 0 F$ k4 p! r. `6 d& ]( ^. u 8 h, v" w3 [% r, O' T% w 4.捕获到上升沿后,定时器当前计数值存入capture_buf[0],改为捕获下降沿; 7 z/ ~/ ?( [! z' t! u 9 g+ s7 L) u0 ? 5.捕获到下降沿后,定时器当前计数值存入存入capture_buf[1],关闭TIM2 CH1捕获功能; capture_Cnt=3; 6. 高电平时间: capture_buf[1] - capture_buf[0] 发送到上位机 重新启动输入捕获 & H2 I7 _* m: S7 v+ J __HAL_TIM_SET_COUNTER(&TIM5_Handler,0); //设置计数寄存器的值变为0 HAL_TIM_PWM_Start() 函数用于使能定时器某一通道的PWM输出。& x( i- V2 m0 G& h O' {+ C HAL_TIM_IC_Start_IT() 函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断2 k% L3 s* \- I8 i9 X! S HAL_TIM_IC_Stop_IT() 函数和开启功能相反,是关闭定时器某一通道的输入捕获功能和相应中断 7 C, F" r# M, M4 j$ D __HAL_TIM_SET_CAPTUREPOLARITY不是函数,而是底层操作的一个宏定义7 G' P9 y) Q; i 在stm32f4xx_hal_tim.h文件中可以找到。其作用是修改定时器某一通道的输入捕获极性! H! a; B/ G$ h
其中有两个函数,第一个为清除清除原来的捕获极性,第二个为设置通道捕捉极性: a8 [9 h' d% O9 [$ s 等价于: ( m4 j9 \1 |6 G' x+ f& J! P) `, \
在修改定时器某一通道的输入捕获极性时,一定要先清除该通道之前捕获极性: ^7 U+ O! Z* A% H9 H3 W 9 ^# L* S! }; y, o' i& n/ x __HAL_TIM_GET_COMPARE也是一个宏定义。 在stm32f4xx_hal_tim.h文件中可以找到。其作用是获取定时器某一通道的捕获/比较寄存器值5 V$ K. J% R! \9 n0 U
等价于 : HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1); 9 i2 g$ N3 r# k. f+ m7 A8 P/ Y' } U 两者都是直接读取对应CCRx寄存器的值1 m* x/ @5 e5 a; ^6 v9 M/ b |
经验分享 | 利用TIMER定时和捕获功能实现编解码演示
STM32 LSE 不起振排查指南:五大核心原因与快速解决方案
我心中的ST中文论坛
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
2025软件工具兔哥知道
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
经验分享 | 一个基于TIMER事件的中断响应话题_续
经验分享 | 一个基于TIMER事件的中断响应话题
11张图学会STM32定时器!
经验分享 | STM32U5系列TIMER+DMA+DAC应用演示
微信公众号
手机版