STM32TIM定时器输入捕获详解(适用于通用,高级定时器)
前言
首先我们要明白,输入捕获有常见的测量脉宽和特殊的
PWM 输入,两种方式,因此我在下面也会提供两端代码。注意代码中我们会出现中断这部分代码,这部分是按照个人需求进行使用。
原理细解
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
这里我看了许多相关的视频讲解,里面关于中断的引用,一般来说配置到主从触发的时候并且使能好后,你可以直接用相关函数读出你记录的值,当然你需要处理一下才能够得到结果,如果你加了中断,那么你就在中断服务函数里面处理,我个人觉得不要中断比较简洁(江科大就是这样写的),当然下文会添加上中断部分,毕竟考虑到严谨。
程序源码
1.PWM 输入+主从触发模式
普通的输入捕获可以使用定时器的四个通道,一路捕获占用一个捕获寄存器,而 PWM 输入则只 能使用两个通道,即通道 1 和通道 2,且一路 PWM 输入要占用两个捕获寄存器,一个用于捕获 周期,一个用于捕获占空比。
第一步 ,配置GPIO配置成输入模式(上拉输入或浮空输入)
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOX, ENABLE);
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_X ;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOX, &GPIO_InitStruct);
第二步,配置时基单元,让CNT计数器在内部时钟的驱动下自增运算
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMX, ENABLE);
TIM_InternalClockConfig(TIMX);
//上面两行代码使用时不会导致重复,因为它们的作用是不同的。RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMX, ENABLE)是用来使能TIM3外设的时钟,而TIM_InternalClockConfig(TIMX)是用来配置TIM3的内部时钟源。
// 自动重装载寄存器的值,
TIM_TimeBaseStructure.TIM_Period=;//ARR
// 时钟预分频数
TIM_TimeBaseStructure.TIM_Prescaler=; //PSC
// 时钟分频因子 ,没用到不用管
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,设置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,没用到不用管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(TIMX, &TIM_TimeBaseStructure);
第三步,配置输入捕获单元
TIM_ICInitTypeDef TIM_ICInitStructure;
// 捕获通道IC1配置
// 选择捕获通道
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1L;
// //极性选择(上升还是下降或者双边)
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
// 设置捕获通道的信号来自于哪个输入通道,有直连和非直连两种
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
// 1分频,即捕获信号的每个有效边沿都捕获
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
//选择输入捕获的滤波器(0x0-0xf之间的一个数)
TIM_ICInitStructure.TIM_ICFilter = 0x0;
// 初始化PWM输入模式
TIM_PWMIConfig(, &TIM_ICInitStructure);
// 当工作做PWM输入模式时,只需要设置触发信号的那一路即可(用于测量周期)
// 另外一路(用于测量占空比)会由硬件自带设置,不需要再配置
第四步,配置主从模式的触发源 (调用库函数)
TIM_SelectInputTrigger(TIMX,TIM_TS_TI1FP1);//选择触发源是用来选择 TIM3 的输入触发源为 TI1FP1,即 TIM3 的通道 1 的滤波后的输入信号。
TIM_SelectSlaveMode(TIMX,TIM_SlaveMode_Reset);//选择从模式是用来选择 TIM3 的从模式为复位模式,即当 TIM3 接收到触发输入信号(TRGI)的上升沿时,TIM3 的计数器会清零,并且产生一个更新事件(UEV)。14
第五步,开启定时。
// 使能捕获中断,这个中断针对的是主捕获通道(测量周期那个)
TIM_ITConfig(, TIM_IT_CC1, ENABLE);
// 清除中断标志位
TIM_ClearITPendingBit(, TIM_IT_CC1);
上面两个如果你使用中断就加上
// 使能高级控制定时器,计数器开始计数
TIM_Cmd(, ENABLE);
第六步.配置中断
//配置优先级
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = TIMx_CC_IRQn;
// 设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// 设置子优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
第七步配置中断服务函数、
按个人需求在stm32f10x_it.c中写
2.常见方法的测量脉宽
(1)
定时器用到的
GPIO
初始化
(2)
定时器时基结构体
TIM_TimeBaseInitTypeDef
初始化
(3)
定时器输入捕获结构体
TIM_ICInitTypeDef
初始化
(4)
编写中断服务函数,读取捕获值,计算出脉宽的时间
和上面不同的是
TIM_PWMIConfig(,&TIM_structure);//pwm用这个
//TIM_ICInit(,&TIM_structure);//常见方法用这个
总结
最后我用我问人工智能的一个问题结尾
问:STM32输入捕获有常见的测量脉宽和特殊的 PWM输入,在代码部分是不是区别只有TIM_PWMIConfig();TIM_ICInit();这两个函数不同
答:STM32输入捕获有两种模式:普通的输入捕获模式和PWM输入模式。它们的区别主要在于:
所以,您的问题的答案是,是的,代码部分的区别只有TIM_PWMIConfig和TIM_ICInit这两个函数不同,其他的配置步骤基本相同。