文章目录
TIM输入捕获与PWMI
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有4个输入捕获通道
可配置为PWMI模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量
测量频率:
主从触发模式
主模式:将定时器内部信号映射到TRGO引脚,用于出发别的外设
触发源选择:选择从模式TRGI的信号来源
从模式:接收TRGI的信号,并自动实现相应功能
主模式 | 信号 | 从模式 | 信号 |
---|---|---|---|
Reset | 复位信号 | Closed | 关闭从模式 |
Enable | 使能定时器的信号 | Encoder1 | 编码器模式1(仅TI2计数) |
Update | 定时器的更新信号 | Encoder2 | 编码器模式2(仅TI1计数) |
OC1 | 比较或捕获成功信号 | Encoder3 | 编码器模式3(都计数) |
OC1REF | OC1REF的信号 | Reset | 计数器复位清零 |
OC2REF | OC2REF的信号 | Gated | 输入高电平启动计数器 低电平停止(不复位) |
OC3REF | OC3REF的信号 | Trigger | 启动计数器(不复位) |
OC4REF | OC4REF的信号 | External1 | 驱动计数器计数 |
输入捕获结构(Input Capture)
ch1通道的信号经过一个异或门的选择(此图中未体现,为了无刷电机的驱动)接入TI1进行滤波和极性选择产生两个输出TI1FP1和TI1FP2(此图仅有TI1FP1),这是为了PWMI模式,之后信号进入预分频器,分频后的信号将触发捕获电路。每来一个触发信号CNT的值相CCR转运一次并发生捕获事件(置状态寄存器的标志位或产生中断)
PWMI结构
两个通道同时捕获一个输入引脚,CCR1是一个周期的长度,CCR2是高电平的长度
占空比 = CCR2 / CCR1
初始化流程
输入捕获初始化流程
- RCC:同前,开启GPIO和TIM(可以选择给默认复用引脚进行重映射)
- TIM及时基单元:同前(其中ARR和PSC需根据实际情况而改变)
- TIMIC结构体:TIM_ICInitTypeDef
- TIM_Channel:通道选择
- TIM_ICFilter:滤波器(数大些效果好)
- TIM_ICPolarity:触发极性选择
- TIM_ICPrescaler:输入捕获单元中的分频器(1,2,4,8)
- TIM_ICSelection:选择直连通道或交叉通道(TI1FP1/TI2FP1)
- 触发源选择:TIM_SelectInputTrigger()
- 从模式选择:TIM_SelectSlaveMode()
- 计数器使能:TIM_Cmd()
PWMI初始化流程
- RCC:同前,开启GPIO和TIM(可以选择给默认复用引脚进行重映射)
- TIM及时基单元:同前(其中ARR和PSC需根据实际情况而改变)
- TIM_IC结构体:同前(不需开启两个通道)另一个为下降沿触发且交叉通道
- PWMI初始化:TIM_PWMIConfig()此函数仅需配置一个通道即可,会自动将另一个配置为相反值(及支持通道1/2)
- 触发源选择:TIM_SelectInputTrigger()主模式TRGO
- 从模式选择:TIM_SelectSlaveMode()从模式TRGI
- 计数器使能:TIM_Cmd()
标准库函数使用模板
输入捕获函数模板
输入捕获初始化函数
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM3);//内部时钟源选择
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_Cmd(TIM3, ENABLE);
}
uint32_t IC_GetFreq(void)
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
获得频率函数
/* IC_GetFreq
* @ param1 None
* @ retval 频率值
*/
uint32_t IC_GetFreq(void)
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
PWMI函数模板
PWMI初始化函数
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_Cmd(TIM3, ENABLE);
}
uint32_t IC_GetFreq(void)
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
获得占空比
/* TIM_SelectInputTrigger
* @ param1 None
* @ retval 占空比 %
*/
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
其他函数
触发源TRGI选择函数
/* TIM_SelectInputTrigger
* @ param1 选择TIM定时器
* @ param2 选择触发源通道
* @ retval None
*/
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
主模式TRGO选择函数
/* TIM_SelectOutputTrigger
* @ param1 选择TIM定时器
* @ param2 选择主模式要映射到TRGO上的事件
* @ retval None
*/
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
从模式选择函数
/* TIM_SelectSlaveMode
* @ param1 选择TIM定时器
* @ param2 选择从模式
* @ retval None
*/
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
单独配置输入捕获的分频器
/* TIM_SetICxPrescaler
* @ param1 选择TIM定时器
* @ param2 待写入的PSC值
* @ retval None
*/
void TIM_SetICxPrescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
读取CCR函数
/* TIM_GetCapturex
* @ param1 选择TIM定时器
* @ retval CCR寄存器的值
*/
uint16_t TIM_GetCapturex(TIM_TypeDef* TIMx);
流程图
+-------+ +---------------------------+
| 从模式+---+-->时基单元 |
| RESET | | |
+-------+ | ARR |
^ | | |
PWMI基本结构 | | | |
+----+-----+ | | |
|触发源选择 +-+--->PSC------------> CNT |
+----------+ | | | |
^ +---------------------+-+---+
| | |
+-------------------------+-----------------------------+-+----+
|输入捕获单元1 +--------+ | TI1FP1 +-+ v | |
+----+ | +------+ |边沿检测+---+---------+ +---->分频器---->CCR1 |
|GPIO+-----+->|滤波器|-->|极性选择| TI1FP2 | | | |
+----+ | +------+ +--------+----+ +-+ | |
+---------------------------+-----------------------------+----+
| |
+---------------------------+-----------------------------+----+
|输入捕获单元2 | +-+ | |
| |TI1FP2 | | v |
| +------>| +---->分频器---->CCR2 |
| +-+ |
+--------------------------------------------------------------+
+--+ +--+
reset -+ | ITR0 -+ |
| | | |
enable -+ | ITR1 -+ | 从模式
|主| |触| closed
update -+ | ITR2 -+ | encoder1
| | | | encoder2
OC1 -+ | ITR3 -+ | encoder3
|模+-> TRGO |发+-> TRGI reset
OC1REF -+ | TI1F_ED -+ | gated
| | | | trigger
OC2REF -+ | TI1FP1 -+ | external1
|式| |源|
OC3REF -+ | TI2FP2 -+ |
| | | |
OC4REF -+ | ETRF -+ |
+--+ +--+
*******************************************************************************
+-------+ +---------------------------+
| 从模式 +---+-->时基单元 |
| RESET | | |
+-------+ | ARR |
^ | | |
| | | |
输入捕获基本结构 +----+-----+ | | |
|触发源选择+-+--->PSC------------>CNT |
+----------+ | | |
^ +---------------------+-----+
| |
+-------------------------+-----------------------------+------+
| 输入捕获单元1 | | |
| +--------+ | +-+ | |
+----+ | +------+ |边沿检测| | TI1FP1 | | v |
|GPIO+-----+->|滤波器 |-->|极性选择+--+-------->| +---->分频器---->CCR1 |
+----+ | +------+ +-------+ +-+ 捕获/比较器 |
+--------------------------------------------------------------+
------ BY Flier
2023.8.30
Reference:江协科技、《stm32f10x用户手册》、《stm32库开发实战指南教程》