STM32CubeMX Tutorial Series: PWM

From Waveshare Wiki
Revision as of 09:52, 9 October 2016 by Wiki Editorial Team (talk | contribs) (Created page with " Abstract: We have shown you the basic application and interrupt of the timer in the last chapter. Now, we are going to present how to use timer to control PWM output and cont...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Abstract: We have shown you the basic application and interrupt of the timer in the last chapter. Now, we are going to present how to use timer to control PWM output and control LED1 blinking and brightness changing. 

PWM introduction

PWM, PulseWidthModulation,is a modulation technique used to control the analog circuitsvia MCU digital outputs. It is widely applied, ranging from measurement and communicationto power control and conversion.

Stm32cubemx-tutorial-series-pwm-6.jpg

The figure above shows a PWM signal. Figure b) shows the MCU digital signal. And figure a) shows the corresponding analog signal when the digital output is connected to the power device, like motor. For example, a pulse with PWM output at a 50% duty cycle, frequency at 10Hz and high level of 3.3V, may have a 1.65V output analog signal result. PWM have two significant parameters, one is output frequency, and the other is duty cycle. Duty cycle is used to change the voltage of the output analog signal. A higher frequency will has a better analog result. And the larger duty cycle will has the higher analog voltage.

STM32cube configuration and illustration

Open a new project on STM32CubeMX, then select the chip STMF746IGT6 and High Speed Clock (HSE). Configure the PB6 of LED1 as the output channel 1 of the TIM 4. And set the channel 1 of TIM4 to PWM Generation CH1.

Stm32cubemx-tutorial-series-pwm-1.png

Stm32cubemx-tutorial-series-pwm-2.png

Pulse width modulation mode allows you to generate a signal with a frequency determined by the value of the TIMx_ARR register and a duty cycle determined by the value of the TIMx_CCRx register. In PWM mode (1 or 2), TIMx_CNT and TIMx_CCRx are always compared to determine whether TIMx_CCRx&TIMx_CNT or TIMx_CNT&TIMx_CCRx (depending on the direction of the counter). The figure below shows the PWM edge-aligned mode (up-counting configuration). CCRx is Capture/compare register, OCxREF is output compare sigal, and CCxIF is interrupt flag. ForCCRX=4, when the value in TIMx_CCRx is lower than the counter, the output is in high level, or else in low level.

Stm32cubemx-tutorial-series-pwm-3.png

The figure below shows the PWM center-aligned mode.

Stm32cubemx-tutorial-series-pwm-4.png

Set the system clock to216MHz. As we known from the last chapter, the timer mount to APB1, and the clock frequency is 108MHz. Therefore, the frequency division is set to 1080 and the divided clock frequency is 100000Hz. If the PWM period is 20ms, the counter should be set to 2000-1. And other parameters are in default settings. The parameterPulse can be used to set the pulse width in TIMx_CCRx register. Modify this parameter can change the setting of duty cycle.

Stm32cubemx-tutorial-series-pwm-5.png

Generate the report and code, compile the programs.

Add application program

In the file tim.c, we can find the timer initialization function.

/* TIM4 init function */
void MX_TIM4_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;
  
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 1080-1;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 2000-1;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim4);
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
  
  HAL_TIM_MspPostInit(&htim4);
  
}

By setting the value of the parameterPulse, you can modify the pulse width settings. Here, we add a user PWM setting function in main.c file, of which the parameter should be modified.

/* USER CODE BEGIN 4 */
void user_pwm_setvalue(uint16_t value)
{
    TIM_OC_InitTypeDef sConfigOC;
  
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = value;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);  
}
/* USER CODE END 4 */

In the main() routine, add HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1) to enable timer PWM output. The parameter pulse width will be continuously changed in the while loop, enabling the LED brightness change gradually.The parameter Pulsehas the maximum value of 2000. It begins from 0 andwill add 100 every 100 ms.When reaching 2000, the value of Pulse will decrease to 0 step by step.

/* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
/* USER CODE END 2 */
 
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
 
/* USER CODE BEGIN 3 */
  HAL_Delay(100); 
  if(pwm_value == 0) step = 100;
  if(pwm_value == 2000) step = -100;
  pwm_value += step;
  user_pwm_setvalue(pwm_value);
}
/* USER CODE END 3 */

Declare the variable pwm_value,step and the function user_pwm_setvalue()before the function main.c. Then compile the function and download it to the device. You can see the LED change its blinking gradually when pressing the WAKEUP button.