1.熟练掌握TIM的参数配置,
2.熟练掌握输入通道的参数配置。
3.深刻理解输入捕获的原理和应用范畴。
4.理解输入捕获的原理。
一 什么是输入捕获功能
定时器输入捕获功能( input capture )是利用定时器的精准计数特性,实现对于脉冲宽度的测量的一种功能。
输入捕获功能示意图 :
结论:通过下降沿(单只电平由高电平降低到低电平的过程)和上升沿(低电平到高电平的过程)来作为判断依据。就可以测量出来低电平的持续时间和高电平的持续时间。
二 什么是定时器的输入捕获功能
2.1 定时器的输入捕获原理示意图
结论:这与上次课程 PWM 输出的硬件原理图相似,我们知道通道本质是一根线路,而线路就和引脚一样既有输入能力,又有输出能力。输出能力,就可以让定时器感知到电平变化。通过感知到的电平变化开始控制定时器计数开始和结束,进而就测量出来两个电平信号之间的时间差。
因此此功能很容易测量出有效电平的持续时间。
高低电平的产生本身可以是 定时器的 PWM 产生的,也可以是我们的超声波雷达产生的,还可以的我们红外人体感应产生的。最简答的产生来源 就是我们的KEY开关。而且还有所有的通信的接口。我们都可以使用测功能来测量。
输入捕获的硬件要求:
引脚外侧:一个可以产生高低电平的器件。
引脚内部:复用功能里面必须要求定时器。
三 输入捕获功能的使用和实现
3.2 任务分配
实施项目,永远先做任务规划。
3.2.3 开始编码
3.2.4 代码展示和整理
void tim_cap_init()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);
//参数配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode =
TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = (5000-1);
TIM_TimeBaseInitStruct.TIM_Prescaler = (8400-1);
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStruct);
//定时器开始工作
TIM_Cmd(TIM5,ENABLE);
//输入捕获参数
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_Channel =TIM_Channel_1;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
TIM_ICInitStruct.TIM_ICSelection
=TIM_ICSelection_DirectTI;
TIM_ICInit(TIM5,&TIM_ICInitStruct);
//定时器都提交给nvic那些事件
TIM_ITConfig(TIM5,TIM_IT_CC1|TIM_IT_Update,ENABLE);
//中断分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//中断配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
中断服务子函数
static uint16_t flag = 0;
static uint16_t i = 0;
void TIM5_IRQHandler()
{
if(SET==TIM_GetFlagStatus(TIM5,TIM_IT_CC1))
{
if(flag == 0)//信号开始了
{
TIM5->CCR1 = 0;
TIM_Cmd(TIM5,ENABLE);
flag = 1;
}
else //信号结束了,结算电平持续时间
{
TIM_Cmd(TIM5,DISABLE);
uint32_t cap = TIM_GetCapture1(TIM5);
cap = i*5000+cap;
printf("cap == %d\n",cap);
flag = 0;
i = 0;
}
TIM_ClearFlag(TIM5,TIM_IT_CC1);
}
//如果该信号持续时间很长,定时器会溢出,这里就散溢出次数
if(SET==TIM_GetFlagStatus(TIM5,TIM_IT_Update))
{
i++;
TIM_ClearFlag(TIM5,TIM_IT_Update);
}
}
输入捕获的编程步骤
第一步,RCC开启时钟,把GPIO和TIM的时钟打开
第二步,GPIO初始化,把GPIO配置成输入模式,一般选择上拉输入或者浮空输入模式
第三步,配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
第四步,配置输入捕获单元,包括滤波器、极性、直连通道还是交叉通道、分频器等参数
第五步,选择从模式的触发源,触发源选择为TI1FP1,调用库函数,给定一个参数即可
第六步,选择从模式触发后的执行操作,执行Reset操作,这里调用库函数即可
最后,调用TIM_Cmd函数,开启定时器