STMCU小助手
发布时间:2022-3-25 10:29
|
前言: 本系列教程将外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 - m$ w* s! ^% i2 [& U1 A E 1 i% x! }8 O* X 所用工具:4 ~1 M' ]# L! g8 U4 N. b : ]3 P9 a( H1 k 1、芯片: STM32F407ZET6/STM32F103ZET63 V9 k7 N# y& i4 d0 W: K 2、STM32CubeMx软件 3、IDE: MDK-Keil软件, G1 _8 {7 `! Z% s% @4 q 4、STM32F1xx/STM32F4xxHAL库 % N$ c1 `0 G2 m. m7 h 知识概括: 通过本篇博客您将学到: u! R' l4 l9 w; C/ E SMT32定时器输入捕获9 h7 E0 B6 S2 M# y 测量PWM频率和占空比 & q0 D. y6 P8 E) q6 j2 [; h - u" j8 j0 b5 Q0 m) L# Z 输入捕获5 _4 d1 J3 s2 s, X 输入捕获概念 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6、TIM7,其他的定时器都有输入捕获的功能。- A8 k, J: P4 ~ : r$ @, j" T/ u4 T: _$ E6 ]2 U 输入捕获的工作原理2 N0 w: M. K6 ]2 q, F
①先设置输入捕获为上升沿检测, % y: L. H3 f0 @- |" j' A" ]' R4 W ②记录发生上升沿时TIMx_CNT(计数器)的值 ) d: @+ a$ E0 n+ U* j ③配置捕获信号为下降沿捕获,当下降沿到来的时候发生捕获1 W7 H1 Y" y/ W+ S9 m0 y: B, C 2 t' \7 W3 v O0 u; u6 o+ W2 @ ④记录此时的TIMx_CN(计数器)T的值9 r; A5 }4 _* P% B6 m7 }# H0 D ⑤前后两次TIMx_CNT(计数器)的值之差就是高电平的脉宽。同时根据TIM的计数频率,我们就能知道高电平脉宽的准确时间。" m3 b& A: `" M0 G& f 1 n* E3 X9 S4 B/ N 简单说:& E5 Z- W' K( ]% @ ! P- G. }% v$ _* h) m9 ?( m( M 当你设置的捕获开始的时候,cpu会将计数寄存器的值复制到捕获比较寄存器中并开始计数,当再次捕捉到电平变化时,这是计数寄存器中的值减去刚才复制的值就是这段电平的持续时间,你可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获,6 C# o; C* n( l 7 y: ~* m+ R* V: R1 H1 ~ 输入捕获的工作流程(对应CubeMx的四个选项) 0 @: m2 M8 r: m; J
7 b; _8 R# @* f0 x3 D& Q 设置输入捕获滤波器 STM32在很多功能中都提供了滤波器,滤波器的功能简单来说就是多次检测视为一次有效,达到滤波效果,& z) c1 U, J, [4 ^$ V/ `% `& h 数字滤波器由一个事件计数器组成,假设我们是检测高电平,滤波N次,那么记录到N个事件后计数器会产生一个输出的跳变。也就是说连续N次采样检测,如果都是高电平,则说明这是一个有效的电平信号,这样便可以过滤掉那些因为某些而干扰产生的一些信号 0 Y( u% e ^' v! ?! ` 输入捕获滤波器IC1F[3:0],这个用于设置采样频率和数字滤波器长度。其中:fCK_INT是定时器的输入频率,fDTS是根据TIMx_CR1的CKD[1:0]的设置来确定的。 设置输入捕获极性2 f; C3 d1 J/ P5 P9 v & z' |% c4 g& z; t 设置具体为那种捕获事件- l/ [& j& b, A. p 5 @, w, g9 D- S5 F6 ~) { 可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获- |/ q0 N. ]8 F S/ a3 p- _ 设置输入捕获映射关系 STM32为了更好的优化使用,TIMx_CH1通道1捕捉到的信号可以传输到IC1,TIMx_CH1捕捉到的信号也可以连接到IC2,TIMx_CH2捕捉到的信号也可以连接到IC2,也可以连接到IC2
* W$ P+ A9 S, b. j" M" ~ ; Z% B+ r- V3 j u% r- k 设置输入捕获分频器 设置每N个事件触发一次捕获,可以设置为1/2/4/8次检测到电平变化才触发捕获 ; x4 D& R- |5 g5 B; Q R+ O" F+ ?1 e 溢出时间计算:$ W/ \+ F3 o% m
t1时刻检测到高电平,发生中断,在中断里将计数值置0,开始记溢出次数N, 0 N9 P8 j' R3 F0 k5 }8 e1 s8 @ 其中每计数0xFFFF次溢出一次,直到t2时刻跳变回低电平,. N* H1 p5 ]5 G: u4 { 获取最后一次溢出时到t2时刻的计数值TIM5CH1_CAPTURE_VAL : l0 d2 v! e- ]3 H) S5 O 则 高电平时间 = 溢出次数*65535+TIM5CH1_CAPTURE_VAL us ;根据定时器初始化时的频率即可计算出溢出总次数所占用的时间,即为高电平时间。& F) s$ J( q( _/ \ & n- Q4 v( a( X$ J6 J% v 如果计数器值为 32 bit 那么最大为0xFFFFFFFF ' f6 J4 Q) m% E5 o3 _$ F0 S8 x" }/ c 高电平时间: 4 X7 W* R, t8 ^4 M( S
* P& s7 G* a9 a/ s8 k, s* A ! v. h/ b5 s( u @. A 输入捕获的工作框图
8 [: g3 H+ M5 |( |! P( q {1 a& J* B) x& Y1 T 工程创建% Z8 {( w: j2 e, i, c) ?" W 设置RCC6 w1 ~1 j$ ?- u4 v 1 C8 b9 r0 F! H, Z2 D; y- m( }0 w8 I( f 设置高速外部时钟HSE 选择外部时钟源8 R# `; Y' ~) Z( h6 V
2设置时钟$ B: w& R* |! W8 |, } 3 V. k/ M- }+ Z# z9 y6 g E7 v: `
, S. K' f l! a- N/ y; x4 w7 l+ D 我的是 外部晶振为8MHz . |% v- G' a% `6 Y 1选择外部时钟HSE 8MHz 2PLL锁相环倍频72倍9 f- u7 }0 n7 A9 k 3系统时钟来源选择为PLL 4设置APB1分频器为 /2 5 这时候定时器的时钟频率为72Mhz, T; j9 `$ x; Z, X J6 g _ 3定时器配置/ Q; j2 T$ I1 {$ h* \; l$ h- J
# Y# x5 _. M5 G/ [$ W6 c5 w 这里我们选择TIM5的通道1# f. p; l3 i6 }8 A$ v 预分频系数为71 计数时钟频率就是 72MHz/(71+1) = 1MHz 此时1us计数一次4 u2 _# e2 o+ T% G" F0 W 自动加载值设置为32bit最大值 0xFFFFFFFF 7 m( r" W+ B; o6 ^ 上升沿捕获' Q( F: c' Q8 R; x( T; I2 { 不分频 滤波值为8! L4 t* {- l& `* @% S- F- D+ A% g, e 同时在NVIC一栏使能TIM5的中断9 x& y1 s/ o j; H: W% n: H $ X3 x( U1 Q! K& s 对应引脚设置下拉电阻,保证没有信号输入的时候电平稳定 1 M. t4 V8 A9 r: a! V
0 d: E" O3 M: @2 B 4项目文件设置
1 设置项目名称+ S& n* V, a7 X$ V0 M+ {* v! G* i3 J 2 设置存储路径 3 选择所用IDE / j9 t1 O) l- A6 l
0 b5 j. n+ x4 B( a 5创建工程文件 5 b) V" `+ [1 |1 p4 }' r* o7 d1 ` } 然后点击GENERATE CODE 创建工程 配置下载工具 新建的工程所有配置都是默认的 我们需要自行选择下载模式,勾选上下载后复位运行; Q% \: b+ {- Q) D6 p
例程实现: 定义变量:
在 while(1)中的用户代码区 3,写入TIM2 CH1通道的输入捕获控制和数据处理
在main函数下方添加中断回调函数:* t( \& K4 W& ^6 n% R5 a* ~: H: G 9 z; R( g, O6 v; g% R% r" X
具体流程:# r" o2 p& j1 \! h: o, _ 1.设置TIM5 CH1为输入捕获功能; % V) g5 E, k+ o" }/ v3 b 2.设置上升沿捕获; . k' Q, g3 w9 P) \3 w4 m 3.使能TIM2 CH1捕获功能; : M' _6 h8 e& n" O" z. [ 4.捕获到上升沿后,定时器当前计数值存入capture_buf[0],改为捕获下降沿; 0 a1 z& s* C8 P # E; Q! y, D' k" ]' l k# {3 C 5.捕获到下降沿后,定时器当前计数值存入存入capture_buf[1],关闭TIM2 CH1捕获功能; capture_Cnt=3; 6. 高电平时间: capture_buf[1] - capture_buf[0] 发送到上位机 重新启动输入捕获5 L. A0 u/ L% b 3 ]8 ~* C2 e$ ^ \& q% X2 P __HAL_TIM_SET_COUNTER(&TIM5_Handler,0); //设置计数寄存器的值变为0 HAL_TIM_PWM_Start() 函数用于使能定时器某一通道的PWM输出。# B# O+ X2 a$ E8 I" o9 G% | & y* m0 o) Z6 ]; h: _0 m# F! n HAL_TIM_IC_Start_IT() 函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断 HAL_TIM_IC_Stop_IT() 函数和开启功能相反,是关闭定时器某一通道的输入捕获功能和相应中断3 R2 d" G# R$ v# ?6 N2 Z7 a' B z __HAL_TIM_SET_CAPTUREPOLARITY不是函数,而是底层操作的一个宏定义. _7 F( i# u. S* e4 N . b# z, a4 v. o/ v 在stm32f4xx_hal_tim.h文件中可以找到。其作用是修改定时器某一通道的输入捕获极性. d1 @% r* x6 A' Y a, s
其中有两个函数,第一个为清除清除原来的捕获极性,第二个为设置通道捕捉极性 等价于: 1 m) Y8 u, N/ O$ S: m' M) G; J
在修改定时器某一通道的输入捕获极性时,一定要先清除该通道之前捕获极性/ T$ r) V3 L' T3 s4 U7 V __HAL_TIM_GET_COMPARE也是一个宏定义。 w! P5 ^3 D9 ]5 v$ d- b( R 在stm32f4xx_hal_tim.h文件中可以找到。其作用是获取定时器某一通道的捕获/比较寄存器值- B$ T! R4 o/ b$ E( t6 [! a
等价于 : HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1); 两者都是直接读取对应CCRx寄存器的值 |
经验分享 | 利用TIMER定时和捕获功能实现编解码演示
STM32 LSE 不起振排查指南:五大核心原因与快速解决方案
我心中的ST中文论坛
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
2025软件工具兔哥知道
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
经验分享 | 一个基于TIMER事件的中断响应话题_续
经验分享 | 一个基于TIMER事件的中断响应话题
11张图学会STM32定时器!
经验分享 | STM32U5系列TIMER+DMA+DAC应用演示
微信公众号
手机版