cancel
Showing results for 
Search instead for 
Did you mean: 

How do I configure timer and pin in PWM output mode?

ADing.11
Associate

I am trying to configure TIM4 Channel 1 and PB6 in PWM output mode on my STM32L476 Discovery.

I found an example for the STM32L476G-Nucleo, but they didn't configure any pins, so I tried to do that myself.

I am new to programming on this board so I am sorry, but I am not sure what other information I can provide.

Here is what my main function looks like:

The 6 lines of code under "/* Config PB6 as alternative function */" are the ones that I added.

int main(void)
{
  /* STM32L4xx 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 the system clock to 80 MHz */
  SystemClock_Config();
 
  /* Configure LED4 */
  BSP_LED_Init(LED4);
	
	
	/* Config PB6 as alternative function */
	__HAL_RCC_GPIOB_CLK_ENABLE();
	
	GPIO_InitTypeDef GPIO_InitAF;
	
  GPIO_InitAF.Pin = GPIO_PIN_6;
  GPIO_InitAF.Mode = GPIO_MODE_AF_PP;
	
	HAL_GPIO_Init(GPIOB, &GPIO_InitAF);
 
 
 
  /* Compute the prescaler value to have TIM1 counter clock equal to 16000000 Hz */
  uhPrescalerValue = (uint32_t)(SystemCoreClock / 16000000) - 1;
 
 
  /*##-1- Configure the TIM peripheral #######################################*/
  /* -----------------------------------------------------------------------
  TIM1 Configuration: generate 4 PWM signals with 4 different duty cycles.
 
    In this example TIM1 input clock (TIM1CLK) is set to APB1 clock (PCLK1),
    since APB1 prescaler is equal to 1.
      TIM1CLK = PCLK1
      PCLK1 = HCLK
      => TIM1CLK = HCLK = SystemCoreClock
 
    To get TIM1 counter clock at 16 MHz, the prescaler is computed as follows:
       Prescaler = (TIM1CLK / TIM1 counter clock) - 1
       Prescaler = ((SystemCoreClock) /16 MHz) - 1
 
    To get TIM1 output clock at 24 KHz, the period (ARR)) is computed as follows:
       ARR = (TIM1 counter clock / TIM1 output clock) - 1
           = 665
 
    TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR + 1)* 100 = 50%
    TIM1 Channel2 duty cycle = (TIM1_CCR2/ TIM1_ARR + 1)* 100 = 37.5%
    TIM1 Channel3 duty cycle = (TIM1_CCR3/ TIM1_ARR + 1)* 100 = 25%
    TIM1 Channel4 duty cycle = (TIM1_CCR4/ TIM1_ARR + 1)* 100 = 12.5%
 
    Note:
     SystemCoreClock variable holds HCLK frequency and is defined in system_stm32l4xx.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
  ----------------------------------------------------------------------- */
 
  /* Initialize TIMx peripheral as follows:
       + Prescaler = (SystemCoreClock / 16000000) - 1
       + Period = (666 - 1)
       + ClockDivision = 0
       + Counter direction = Up
  */
	
  Tim4_Handle.Instance = TIM4;
 
  Tim4_Handle.Init.Prescaler         = uhPrescalerValue;
  Tim4_Handle.Init.Period            = PERIOD_VALUE;
  Tim4_Handle.Init.ClockDivision     = 0;
  Tim4_Handle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  Tim4_Handle.Init.RepetitionCounter = 0;
  if (HAL_TIM_PWM_Init(&Tim4_Handle) != 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(&Tim4_Handle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
  {
    /* Configuration Error */
    Error_Handler();
  }
 
  /*##-3- Start PWM signals generation #######################################*/
  /* Start channel 1 */
  if (HAL_TIM_PWM_Start(&Tim4_Handle, TIM_CHANNEL_1) != HAL_OK)
  {
    /* PWM Generation Error */
    Error_Handler();
  }
	
  while (1)
  {
  }
 
}

3 REPLIES 3

Look for the initialization code in the MSP file with the project.

STM32Cube_FW_L4_V1.10.0\Projects\STM32L476RG-Nucleo\Examples\TIM\TIM_PWMOutput\Src\stm32l4xx_hal_msp.c

For the pin you'd need to associate the pin with a specific AF mux setting to route the TIM4 functionality there.

Code in MSP file should also enable the TIM4 clock.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ADing.11
Associate

Oh okay, I found it but it doesn't seem like it's filled it.

>For the pin you'd need to associate the pin with a specific AF mux setting to route the TIM4 functionality there.

Is that not what the GPIO_InitTypeDef does? Or do I need to change the AFR register myself?

For the MSP init, what else do I need to put in this function?

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef          GPIO_InitStruct;
  static DMA_HandleTypeDef  hdma_adc;
 
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
 
	/* ADC1 Periph clock enable */
   __HAL_RCC_ADC_CLK_ENABLE();      //NO ADC1, 2 OR 3??
   /* ADC Periph interface clock configuration */
  __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);  //???
 
 
	/* Enable DMA2 clock */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /*##-2- Configure peripheral GPIO ##########################################*/ 
 
 
	
	
 
 
 
  //##-3- Configure the DMA  
	//RM0351, table 45 & 46 on page 342 shows: ADC mapped to DMA1/channel 1  or to DMA2/channel 3.
 
 
 
  __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc);
 
  //##-4- Configure the NVIC for DMA 
 
}

>>Is that not what the GPIO_InitTypeDef does?

Well if you fill in more than two fields, and the Alternate field specifically, it might

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..