本次我们捕获一下按下按键KEY4持续电平变化时间的长短
查看电路原理图:得到按键的信息
我们使用cubeMX配置一下引脚:
查看芯片数据手册,看外设架构:
发现定时器2是连接在APB1总线,最大允许外设时钟频率42MHZ,来配置cubeMX时钟系统:
定时器2的内部时钟频率是84MHZ
我们设置1s产生一次溢出中断,且计数一次耗时1us(1MHZ)
按键空闲的状态GPIO处于高电平,按键按下的时候GPIO处于低电平,
所以我们捕获下降沿。
至此,关于定时器的基本配置基本ok,我们还要配置一下定时器2的全局中断
嘻嘻,你认为就可以写程序了么?no,no,no此时此刻我们还不知道写的程序正确与否呢,需要打开串口进行程序的结果显示,
定时器的相关中断需要我们自己手动开启:
HAL_UART_Transmit(&huart1,"串口初始化完成!!!\r\n",strlen("串口初始化成功!\r\n"),10);
HAL_TIM_Base_Start_IT(&htim2);
HAL_UART_Transmit(&huart1,"定时器2溢出中断打开!!!\r\n",strlen("定时器2溢出中断打开!!!\r\n"),10);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
HAL_UART_Transmit(&huart1,"定时器2捕获中断打开!!!\r\n",strlen("定时器2捕获中断打开!!!\r\n"),10);
/* USER CODE BEGIN 1 */
uint16_t flag = 0;
uint32_t res = 0;//时间间隔,微秒级别
char data[64] = {0};
/*定时器溢出中断*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(flag)
{
HAL_UART_Transmit(&huart1,"定时器溢出!!!\r\n",strlen("定时器溢出!!!\r\n"),10);
res += 1000000; /*定时器溢出周期是1s,1s = 1 000 000us = 1 000ms*/
}
else
{
res = res;
}
}
/*定时器输入捕获中断*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
if(!flag)
{
/*消除抖动*/
HAL_Delay(20);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
{
flag = 1;
__HAL_TIM_DISABLE(htim);
__HAL_TIM_SetCounter(htim,0);
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1);
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_TRIGGERPOLARITY_RISING);
__HAL_TIM_ENABLE(htim);
}
}
else
{
flag = 0;
res = res + HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1) + 20;
sprintf(data,"秒:%d,毫秒:%d,微秒:%d\r\n",res / 1000000,res % 1000000 / 1000,res % 1000000 % 1000);
HAL_UART_Transmit(&huart1,(uint8_t*)data,strlen(data),10);
memset((void*)data,0,256);
res = 0;
__HAL_TIM_DISABLE(htim);
__HAL_TIM_SET_COUNTER(htim,0);
TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1);
TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_TRIGGERPOLARITY_FALLING);
__HAL_TIM_ENABLE(htim);
}
}
}
/* USER CODE END 1 */