(1)Cube5.24函數
(2)Keil5ui
(3)STM32F103spa
Cube配置很簡單,只要打開TIM4通道1的引腳,設置爲輸入捕獲模式,在配置是高或低電平沿觸發code
TIM的定時器時鐘可根據本身的須要來配置,觸發模式爲上升沿觸發blog
最後把中斷給打開事務
Cube生成的代碼以下:ip
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 */ } }
在寫本身的代碼以前要說一下HAL庫的stm32f1xx_hal_tim.c裏有一個BUG,他們這個宏定義——#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__)要改一下開發
本來以下:it
#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)))
改了以下:io
#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] ); } } }
我這裏只是計算一下進入了多少次中斷,大家能夠根據本身的需求來寫處理的程序。