流程图如上 但过于繁琐 有很大程度的冗余
当进入按键中断时,首先检测下降沿,此时falling_flag为0 故进入else printf函数输出下降沿 置falling_flag 为1 清空通道 设置检测上升沿
当松开时 falling_flag为1 进入if语句 输出捕获到上升沿 清空通道 设置为下降沿检测 最后一定要将结构体中的所有都清空 这样就回到了最开始的状态
#include "ic.h"
#include "stdint.h"
#include "stdio.h"
#include "string.h"
struct
{
uint8_t succeed_flag; //检测是否成功捕获到上升or下降沿标志位
uint8_t rising_flag; //上升沿标致位
uint8_t falling_flag; //下降沿标志位
uint8_t timout_cnt; //溢出的次数标致位
}capture_status ={0};
TIM_HandleTypeDef ic_handle={0};
void ic_init(uint16_t arr,uint16_t psc)
{
TIM_IC_InitTypeDef ic_config ={0};
ic_handle.Instance = TIM2;
ic_handle.Init.Period = arr;
ic_handle.Init.CounterMode =TIM_COUNTERMODE_UP;
ic_handle.Init.Prescaler = psc;
HAL_TIM_IC_Init(&ic_handle); //时基工作参数配置
ic_config.ICPolarity = TIM_ICPOLARITY_FALLING; //选择极性 刚开始捕获的是下降沿 故选择下降沿的模式
ic_config.ICSelection = TIM_ICSELECTION_DIRECTTI; //定时器2被直接连接到相应的输入捕获通道
ic_config.ICPrescaler = TIM_ICPSC_DIV1; //默认不分频
ic_config.ICFilter =0; //滤不滤波 不滤波设置为0
HAL_TIM_IC_ConfigChannel(&ic_handle,&ic_config,TIM_CHANNEL_2); //输入通道的配置 捕获的边沿 映射 分频 滤波
__HAL_TIM_ENABLE_IT(&ic_handle,TIM_IT_UPDATE); //更新中断使能 第二个参数为更新中断的模式
HAL_TIM_IC_Start_IT(&ic_handle,TIM_CHANNEL_2); //使能捕获 捕获中断及计数器
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
//①定义初始化结构体
GPIO_InitTypeDef gpio_initstruct;
//打开时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //打开GPIO的时钟
__HAL_RCC_TIM2_CLK_ENABLE(); //打开定时器的时钟
//调用GPIO初始化函数
gpio_initstruct.Pin = GPIO_PIN_1 ; //LED1、LED2对应的引脚
gpio_initstruct.Pull = GPIO_PULLUP; //上拉
gpio_initstruct.Mode =GPIO_MODE_INPUT; //推挽复用输出
gpio_initstruct.Speed =GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOA,&gpio_initstruct);
HAL_NVIC_SetPriority(TIM2_IRQn, 2,2); //设置NVIC
HAL_NVIC_EnableIRQ(TIM2_IRQn); //设置NVIC
}
}
void TIM2_IRQHandler(void)
{
HAL_TIM_IRQHandler(&ic_handle);
}
//下面代码冗余
/*
void HAL_TIM_IC_CaptureCallback (TIM_HandleTypeDef *htim)
{
//printf("捕获到下降沿\r\n");
if(htim->Instance == TIM2) //回调函数中也有很多定时器 因此要确是否是定时器2
{
if(capture_status.succeed_flag == 0)
{
if(capture_status.falling_flag == 1)
{
printf("捕获到上升沿\r\n");
capture_status.succeed_flag =1;
TIM_RESET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2); //清除通道设置 传入两个参数 一个是距离 另外一个是渠道
TIM_SET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING); //设置为下降沿检测等待检测下降沿 变成初始检测状态
memset(&capture_status,0,sizeof(capture_status)); //让结构体中的所有都置0
}
else
{
printf("捕获到下降沿\r\n");
memset(&capture_status,0,sizeof(capture_status)); //让结构体中的所有都置0
capture_status.falling_flag = 1;
TIM_RESET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2); //清除通道设置 传入两个参数 一个是距离 另外一个是渠道
TIM_SET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING); //设置为上升沿检测等待检测上升沿 因为初始检测的是下降沿
}
}
}
}
*/
void HAL_TIM_IC_CaptureCallback (TIM_HandleTypeDef *htim)
{
//printf("捕获到下降沿\r\n");
if(htim->Instance == TIM2) //回调函数中也有很多定时器 因此要确是否是定时器2
{
if(capture_status.falling_flag == 1)
{
printf("捕获到上升沿\r\n");
TIM_RESET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2); //清除通道设置 传入两个参数 一个是距离 另外一个是渠道
TIM_SET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING); //设置为下降沿检测等待检测下降沿 变成初始检测状态
memset(&capture_status,0,sizeof(capture_status)); //让结构体中的所有都置0
}
else
{
printf("捕获到下降沿\r\n");
capture_status.falling_flag = 1;
TIM_RESET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2); //清除通道设置 主要用于清空下降沿捕获的命令 传入两个参数 一个是距离 另外一个是渠道
TIM_SET_CAPTUREPOLARITY(&ic_handle,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING); //设置为上升沿检测等待检测上升沿 因为初始检测的是下降沿
}
}
}