/** ****************************************************************************** * @file TIM/TIM_PWMInput/Src/main.c * @author MCD Application Team * @brief This example shows how to use the TIM peripheral to measure the * frequency and duty cycle of an external signal. ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2016 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /** @addtogroup STM32F3xx_HAL_Examples * @{ */ /** @addtogroup TIM_PWMInput * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Timer handler declaration */ TIM_HandleTypeDef TimHandle; /* Timer Input Capture Configuration Structure declaration */ TIM_IC_InitTypeDef sConfig; /* Slave configuration structure */ TIM_SlaveConfigTypeDef sSlaveConfig; /* Captured Value */ __IO uint32_t uwIC2Value = 0; /* Duty Cycle Value */ __IO uint32_t uwDutyCycle = 0; /* Frequency Value */ __IO uint32_t uwFrequency = 0; /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void Error_Handler(void); /* Private functions ---------------------------------------------------------*/ /** * @brief Main program. * @param None * @retval None */ int main(void) { /* STM32F3xx HAL library initialization: - Configure the Flash prefetch - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 64 MHz */ SystemClock_Config(); /* Configure LED2 */ BSP_LED_Init(LED2); /*##-1- Configure the TIM peripheral #######################################*/ /* --------------------------------------------------------------------------- TIM3 configuration: PWM Input mode In this example TIM3 input clock (TIM3CLK) is set to APB1 clock (PCLK1), since APB1 prescaler is 1. TIM3CLK = PCLK1 PCLK1 = HCLK => TIM3CLK = HCLK = SystemCoreClock External Signal Frequency = TIM3 counter clock / TIM3_CCR2 in Hz. External Signal DutyCycle = (TIM3_CCR1*100)/(TIM3_CCR2) in %. --------------------------------------------------------------------------- */ /* Set TIMx instance */ TimHandle.Instance = TIMx; /* Initialize TIMx peripheral as follows: + Period = 0xFFFF + Prescaler = 0 + ClockDivision = 0 + Counter direction = Up */ TimHandle.Init.Period = 0xFFFF; TimHandle.Init.Prescaler = 0; TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0; TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_IC_Init(&TimHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-2- Configure the Input Capture channels ###############################*/ /* Common configuration */ sConfig.ICPrescaler = TIM_ICPSC_DIV1; sConfig.ICFilter = 0; /* Configure the Input Capture of channel 1 */ sConfig.ICPolarity = TIM_ICPOLARITY_FALLING; sConfig.ICSelection = TIM_ICSELECTION_INDIRECTTI; if (HAL_TIM_IC_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /* Configure the Input Capture of channel 2 */ sConfig.ICPolarity = TIM_ICPOLARITY_RISING; sConfig.ICSelection = TIM_ICSELECTION_DIRECTTI; if (HAL_TIM_IC_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_2) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*##-3- Configure the slave mode ###########################################*/ /* Select the slave Mode: Reset Mode */ sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; sSlaveConfig.InputTrigger = TIM_TS_TI2FP2; sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED; sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; sSlaveConfig.TriggerFilter = 0; if (HAL_TIM_SlaveConfigSynchronization(&TimHandle, &sSlaveConfig) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*##-4- Start the Input Capture in interrupt mode ##########################*/ if (HAL_TIM_IC_Start_IT(&TimHandle, TIM_CHANNEL_2) != HAL_OK) { /* Starting Error */ Error_Handler(); } /*##-5- Start the Input Capture in interrupt mode ##########################*/ if (HAL_TIM_IC_Start_IT(&TimHandle, TIM_CHANNEL_1) != HAL_OK) { /* Starting Error */ Error_Handler(); } while (1) { } } /** * @brief Input Capture callback in non blocking mode * @param htim : TIM IC handle * @retval None */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { /* Get the Input Capture value */ uwIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); if (uwIC2Value != 0) { /* Duty cycle computation */ uwDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1)) * 100) / uwIC2Value; /* uwFrequency computation TIM3 counter clock = (RCC_Clocks.HCLK_Frequency) */ uwFrequency = (HAL_RCC_GetHCLKFreq()) / uwIC2Value; } else { uwDutyCycle = 0; uwFrequency = 0; } } } /** * @brief This function is executed in case of error occurrence. * @param None * @retval None */ static void Error_Handler(void) { /* Turn LED2 on */ BSP_LED_On(LED2); while (1) { } } /** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSI) * SYSCLK(Hz) = 64000000 * HCLK(Hz) = 64000000 * AHB Prescaler = 1 * APB1 Prescaler = 2 * APB2 Prescaler = 1 * HSI Frequency(Hz) = 8000000 * PREDIV = RCC_PREDIV_DIV2 (2) * PLLMUL = RCC_PLL_MUL16 (16) * Flash Latency(WS) = 2 * @param None * @retval None */ void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* HSI Oscillator already ON after system reset, activate PLL with HSI as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_NONE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK) { /* Initialization Error */ while(1); } /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2)!= HAL_OK) { /* Initialization Error */ while(1); } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(char *file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/