在这个例程中用了定时器5通道1的输入捕获/比较模式,测定按下一次按键用时为多少。
在用cubemx生成配置代码时,我们用到了串口和定时器5的通道1,串口的初始化代码非常简单,就是设置了波特率为115200,8位数据位,一个停止位,没有校验位,收发模式。
在初始化定时器的代码中,用到了 GENERAL_TIMx_Init(); 函数,我们go to definition进入函数体。
里面的配置几乎和我上一篇文章的PWM输出中对定时器的配置一样,只有一条代码不同。
我们双击GENERAL_TIM_STRAT_ICPolarity得到下图:
再次双击TIM_INPUTCHANNELPOLARITY_RISING得到下图:
我们可以看出我们最终设置的是TIM的CCER寄存器的CC1P位寄存器所在位置如下图;
我们选择的是输入捕获,此处配置为上升沿捕获。
接着我们看main函数下面的内容, ulTmrClk = HAL_RCC_GetHCLKFreq()/GENERAL_TIM_PRESCALER; (‘/’操作符两个操作数都是一个宏定义) 这条代码的意思是对系统主时钟进行72分频,使定时器的时钟为1MHZ即计数器加一走时1us。在while(1)中 :
while (1)
{
if(strCapture.ucFinishFlag == 1 )//参数为捕获的结束标志,属于定义的一个结构体变量
{
//strCapture .usPeriod为定时器正常计数溢出次数
//strCapture .usCtr为计数器当前值
ulTime = strCapture .usPeriod * GENERAL_TIM_PERIOD + strCapture .usCtr;//得到总的计数
printf ( "测得高电平脉宽时间为:%d.%d s\n", ulTime / ulTmrClk, ulTime % ulTmrClk );
strCapture .ucFinishFlag = 0;
}
}
在定时器每次溢出时,会执行strCapture .usPeriod ++;得到溢出次数。
这里重点讲解定时器输入捕获中断回调函数。
回调函数主要流程就是:当我们按下KEY1时(KEY1和定时器5通道1连在同一个引脚)判断捕获是否开启按下按键后首先会进入if分支,首先翻转小灯状态,清零计数器,修改捕获触发方式为下降沿捕获,以便按键弹起时能检测到,清楚当前中断标志位,并重新开启捕获中断以便下次产生中断能进入回调函数,设置捕获开始标志 strCapture .ucStartFlag = 1; 退出循环并退出函数。
当按键弹起时,再次翻转小灯状态,获取定时器CNT的值,配置下降沿捕获。并设置结束标志strCapture .ucFinishFlag = 1; strCapture .ucStartFlag = 0;退出循环。
这样就可以得到高电平的时间,由(溢出次数*计数周期+TIM->CNT)*1us=T(总)。