通用定时器输入捕获实验,通常用于测量外部信号的频率和占空比。在这个实验中,利用通用定时器2的输入捕获功能测量按下KEY4键后低电平持续的时间,并使用定时器捕获输入信号的时间,并将结果与预期值进行比较。
通用定时器输入捕获实验的步骤:
(1)配置Key4的GPIO引脚PA0作为通用定时器的输入引脚,并将PA0设置为:TIM2_CH1
(2)配置TIM2的时钟源:内部时钟;打开通道1,设置为输入捕获功能;配置TIM2
(TIM2 和 TIM5的计数器的值是32位的)
(3)配置TIM2定时器中断,主优先级和子优先级都配置的稍微低一点(比如2级)
(4)配置时钟:选择外部晶振模式
(5)打开串口USART1(方便调试代码)
输入捕获实验原理图
第一次捕获,要使能捕获中断,这样才能进入中断里边,进入中断之后,将CNT清零,并且将下次捕获方式设置为上升沿;同时溢出中断也要打开,为了记录溢出多少次。
printf("this is Tim2_cap test\n"); //调试程序
HAL_TIM_Base_Start_IT(&htim2); //启动定时器2中断,使能溢出更新中断
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //捕获中断
uint8_t fall_flag = 0; //下降沿捕获标记位
uint32_t cap_value = 0; //计数的总值
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //溢出更新
{
if(htim->Instance == TIM2) //判断是不是Tim2触发中断
{
if(fall_flag)
{
cap_value += 1000000; //每次溢出都做加ARR的记录
printf("updata int\n");//溢出一次,打印一次
}
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) //实现捕获中断
{
if(htim->Instance == TIM2) //判断是不是Tim2触发中断
{
if(!fall_flag) //当前捕获到的是下降沿
{
printf("捕获到了下降沿\n");
HAL_Delay(20); //延时20ms,消抖
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) //再次判断
{
fall_flag = 1;
__HAL_TIM_DISABLE(htim); //关闭定时器
__HAL_TIM_SET_COUNTER(htim,0); //设置计数器的值为0
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); //清除原来的设置
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
//设置为上升沿捕获
__HAL_TIM_ENABLE(htim); //使能定时器
}
}
else
{
printf("捕获到了上升沿\n");
fall_flag = 0; //当前捕获到的是上升沿,本次捕获结束
cap_value = cap_value + HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) + 20000;
//最终时间 = 溢出时间 + 两次计数差值 + 延时消抖时间
//cap_value = value + n* ARR;
printf("低电平持续时间= %d秒: %d毫秒: %d微妙\n",cap_value/1000000,cap_value%1000000/1000,cap_value%1000);
cap_value = 0;
__HAL_TIM_DISABLE(htim); //关闭定时器
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); //清除原来的设置
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
//设置为下降沿捕获
__HAL_TIM_ENABLE(htim); //使能定时器
HAL_Delay(20);
}
}
}
实验现象:
代码已详细标记注释,如果还是不太明白,可以评论或私信我。