Старт ARM. Широтно-импульсная модуляция на STM32F4.

Всем привет, продолжаем дальше на практике изучать ARM. Сегодня на повестки дня широтно-импульсная модуляция.
Широтно-импульсная модуляция (ШИМ, pulse-width modulation (PWM)) — управление средним значением напряжения на нагрузке путём изменения скважности импульсов, управляющих ключом. Различают аналоговую ШИМ и цифровую ШИМ, двоичную (двухуровневую) ШИМ и троичную (трёхуровневую) ШИМ.

PWM реализуется на таймере, каждый таймер поддерживает специальный режим генерации ШИМ-сигналов. В этом режиме период ШИМ задается с помощью регистра автоматической перезагрузки таймера. Значение заполнения импульсов задается через регистр захвата/сравнения канала. Таким образом, каждый таймер может генерировать до четырех независимых ШИМ-сигналов. В каждом канале можно генерировать ШИМ-сигнал с выравниванием по фронту или по центру. В режиме с выравниванием по фронту, падающий фронт импульса всегда совпадает с моментом перезагрузки таймера. Изменение значения в регистре захвата/сравнения позволяет легко управлять моментом возникновения нарастающего фронта ШИМ-сигнала. В режиме с выравниванием по центру, таймер конфигурируется как реверсивный счетчик, который сначала считает в прямом направлении, а затем – в обратном. Когда будет выявлено совпадение счетчика с регистром захвата/сравнения канала, инвертируется состояние выходного сигнала канала.

Задача следующего рода, менять яркость свечения светодиодов. Имеем STM32F401C-DISCO, на ней 4 светодиода, порты которые идут к ним, могут работать в ШИМ режиме, мы их с Вами заюзаем, и у нас получиться небольшая светодиодная гирлянда.

Программа для PWM->LED

#include "stm32f4xx_hal.h"
#include <stdint.h>
#include <math.h>

TIM_HandleTypeDef htim4;

TIM_OC_InitTypeDef sConfigOC1;
TIM_OC_InitTypeDef sConfigOC2;
TIM_OC_InitTypeDef sConfigOC3;
TIM_OC_InitTypeDef sConfigOC4;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM4_Init(void);



int main(void)
{
	volatile int i = 0;
	volatile int j = 0;
	
	SystemClock_Config();
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  MX_GPIO_Init();
  MX_TIM4_Init(); 
	
	HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
	HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
	HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
	while (1)
  {
		for(i = 0; i <= 65353 ; i++){
			
			TIM4->CCR1 = i;
			TIM4->CCR2 = i;
			TIM4->CCR3 = i;
			TIM4->CCR4 = i;
			for(j = 0 ; j < 100; j++) __NOP();
		}
		for(i = 65535; i >= 0 ; i--){
			TIM4->CCR1 = i;
			TIM4->CCR2 = i;
			TIM4->CCR3 = i;
			TIM4->CCR4 = i;
			
			for(j = 0 ; j < 100; j++) __NOP();
		}
		
	}
}

Конфигурация ШИМ

void MX_TIM4_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig;

  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 0;
  
	htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 65535;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.RepetitionCounter = 0;
	HAL_TIM_PWM_Init(&htim4);

  sConfigOC1.OCMode = TIM_OCMODE_PWM1;
  sConfigOC1.Pulse = 0;
  sConfigOC1.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC1.OCFastMode = TIM_OCFAST_ENABLE;
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC1, TIM_CHANNEL_1);
	
	sConfigOC2.OCMode = TIM_OCMODE_PWM1;
  sConfigOC2.Pulse = 0;
  sConfigOC2.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC2.OCFastMode = TIM_OCFAST_ENABLE;
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC2, TIM_CHANNEL_2);
	
	sConfigOC3.OCMode = TIM_OCMODE_PWM1;
  sConfigOC3.Pulse = 0;
  sConfigOC3.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC3.OCFastMode = TIM_OCFAST_ENABLE;
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC3, TIM_CHANNEL_3);

  sConfigOC4.OCMode = TIM_OCMODE_PWM1;
  sConfigOC4.Pulse = 0;
  sConfigOC4.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC4.OCFastMode = TIM_OCFAST_ENABLE;
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC4, TIM_CHANNEL_4);
	
	sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
}

Проект для PWM

На сегодня все! Всем пока, если есть вопросы, пишите, всегда отвечу! 🙂

One thought on “Старт ARM. Широтно-импульсная модуляция на STM32F4.

  1. Если уже идти по пути HAL то нужно писать:
    htim4.Instance->CCR1

Comments are closed.