STM32基于hal库定时器输入捕获

原理要自己学习,这里仅仅给出最简单的通俗易懂的代码

//main.h
typedef struct              //测量低电平脉宽
{   
	uint8_t   ucFinishFlag; //结束
	uint8_t   ucStartFlag;  //开始
	uint16_t  usCtr;
	uint16_t  usPeriod;
}STRUCT_CAPTURE;

//main.c
STRUCT_CAPTURE strCapture = { 0, 0, 0 };
uint32_t ulTmrClk, ulTime,ulTimea,ulTimeb;
int main(void)
{
/* 获取定时器时钟周期 */	
	ulTmrClk = HAL_RCC_GetHCLKFreq()/72; //实际上就是定时器时钟/预分频系数 72M/72获取每次计数时间  
  /* 启动定时器 */
  HAL_TIM_Base_Start_IT(&htim2);  
  /* 启动定时器通道输入捕获并开启中断 */
  HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
 while (1)
  {
      
       /* 完成测量低电平脉宽 */
    if(strCapture.ucFinishFlag == 1 )
		{
      /* 计算低电平计数值 */
			ulTime = strCapture .usPeriod * 0xFFFF + strCapture .usCtr;//0xFFFF为Period计数周期
			/* 打印低电平脉宽时间 */
			printf ( ">>测得低电平脉宽时间:%d.%d s\n", ulTime / ulTmrClk, ulTime % ulTmrClk ); 
			strCapture .ucFinishFlag = 0;			
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
}


/* USER CODE BEGIN 4 */
/**
  * 函数功能: 非阻塞模式下定时器的回调函数
  * 输入参数: htim:定时器句柄
  * 返 回 值: 无
  * 说    明: 无
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    //每次溢出时间为65536us
    //需要判断电平时间是否太长
    if(strCapture.ucFinishFlag==0)//还未成功捕获
    {
        if(strCapture.ucStartFlag==1)//已经开始捕获
			{
				if(strCapture.usPeriod==0XFFFF)//电平太长了
				{
					strCapture.ucFinishFlag=1;		//标记成功捕获了一次
					strCapture .usCtr=0XFFFF;
				}else strCapture .usPeriod ++;
			}	 
    }
    //不需要判断电平时间是否太长
//  strCapture .usPeriod ++;
}

/**
  * 函数功能: 定时器输入捕获中断回调函数
  * 输入参数: htim:定时器句柄
  * 返 回 值: 无
  * 说    明: 无
  */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  TIM_IC_InitTypeDef sConfigIC;
  
  if ( strCapture .ucStartFlag == 0 )
  {
    LED_TOGGLE;       
    
    __HAL_TIM_SET_COUNTER(htim,0); // 清零定时器计数
    strCapture .usPeriod = 0;			
    strCapture .usCtr = 0;
    
    // 配置输入捕获参数,主要是修改触发电平
    sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
    sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    sConfigIC.ICFilter = 0;
    HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
    // 清除中断标志位
    __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
    // 启动输入捕获并开启中断
    HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);    
    strCapture .ucStartFlag = 1;			
  }		
  
  else
  {
    LED_TOGGLE;
    
    // 获取定时器计数值
    strCapture .usCtr = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
    // 配置输入捕获参数,主要是修改触发电平
    sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
    sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    sConfigIC.ICFilter = 0;
    HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
    
    // 清除中断标志位
    __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); 
    // 启动输入捕获并开启中断
    HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);    
    strCapture .ucStartFlag = 0;			
    strCapture .ucFinishFlag = 1;    
  }
}

/* USER CODE END 4 */

你可能感兴趣的:(stm32)