STM32CubeMX series|PWM output

PWM output

1. Introduction to PWM

Pulse Width Modulation (PWM, Pulse Width Modulation) is abbreviated as Pulse Width Modulation. It is a very effective technology that uses the digital output of a microprocessor to control analog circuits. That is to control the pulse width, the principle of PWM is as shown below:

Insert picture description here
In the figure, we assume that the timer is working in up-counting PWM mode, and output 0 when CNT <CCRx, and output 1 when CNT >= CCRx, then the above PWM diagram can be obtained: When CNT <CCRx, IO port output Low level; when CNT >= CCRx, the IO port outputs high level; when the CNT value reaches ARR, it resets to zero, and then counts up again, and loops in turn. Changing the value of CCRx can change the duty cycle of PWM output, and changing the value of ARR can change the frequency of PWM output

There are two output modes: PWM1 and PWM2

Insert picture description here
Output polarity: active high and active low

2. Hardware design

This experiment outputs the PWM signal through channel 1 of TIM3 to control the brightness of the D7 indicator

  • D7 indicator
  • Timer TIM3

Insert picture description here
Here, since the pin corresponding to the CH1 channel of TIM3 is PA6, the LED on the development board is not connected to PA6. If you want to map this channel to the IO port connected to the LED, you need to use the GPIO multiplexing function remapping function Remap PA6 to PC6

Insert picture description here

3. Software design

3.1 STM32CubeMX settings
  • RCC set external HSE, clock set to 72MHz; TIM3 clock mounted on APB1 Time Clocks is 72MHz
  • Select TIM3, set the timer clock source to the internal clock source, set channel 1 to PWM mode (corresponding to pin PA6 automatically turned on, then you should select PC6 TIM3_CH1 to complete remapping), choose whether to turn on the timer interrupt by yourself

Insert picture description here

  • The prescaler coefficient is set to 72-1, counts up, and the auto-reload value is set to 500-1, then the timer clock frequency is 1MHz, the timer period is 1us, and the timer overflow period (ie PWM period) is 500 * 1 = 500us, overflow frequency (ie PWM frequency) is 1/500us = 2KHz

  • PWM mode select PWM1, Pulse defaults to 0, and PWM polarity is set to low level (because the LED is lit at low level)

Insert picture description here

  • Enter the project name, select the project path (no Chinese), select MDK-ARM V5; check Generated periphera initialization as a pair of'.c/.h' files per IP; click GENERATE CODE to generate the project code
3.2 MDK-ARM programming
  • You can see the initialization function of the timer in the tim.c file
void MX_TIM3_Init(void)
{
    
    
  TIM_ClockConfigTypeDef sClockSourceConfig = {
    
    0};
  TIM_MasterConfigTypeDef sMasterConfig = {
    
    0};
  TIM_OC_InitTypeDef sConfigOC = {
    
    0};

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 72-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 500-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK){
    
    
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK){
    
    
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK){
    
    
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK){
    
    
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
    
    
    Error_Handler();
  }
  __HAL_TIM_DISABLE_OCxPRELOAD(&htim3, TIM_CHANNEL_1);
  HAL_TIM_MspPostInit(&htim3);
}
  • Write code in the main function to periodically change the value of CCR1 to change the PWM duty cycle
int main(void){
    
    
  /* USER CODE BEGIN 1 */
  uint8_t dir = 1;
  uint16_t ledpwmval = 0;
  /* USER CODE END 1 */
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);		//开启定时器PWM输出
  /* USER CODE END 2 */
  while (1){
    
    
    HAL_Delay(10);
		if(dir)
			ledpwmval++;
		else
			ledpwmval--;
		
		if(ledpwmval > 300)
			dir = 0;
		if(ledpwmval == 0)
			dir = 1;
		
		TIM3->CCR1 = ledpwmval;		//更改CCR1的值来改变PWM的占空比
  }
}

4. Download verification

After the compilation is correct, download it to the development board, you can see that the D7 indicator light changes from dark to bright, and then from bright to dark, showing the effect of breathing light

Guess you like

Origin blog.csdn.net/Chuangke_Andy/article/details/108590150