/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 180 MHz */ SystemClock_Config(); /* Configure LED3 */ BSP_LED_Init(LED3); /*##-1- Configure the TIM peripheral #######################################*/ /* ----------------------------------------------------------------------- In this example TIM3 input clock (TIM3CLK) is set to 4 * APB1 clock (PCLK1), since TIMPRE bit from RCC_DCKCFGR register is set. TIM3CLK = 4 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK = SystemCoreClock For TIM3CLK equal to SystemCoreClock, TIM3 counter clock is computed as follows: TIM3 counter clock = TIM3CLK / (Prescaler + 1) = SystemCoreClock / (Prescaler + 1) = 36MHz For ARR equal to (1800 - 1), the TIM3 output clock is computed as follows: TIM3 output clock = TIM3 counter clock / (ARR + 1) = 20KHZ The TIM3 CCR1 register value is equal to 900, so the TIM3 Channel 1 generates a PWM signal with a frequency equal to 20 KHz and a duty cycle equal to 50%: TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR + 1)* 100 = 50% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency ----------------------------------------------------------------------- */ /* Timer clock prescalers selection activation */ __HAL_RCC_TIMCLKPRESCALER(RCC_TIMPRES_ACTIVATED); /* Initialize TIMx peripheral as follow: + Prescaler = (5 - 1) + Period = (1800 - 1) + ClockDivision = 0 + Counter direction = Up */ TimHandle.Instance = TIMx; TimHandle.Init.Prescaler = PRESCALER_VALUE; TimHandle.Init.Period = PERIOD_VALUE; TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0x0; if(HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-2- Configure the PWM channels #########################################*/ /* Common configuration for all channels */ sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCFastMode = TIM_OCFAST_DISABLE; /* Set the pulse value for channel 1 */ sConfig.Pulse = PULSE1_VALUE; if(HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*##-3- Start PWM signals generation #######################################*/ /* Start channel 1 */ if(HAL_TIM_PWM_Start_IT(&TimHandle, TIM_CHANNEL_1) != HAL_OK) { /* Starting Error */ Error_Handler(); } /* Infinite loop */ while (1) { } }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /* STM32F4xx HAL library initialization: - Configure the Flash prefetch - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure LED3 */ BSP_LED_Init(LED3); /* Configure the system clock to 180 MHz */ SystemClock_Config(); /* Compute the prescaler value to have TIM3 counter clock equal to 36000000 Hz */ uhPrescalerValue = (uint32_t)(SystemCoreClock / 36000000) - 1; /*##-1- Configure the TIM peripheral #######################################*/ /* ----------------------------------------------------------------------- TIM3 Configuration: generate 1 PWM signal with clock prescaler selection feature activated using __HAL_RCC_TIMCLKPRESCALER() which allow to double the output frequency. In this example TIM3 input clock (TIM3CLK) is set to 4 * APB1 clock (PCLK1), since Timer clock prescalers selection activated (TIMPRE bit from RCC_DCKCFGR register is set). TIM3CLK = 4 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK = SystemCoreClock For TIM3CLK equal to SystemCoreClock and prescaler equal to (5 - 1), TIM3 counter clock is computed as follows: TIM3 counter clock = TIM3CLK / (Prescaler + 1) = SystemCoreClock / (Prescaler + 1) = 36MHz For ARR equal to (1800 - 1), the TIM3 output clock is computed as follows: TIM3 output clock = TIM3 counter clock / (ARR + 1) = 20KHZ The TIM3 CCR1 register value is equal to 900, so the TIM3 Channel 1 generates a PWM signal with a frequency equal to 20 KHz and a duty cycle equal to 50%: TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR + 1)* 100 = 50% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency ----------------------------------------------------------------------- */ /* Timer clock prescalers selection activation */ __HAL_RCC_TIMCLKPRESCALER(RCC_TIMPRES_ACTIVATED); /* Initialize TIMx peripheral as follows: + Prescaler = (SystemCoreClock / 36000000) - 1 + Period = (1800 - 1) + ClockDivision = 0 + Counter direction = Up */ TimHandle.Instance = TIMx; TimHandle.Init.Prescaler = uhPrescalerValue; TimHandle.Init.Period = PERIOD_VALUE; TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0; if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-2- Configure the PWM channels #########################################*/ /* Common configuration for all channels */ sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; /* Set the pulse value for channel 1 */ sConfig.Pulse = PULSE1_VALUE; if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*##-3- Start PWM signals generation #######################################*/ /* Start channel 1 */ if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1) != HAL_OK) { /* PWM Generation Error */ Error_Handler(); } /* Start channel 2 */ if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_2) != HAL_OK) { /* PWM Generation Error */ Error_Handler(); } /* Start channel 3 */ if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_3) != HAL_OK) { /* PWM generation Error */ Error_Handler(); } /* Start channel 4 */ if (HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_4) != HAL_OK) { /* PWM generation Error */ Error_Handler(); } while (1) { } }