STM32测量按键按下时长
测量原理:
检测到下降沿后,就开始计时,直到检测到上升沿后再停止计时,在这个过程中,我们设置的自动重装载值ARR最大为65536,所以在按键按下去后,中间可能会有N多次的溢出时间,那么我们最后可以使用这样一个计算公式,time = arr_cnt*65536+ccr_cnt,arr_cnt是自动重装载次数,ccr_cnt是寄存器中的计数,根据计算公式,就可以得到按键从捕获到下降沿到上升沿的时间了。
配置过程:
参考这一篇博客:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/142829989
1、准备工作
我们在进行捕获的时候,通常需要一些标志位来进行操作,通常需要用到(成功捕获、下降捕获、上升捕获,时间计数)这样四个标志位,使用要给结构体把它们定义出来。
struct
{
uint8_t succeed_flag;
uint8_t rising_flag;
uint8_t falling_flag;
uint8_t time_cnt;
} caputure_status = {0};
2、编写代码
在参考博客中的回调函数HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)中,我们需要实现一个流程图:
根据这个流程图,我们可以写出捕获到下降沿的代码:
printf("捕获到下降沿\n");
memset(&caputure_status,0,sizeof(caputure_status));
caputure_status.falling_flag =1;
__HAL_TIM_DISABLE(&ic_handle);
__HAL_TIM_SET_COUNTER(&ic_handle,0);
TIM_RESET_CAPTUREPOLARITY(&ic_handle, TIM_CHANNEL_2);
TIM_SET_CAPTUREPOLARITY(&ic_handle, TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);
__HAL_TIM_ENABLE(&ic_handle);
第一行:如果succeed_flag=0,判断falling_flag是否等于0,若等于,则在串口中显示“捕获到下降沿”
第二行:memset函数用于对一整个结构体的清零,这里我们就是把四个标志位全部清零。
第三行:将falling_flag = 1;
第四行:关闭定时器。
第五行:将定时器清零。
第六行:清除通道设置
第七行:设置通道为上升沿捕获
第八行:重新开启定时器
以上代码就把捕获下降沿状态转换为捕获上升沿状态。
同样的,我们可以根据流程图写出捕获上升沿的代码:
printf("捕获到上升沿\n");
caputure_status.succeed_flag =1;
last_cnt = HAL_TIM_ReadCapturedValue(&ic_handle,TIM_CHANNEL_2);
TIM_RESET_CAPTUREPOLARITY(&ic_handle, TIM_CHANNEL_2);
TIM_SET_CAPTUREPOLARITY(&ic_handle, TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);
第一行: 若检测到succeed_flag = 1,在串口输出“捕获到上升沿”
第二行:将succeed_flag置为1,也就是表明一次完整的按键检测已经完成。
第三行:将定时器中ccr的值读取出来,方便计算
第四行~第五行同上
这里不需要将结构体的标志位置为0,我们在后面调用的函数中再使用。现在已经把流程图的代码写完了,因为我们的要求是显示出按键按下的时间,所以根据计算公式,我们已经知道了ccr中的值,还不知道ARR溢出了多少次,下面就编写ARR溢出的次数。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
if(caputure_status.succeed_flag == 0)
{
if(caputure_status.falling_flag == 1)
{
caputure_status.time_cnt++;
}
}
}
}
调用HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)函数
第一行:判断是否在使用定时器2
第二行:判断是否成功按下
第三行:若成功按下,检测到下降沿,则溢出次数加1;
最后我们需要一个函数输出按键按下的状态和按下的时间
void pressed_time_get(void)
{
if(caputure_status.succeed_flag == 1)
{
printf("按下时间:%d us\r\n",caputure_status.time_cnt*65536 + last_cnt);
memset(&caputure_status,0,sizeof(caputure_status));
}
}
第一行:如果成功按下
第二行:串口打印时间,时间是根据计算公式来的
第三行:清零结构体
在主函数中不断调用这个函数即可,注意需要延时一点点。
效果:
以上我们就完成了对按键按下时间的捕获。
作者:ljhlovezyx