STM32 и CubeIDE: ШИМ и светодиод

Самый наглядный способ продемонстрировать работу ШИМ — плавное изменение яркости светодиода. Начнём с настройки выводов микроконтроллера в конфигураторе CubeIDE.

Для тех, кто ещё не знаком с этим понятием есть специальный урок про ШИМ.

ШАГ 1. Настраиваем контакты программатора и отладчика.

Для этого в разделе System Core / SYS в поле Debug выбираем Serial Wire.

STM32, CubeIDE и светодиод

Этот шаг позволяет нам избежать проблем с загрузкой программы на микроконтроллер. Мы делаем его начиная с первого урока про stm32 и CubeIDE.

ШАГ 2. Выбираем режим контакта PA10

Нажимаем правую кнопку мыши на конакте PA10 и выбираем странный пункт TIM1_CH3. Выбор этого пункта означает, что мы подключаем данный контакт к каналу №3 аппаратного таймера №1.

STM32, CubeIDE и светодиод

Аппаратный таймер — это устройство, которое может генерировать и обрабатывать прямоугольные импульсы не нагружая центральный процессор. У STM32 имеется несколько таймеров с разным набором функций. Разные каналы разных таймеров могут быть подключены только к определенным контактам, что следует учитывать при проектировании принципиальной схемы устройства.

ШАГ 3. Настройка таймера

Теперь нам необходимо настроить канал №3 таймера №1 на генерацию именно ШИМ сигнала. Для этого раскроем раздел timers в левой колонке конфигуратора. В появившемся блоке настроек находим пункт Channel 3 и выбираем в нём:

PWM Generation CH3

Далее, в том же блоке настроек, но чуть ниже указываем величину предделителя (Prescaler) и счётчика (Counter period).

STM32, CubeIDE и светодиод

Для установки этих параметров будем использовать следующие рассуждения.

Мы управляем светодиодом, следовательно частота ШИМ может находиться в диапазоне от 100 до 300 Гц. Пусть будет 250Гц, что соответствует периоду T = 4мс. Чтобы градаций яркости совсем не было заметно, выберем разрешение ШИМ равным 500.

Для обеспечения таких параметров, на вход генератора ШИМ необходимо подать сигнал с частотой 250Гц*500 = 125кГц. Это нужно для того, чтобы в течение каждого периода счётчик таймера смог отсчитывать импульс нужной длины: 0,1,2,…,499 частей периода.

С другой стороны, таймер №1 в STM32F103 подключён к шине APB2, а значит он тактируется её частотой. Шина — это такой аппаратный канал передачи данных между разными устройствами внутри микроконтроллера: процессором, памятью, интерфейсами I2C, SPI и пр.

Мы ничего не меняли в проекте, поэтому изначально APB2 работает на частоте 8МГц, значит и на входе счётчика таймера будет 8МГц. А нам надо 125кГц! Что делать? Для этого нам и понадобится предделитель! Мы просто поделим частоту шины на 64 и получим, что хотим.

И самое последнее. В поле Counter period мы запишем разрешение ШИМ сигнала — 500. Этот параметр говорит счётчику таймера на сколько частей необходимо делить период сигнала.

Важный нюанс. При выставлении предделителя и периода счётчика следует вычитать единицу!

Не забываем сохранить конфигурацию. Только после сохранения CubeIDE автоматически обновит исходный код согласно внесённым в конфигураторе изменениям. Готово! Переходим к программе.

Программа

Чтобы изменить коэффициент заполнения ШИМ сигнала нам необходимо каждый раз перенастраивать таймер, но уже не в конфигураторе, а в самой программе. Для этого мы опишем новую функцию, которую назовём setPWM. Сначала объявим её в самом начале файла main.c.

/* USER CODE BEGIN PFP */
void setPWM(uint16_t pwm_value);
/* USER CODE END PFP */

А затем реализуем её в блоке USER CODE BEGIN 4.

/* USER CODE BEGIN 4 */
void setPWM(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(&htim1, &sConfigOC, TIM_CHANNEL_3); // таймер №1, канал №3
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
}
/* USER CODE END 4 */

Также необходимо запустить ШИМ на 3-м канале первого таймера. Делаем это так:

  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  /* USER CODE END 2 */

Это была подготовка. Теперь напишем программу, которая будет плавно менять яркость светодиода от 0 до 100%, а затем от 100% до нуля. Сделаем это следующим образом. Пусть изначально яркость равна 0. На каждом шаге суперцикла будем прибавлять единицу к яркости, пока не достигнем максимального значения. В момент, когда яркость достигла 500, меняем направление отсчёта и начинаем вычитать по единице, пока не достигнем 0. И так далее.

Объявим пару переменных, в которых будем хранить текущее значение коэффициента заполнения (pwm_value) и направление отсчёта (step).

/* USER CODE BEGIN PV */
uint16_t pwm_value = 0;
int8_t step = 0;
/* USER CODE END PV */

Основной код добавим в суперцикл while:

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	  if(pwm_value == 0) step = 1;
	  if(pwm_value == 500) step = -1;
	  pwm_value += step;
	  setPWM(pwm_value);
  	  HAL_Delay(5);
  }
  /* USER CODE END 3 */

Последнее, что нам нужно сделать — подключить светодиод к ножке PA10. Воспользуемся простейшей схемой с резистором на 200 Ом, такой же, как в уроке про светодиод на Ардуино.

Наконец, загружаем программу на микроконтроллер и наблюдаем плавно вспыхивающий и также плавно затухающий светодиод. Ура!

На следующем уроке будем управлять куда более серъёзной нагрузкой — двигателем постоянного тока!

+3

Изменено:

STM32 и CubeIDE: ШИМ и светодиод: 7 комментариев

  1. Очень жду! «На следующем уроке будем управлять куда более серъёзной нагрузкой — двигателем постоянного тока!»

    0
  2. Частота ЦП и периферии какая?
    Читатель по прескейлерам должен угадывать?

    0
  3. Не работает этот код. Всё в точности скопировал отсюда и ничего нет на выходе. Светодиод не загорается. Не подскажете в чём может быть проблема?

    +2
  4. int8_t step = 0;
    step = -1;
    Это косяк, int8_t не может быть отрицательным, однако этот пример работает.

    0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.