1. 程式人生 > >基於STM32F103和Cube的輸入捕獲例程

基於STM32F103和Cube的輸入捕獲例程

1.開發環境

(1)Cube5.24

(2)Keil5

(3)STM32F103

2.Cube配置

Cube配置很簡單,只要開啟TIM4通道1的引腳,設定為輸入捕獲模式,在配置是高或低電平沿觸發

 

TIM的定時器時鐘可根據自己的需要來配置,觸發模式為上升沿觸發

 

 

 

最後把中斷給開啟

 

Cube生成的程式碼如下:

 

 

void MX_TIM4_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};

  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 2;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 0xffff;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_IC_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_TIM_IC_MspInit(TIM_HandleTypeDef* tim_icHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(tim_icHandle->Instance==TIM4)
  {
  /* USER CODE BEGIN TIM4_MspInit 0 */

  /* USER CODE END TIM4_MspInit 0 */
    /* TIM4 clock enable */
    __HAL_RCC_TIM4_CLK_ENABLE();
  
    __HAL_RCC_GPIOD_CLK_ENABLE();
    /**TIM4 GPIO Configuration    
    PD12     ------> TIM4_CH1 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_TIM4_ENABLE();

    /* TIM4 interrupt Init */
    HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM4_IRQn);
  /* USER CODE BEGIN TIM4_MspInit 1 */

  /* USER CODE END TIM4_MspInit 1 */
  }
}

void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef* tim_icHandle)
{

  if(tim_icHandle->Instance==TIM4)
  {
  /* USER CODE BEGIN TIM4_MspDeInit 0 */

  /* USER CODE END TIM4_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM4_CLK_DISABLE();
  
    /**TIM4 GPIO Configuration    
    PD12     ------> TIM4_CH1 
    */
    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_12);

    /* TIM4 interrupt Deinit */
    HAL_NVIC_DisableIRQ(TIM4_IRQn);
  /* USER CODE BEGIN TIM4_MspDeInit 1 */

  /* USER CODE END TIM4_MspDeInit 1 */
  }
} 

 

 

 

 

 

3.主程式

在寫自己的程式碼之前要說一下HAL庫的stm32f1xx_hal_tim.c裡有一個BUG,他們這個巨集定義——#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__)要改一下

原本如下:

 

#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP))) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P)) :\
   ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P)))

 

 

 

改了如下:

#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P)) :\
   ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P)))

 

 

兩者唯一的區別就是原本的第一行後面多了一個括號!!!

輸入捕獲的功能就是當輸入捕獲引腳檢測到上升沿或下降沿時進入中斷服務函式,處理事務,該中斷服務函式為void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

主函式:

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        if(capture_Cnt==0)
        {
             __HAL_TIM_SET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);           //設定為上升沿捕獲
             HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_1);
             capture_Cnt++;
            
             
        }

        
  }

 

中斷函式

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
 uint32_t a;
    if(TIM4 == htim->Instance)
    {
        if(capture_Cnt==1)
        {
             //capture_Buf[0] =HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);                     //獲取當前的捕獲值
             HAL_TIM_IC_Stop_IT(&htim4,TIM_CHANNEL_1);                                            //停止捕獲   
                capture_Cnt=0;
              Number++;
             printf("\n%d",Number);
//            printf("\n捕捉上升沿:%d",capture_Buf[0] );
            
        }



    }
    
}

 

我這裡只是計算一下進入了多少次中斷,你們可以根據自己的需求來寫處理的程式。

&n