【STM32】细说TIM的Channels与应用
寄存器层
1、TIM_Base_Set初始化常用:
CR1:TIM control reg 1
该寄存器内容决定定时器计数模式CounterMode、分频比ClockDivision和ARR重装值何时写入有效判断AutoReloadPreload
PSC:TIM prescaler reg
该寄存器内容决定预分频Prescaler,对输入的步长进行预处理为单位时间
ARR:TIM auto_reload_reg
该寄存器内容决定周期Period
CNT:TIM counter reg
定时器计数寄存器,Period对单位时间的count
EGR:TIM event generation reg
2、TIM_OC_Set初始化常用:
CR2:TIM control reg 2
该寄存器内容决定输出引脚电平状态OCIdleState或OCNIdleState
CCMRx:TIM_capture/compare mode reg x
channel1/2-------------x = 1
channel3/4-------------x = 2
该寄存器内容决定输出模式OCMode,其中就包含了PWM
CCER:TIM capture/compare enable reg
该寄存器内容决定输出极性设置OCPolarity/OCNPolarity
CCRx:TIM capture/compare regx
该寄存器在OC模式下决定PWM的Pulse值
3、TIM_TIx_Set初始化常用:
CCMRx:TIM capture/compare reg x
channel1/2-------------x = 1
channel3/4-------------x = 2
该寄存器决定捕获通道选择ICSelection和捕获滤波器ICFilter,以及输入捕获预分频ICPrescaler,注意ICPrescaler与寄存器是直接建立联系,而不是通过TIM_TIx_Set传入寄存器的,这与TIx的定义有关
CCER:TIM capture/compare enable reg
该寄存器决定输入触发极性ICPolarity,可选择上升沿、下降沿或者双沿触发
CCRx:TIM capture/compare regx
该寄存器存储上一个输入捕获事件发生时的计数值
上述各个寄存器对应的数值,除ICPrescaler外都在各自的TIM_XXX_Set中被赋以TIM_Base_InitTypeDef、TIM_OC_InitTypeDef、TIM_IC_InitTypeDef结构体中对应成员的数值,用户只需要设定这些成员的数值就可以改变寄存器值
/**
* @brief TIM Time base Configuration Structure definition
*/
typedef struct
{
uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock.
This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ uint32_t CounterMode; /*!< Specifies the counter mode.
This parameter can be a value of @ref TIM_Counter_Mode */ uint32_t Period; /*!< Specifies the period value to be loaded into the active
Auto-Reload Register at the next update event.
This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ uint32_t ClockDivision; /*!< Specifies the clock division.
This parameter can be a value of @ref TIM_ClockDivision */ uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter
reaches zero, an update event is generated and counting restarts
from the RCR value (N).
This means in PWM mode that (N+1) corresponds to:
- the number of PWM periods in edge-aligned mode
- the number of half PWM period in center-aligned mode
GP timers: this parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.
Advanced timers: this parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ uint32_t AutoReloadPreload; /*!< Specifies the auto-reload preload.
This parameter can be a value of @ref TIM_AutoReloadPreload */
} TIM_Base_InitTypeDef;
/**
* @brief TIM Output Compare Configuration Structure definition
*/
typedef struct
{
uint32_t OCMode; /*!< Specifies the TIM mode.
This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ uint32_t OCPolarity; /*!< Specifies the output polarity.
This parameter can be a value of @ref TIM_Output_Compare_Polarity */ uint32_t OCNPolarity; /*!< Specifies the complementary output polarity.
This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
@note This parameter is valid only for timer instances supporting break feature. */ uint32_t OCFastMode; /*!< Specifies the Fast mode state.
This parameter can be a value of @ref TIM_Output_Fast_State
@note This parameter is valid only in PWM1 and PWM2 mode. */ uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_Idle_State
@note This parameter is valid only for timer instances supporting break feature. */ uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
@note This parameter is valid only for timer instances supporting break feature. */
} TIM_OC_InitTypeDef;
/**
* @brief TIM Input Capture Configuration Structure definition
*/
typedef struct
{
uint32_t ICPolarity; /*!< Specifies the active edge of the input signal.
This parameter can be a value of @ref TIM_Input_Capture_Polarity */ uint32_t ICSelection; /*!< Specifies the input.
This parameter can be a value of @ref TIM_Input_Capture_Selection */ uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler.
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ uint32_t ICFilter; /*!< Specifies the input capture filter.
This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
} TIM_IC_InitTypeDef;
Init与Config层
这一层相当于一个过渡,目的是更方便地引出API
从官方差异化的命名可以看出,定时器的输出与输入捕获有别于定时器的基本功能——定时溢出,而是在基本功能实现的情况下去做一些附加的东西,这里从回调函数也可以看出来,并不复杂就不再细说,这些函数会调用对应的TIM_XXX_Set与MspInit
用户Init层
用户需要编写Init层,通过TypeDef上述句柄,修改结构体内容并传入Init与Config层达到配置TIM特性的目的,Init与Config层、寄存器层都是封装在HAL库里的,于是我们可以得到如下关系
一层层把包含特性配置信息的句柄传入,最后赋值给寄存器
以上就是定时器初始化的部分内容
要让定时器开始工作,中断使能必不可少
CRx:TIM control regx
控制寄存器,使能时需要置位寄存器使能计数器,具体操作可由函数__HAL_TIM_ENABLE(&htim)实现
DIER:TIM DMA/interrupt enable reg
中断允许寄存器,一般情况下可调用__HAL_TIM_ENABLE_IT(&htim,TIM_IT_UPDATE)置位对应寄存器
定时器使能完成后,用户最常访问的就是定时器的状态,要访问定时器的状态,只需要下面这个寄存器
SR:TIM state reg
__HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__)
__HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)
其中,__HANDLE__为自定义的句柄&htim,__FLAG__为各flag
/** @brief Check whether the specified TIM interrupt flag is set or not.
* @param __HANDLE__ specifies the TIM Handle.
* @param __FLAG__ specifies the TIM interrupt flag to check.
* This parameter can be one of the following values:
* @arg TIM_FLAG_UPDATE: Update interrupt flag
* @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag
* @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag
* @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag
* @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag
* @arg TIM_FLAG_COM: Commutation interrupt flag
* @arg TIM_FLAG_TRIGGER: Trigger interrupt flag
* @arg TIM_FLAG_BREAK: Break interrupt flag
* @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag
* @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag
* @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag
* @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag
* @retval The new state of __FLAG__ (TRUE or FALSE).
*/
#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__))
TIM Channels应用实例1:输出比较(PWM)
STM32可以由定时器产生PWM波,相较于TIM的一般应用,增加了对于通道及输出口的配置:
初始化:MX_TIM_Init()
1、配置结构体TIM_HandleTypeDef定义的htim成员
2、配置结构体TIM_OC_InitTypeDef定义的sConfigOC成员
3、配置结构体TIM_MasterConfigTypeDef与TIM_ClockConfigTypeDef定义的成员,这里按默认
4、配置输出GPIO复用参数,MX将其封装在一个MspPostInit里在MX_TIM_Init()调用
其中第二条是与一般应用的不同之处,用于初始化Output Compare的各项参数
输出允许:HAL_TIM_PWM_Start(&htim,TIM_CHANNEL_x)
允许输出PWM,将在配置的GPIO口上输出PWM波,这一功能的配置相对简单,也可以看出,ST官方给出定时器的比较与捕获通道,具有很多用处,且避免了用户需要自己写逻辑来实现这些功能的麻烦
TIM Channels应用实例2:输入捕获
输入捕获,实际上就是在定时器的基础上加了对于特定引脚的捕获通道,使得循环计时的定时器能关联上外部引脚电平:
初始化:MX_TIM_Init()
1、配置结构体TIM_HandleTypeDef定义的htim成员
2、配置结构体TIM_IC_InitTypeDef定义的sConfigIC成员
3、配置结构体TIM_MasterConfigTypeDef与TIM_ClockConfigTypeDef定义的成员,这里按默认
4、配置输入GPIO复用参数,此处写在MspInit里
中断允许:HAL_TIM_IC_Start_IT(&htim5,TIM_CHANNEL_1);
__HAL_TIM_ENABLE_IT(&htim5,TIM_IT_UPDATE);
此处对CR进行了两次操作,后者将DIER置位为TIM_TI_UPDATE,在前者将DIER置位为TIM_IT_CC1,同时允许了CR中的计数器使能
中断服务:
基本的逻辑就是在检测到高电平时定时器清零,接着开始循环计时,同时更改触发电平为低电平触发,每溢出一次手动计数,这是在下次触发时,高电平事件就是ARR乘以溢出次数加上此次的CCRx
uint8_t TIM5CH1_CAPTURE_STA = 0;
uint32_t TIM5CH1_CAPTURE_VAL = 0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == (&htim5))
{
if((TIM5CH1_CAPTURE_STA &0x80) == 0)
{
if(TIM5CH1_CAPTURE_STA &0x40)
{
if((TIM5CH1_CAPTURE_STA &0x30) == 0x3f)
{
TIM5CH1_CAPTURE_STA |= 0x80;
TIM5CH1_CAPTURE_VAL = 0xffffffff;
}
else
{
TIM5CH1_CAPTURE_STA ++;
}
}
}
} } void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim == (&htim5))
{
if((TIM5CH1_CAPTURE_STA &0x80) == 0)
{
if(TIM5CH1_CAPTURE_STA &0x40)
{
TIM5CH1_CAPTURE_STA |= 0x80;
TIM5CH1_CAPTURE_VAL = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_1);
TIM_RESET_CAPTUREPOLARITY (&htim5, TIM_CHANNEL_1);
TIM_SET_CAPTUREPOLARITY (&htim5, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);
}
else
{
TIM5CH1_CAPTURE_STA = 0;
TIM5CH1_CAPTURE_VAL = 0;
TIM5CH1_CAPTURE_STA |= 0x40;
__HAL_TIM_DISABLE (&htim5); //关闭定时器5
__HAL_TIM_SET_COUNTER (&htim5,0);
TIM_RESET_CAPTUREPOLARITY (&htim5,TIM_CHANNEL_1); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY (&htim5,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获
__HAL_TIM_ENABLE (&htim5);//使能定时器5
}
}
}
}
if(TIM5CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平
{
temp=TIM5CH1_CAPTURE_STA&0X3F;
temp*=0XFFFFFFFF; //溢出时间总和
temp+=TIM5CH1_CAPTURE_VAL; //得到总的高电平时间
printf("HIGH:%lld us\r\n",temp);//打印总的高点平时间
TIM5CH1_CAPTURE_STA=0; //开启下一次捕获
}
此处引用正点原子的服务函数,自行理解
【STM32】细说TIM的Channels与应用的更多相关文章
- stm32之TIM+ADC+DMA采集50HZ交流信号
http://cache.baiducontent.com/c?m=9d78d513d98207f04fece47f0d01d7174a02d1743ca6c76409c3e03984145b5637 ...
- stm32 定时器TIM时钟步骤
1)TIM3 时钟使能 . RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMx, ENABLE); //时钟使能 2) 初始化定时器参数,设置自动重装值, 分频系数, ...
- STM32 TIM高级定时器死区时间的计算
STM32 TIM高级定时器的互补PWM支持插入死区时间,本文将介绍如何计算以及配置正确的死区时间. 文章目录 什么是死区时间? 数据手册的参数 如何计算合理的死区时间? STM32中配置死区时间 什 ...
- STM32F4_TIM基本延时(计数原理)
Ⅰ.概述 STM32的TIM定时器分为三类:基本定时器.通用定时器和高级定时器.从分类来看就知道STM32的定时器功能是非常强大的,但是,功能强大了,软件配置定时器就相对复杂多了.很多初学者甚至工作了 ...
- STM32F0使用LL库实现PWM输出
在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本文我们将说明如何通过LL库实现PWM信号 ...
- STM32F103VET6 ADC采集64点做FFT变换
http://www.stmcu.org/module/forum/thread-598459-1-11.html http://bbs.21ic.com/icview-589756-1-1.html ...
- 有感FOC算法学习与实现总结
文章目录 基于STM32的有感FOC算法学习与实现总结 1 前言 2 FOC算法架构 3 坐标变换 3.1 Clark变换 3.2 Park变换 3.3 Park反变换 4 SVPWM 5 反馈部分 ...
- STM32 TIM重映射
复用功能 没有重映射 部分重映射 完全重映射 TIM3_CH1 PA6 PB4 PC6 CH2 PA7 PB5 PC7 CH3 PB0 PB0 PC8 CH4 PB1 PB1 PC9 /**重映射 t ...
- STM32 ~ STM32 TIM重映射
复用功能 没有重映射 部分重映射 完全重映射 TIM3_CH1 PA6 PB4 PC6 CH2 PA7 PB5 PC7 CH3 PB0 PB0 PC8 CH4 PB1 PB1 PC9 /**重映射 t ...
- STM32 TIM 编码器模式采集编码器信号
layout: post tags: [STM32] comments: true 文章目录 @[toc] 什么是正交解码? 编码器接口模式 标准库接口 TIM_TimeBaseInitTypeDef ...
随机推荐
- 题解 【POJ3728】The merchant(LCA)
题意:一棵树有N个城市,每个城市商品价格不一样,Q个询问,问从u出发到达v点,每个城市只能经过一次的最大利润 max min数组存u城到u的第2^i个祖先路径上的最值 答案就是u-v路径上的最大值-最 ...
- WCF学习系列---1、新建第一个WCF服务
一.了解.Net平台下的分布式技术 1.WebService:基于Http协议的Soap模式 2.Remoting :也是一种分布式架构技术,常常用于TCP模式的二进制传输 3.MSMQ:这是一种分布 ...
- windows server 2012以上版本离线安装 net framework3.5 方法
方法1. 通过服务管理器安装操作系统原镜像文件 准备windows系统镜像文件,解压windows server.iso文件到 D:\WindowsOS 在服务器管理器上添加.NET Framewor ...
- [2] Bert 论文精读
BERT是NLP领域让预训练这件事情出圈的工作. 开篇Introduction介绍了两类主流的预训练方法: 1.feature-based,即基于特征的,即我首先通过预训练得到一些比较好的特征,然后将 ...
- Go--求数组奇偶数之和
package main //申明main包 import "fmt" // 导入fmt标准库 func main() { arr := [...]int{01, 11, 22, ...
- Docker CLI docker attach 常用命令
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化.Docker是内核 ...
- java创建对象时内存发生了什么
Student s = new Student();\ 把Student.class文件加载到内存 在栈内存给s变量开辟一个空间 在堆内存为学生对象申请一个空间 给成员变量进行默认初始化 给成员变量显 ...
- wpf 解决画图模糊或抗锯齿以及文字模糊或抗锯齿问题
解决方案中使用的.Net FrameWork版本:4.6.1 画图模糊或抗锯齿: 控件属性加入 SnapsToDevicePixels="True" 文字模糊或抗锯齿: 控件属性 ...
- Gradle 安装配置
1 下载 官网各版本下载地址如下: https://gradle.org/releases/ 2 安装 将下载后的压缩包(此处以 gradle-6.5-all.zip 为例)解压到某个目录进行安装. ...
- PyTables 教程(一)入门,浏览对象树,将数据提交到表和数组
翻译自http://www.pytables.org/usersguide/tutorials.html 教程 Seràs la clau que obre tots els panys, seràs ...