这里我只介绍一下timer.c中的一个函数,其他的几个函数都是初始化函数,这个大家都很清楚,也没什么好讲的。接下来就看看我接下来要讲的函数:
u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态
u16 TIM2CH1_CAPTURE_VAL; //输入捕获值
//定时器2中断服务程序
void
TIM2_IRQHandler(void)
{
if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)//检查指定的TIM中断发生与否:TIM 中断源
{
if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM2CH1_CAPTURE_VAL=0XFFFF;
}
else
{
TIM2CH1_CAPTURE_STA++;
}
}
}
if (TIM_GetITStatus(TIM2,TIM_IT_CC1) != RESET)//捕获1发生捕获事件
{
if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿
{
TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次上升沿
TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);//记下捕获的值
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);//CC1P=0 设置为上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM2CH1_CAPTURE_STA=0; //清空
TIM2CH1_CAPTURE_VAL=0;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}
}
}
TIM_ClearITPendingBit(TIM2,
TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}
开头定义的两个全局变量:TIM2CH1_CAPTURE_STA的作用在接下来我们会讲到,而TIM2CH1_CAPTURE_VAL则是我们在主函数中计算时间所需要用到的数。
TIM2CH1_CAPTURE_STA是一个八位二进制数,各个位的作用如下:
现在让我们来好好看看这个中断函数。
第一个if判断判断的是TIM2CH1_CAPTURE_STA的最高位是不是0,如果为0表示还没有完全捕获到一个完整的高电平(有一个上升沿和一个下降沿),在刚开始这个判断肯定为真,现在让我们进入这个函数,紧接着的这个判断if (TIM_GetITStatus(TIM2,
TIM_IT_Update) != RESET)判断的是TIM2是否发生了中断,再下面的一层判断if(TIM2CH1_CAPTURE_STA&0X40)则是判断TIM2CH1_CAPTURE_STA的第二高位是否为1,如果为1,则表示已经接收到了一个上升沿。再往里if判断的我将会在最后的一个流程内解释清楚。
if (TIM_GetITStatus(TIM2,
TIM_IT_CC1) != RESET)这个if判断判断的则是是否捕获到你定义的捕获(这里就是上升沿捕获或者下降沿捕获),前面的初始化函数里已经初始化为上升沿捕获,所以第一次这是是判断是否捕获到上升沿。如果捕获到了,进入第二层判断,判断TIM2CH1_CAPTURE_STA的次高位是否为1,不是1则执行else内的内容。
讲了这么多,我想你们可能还没有完全理解,接下来我就以一个高电平的例子来讲一下这个中断函数。
开始了,进行第一层判断if((TIM2CH1_CAPTURE_STA&0X80)==0),这时TIM2CH1_CAPTURE_STA=00000000,为真,进入判断if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET) ,这个判断在TIM2发生中断的时候自动进入,关键在if(TIM2CH1_CAPTURE_STA&0X40)这个判断,前面我们说了TIM2CH1_CAPTURE_STA=00000000,没有执行这个判断内部代码的权利,只有次高位为1即TIM2CH1_CAPTURE_STA=x1xxxxxx时,才有权利进去。所以,我们把他先放在一边。
接下来我们看这个判断if (TIM_GetITStatus(TIM2, TIM_IT_CC1)!= RESET),前面我们也说了,这个是判断是否捕获到上升沿的。好的,这个判断就是我们的开始,当我们捕获到一个上升沿的时候,进入,if(TIM2CH1_CAPTURE_STA&0X40)为假,执行else,
else
{
TIM2CH1_CAPTURE_STA=0;
TIM2CH1_CAPTURE_VAL=0;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAPTURE_STA|=0X40;
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);
}
这里让TIM2CH1_CAPTURE_STA的次高位为1了,而且改成了捕获下降沿!!!!!
然后在接下执行中断函数的时候 ,我们就有进入这个if(TIM2CH1_CAPTURE_STA&0X40)判断的权利,因为现在TIM2CH1_CAPTURE_STA=01xxxxxx,现在我们看这个判断内的代码:
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)
{
TIM2CH1_CAPTURE_STA|=0X80;
TIM2CH1_CAPTURE_VAL=0XFFFF;
}
else
{
TIM2CH1_CAPTURE_STA++;
}
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)这个判断的是TIM2CH1_CAPTURE_STA后六位是否都为1,如果都为1表示这个高电平的时间很长很长,这时强制将TIM2CH1_CAPTURE_STA的最高位置1,令TIM2CH1_CAPTURE_VAL=0XFFFF,完成一个高电平的接收。如果后六位不都为1,TIM2CH1_CAPTURE_STA++,表示溢出次数加1.。如此反复,直至到下降沿的到来。
当下降沿到来的时候if (TIM_GetITStatus(TIM2, TIM_IT_CC1) !=RESET)为真(因为前面已经将捕获事件改为捕获下降沿!!!这里不再是捕获上升沿),第二层判断if(TIM2CH1_CAPTURE_STA&0X40)也为真
if(TIM2CH1_CAPTURE_STA&0X40)
{
TIM2CH1_CAPTURE_STA|=0X80;
TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);
}
将TIM2CH1_CAPTURE_STA最高位置1,读取最后一次中断计数器内的数,再改为捕获上升沿,为下一次读取高电平做准备。
到这里,一个高电平就读取完了,数据将在主函数中处理。
总而言之,当TIM2CH1_CAPTURE_STA最高位置1时,一个高电平就读取完了。