pwmПродолжим осваивать периферию STM32. На этот раз научимся плавно включать и выключать светодиод.

Про ШИМ было сказано уже достаточно в статье «Как работает ШИМ». Поэтому здесь лишь представлена реализация и краткое описание. Стоит отметить, что у семейства STM32F407xx среди фич указано «Up to 17 timers: each up to 4 pwm…» в общем проблем с количеством таймеров и каналов ШИМ не должно быть.

Задача — плавное изменение яркости светодиода, т.е. получить регулируемое напряжение. Поэтому нам нужен таймер, который будет делать отсчеты. На основе этих отсчетов мы формируем сигнал с определенной частотой(периодом). Регулируя заполнение импульса(скважность), мы изменяем напряжение.

В качестве примера будем использовать ножку PD12, потому что на ней светодиод. При этом помним, что на любую произвольную ножку нельзя назначить ШИМ канал, только на те у которых есть в качестве альтернативной функции можно использовать таймер. У PD12 используется TIM4.
pd12

TIM4 имеет 16 битный счетчик, которой умеет считать как вверх, так и вниз. Можно использовать 16 битный предделитель. Кроме того имеется 2 режима Edge- and Center-aligned, выравнивание по центру и фронту, фишка специфичная помогает снизить помехи, для управления светодиодом разницы нет какой использовать.

В качестве прошивки — плавно зажигаем, затем плавно тушим светодиод. Для этого придется настроить ножку на альтернативный режим, включить таймер и настроить ШИМ

#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_tim.h>
 
void delay_ms(uint32_t ms)
{
volatile uint32_t nCount; //переменная для счета
RCC_ClocksTypeDef RCC_Clocks; //переменная для считывания текущей частоты
RCC_GetClocksFreq (&RCC_Clocks); //считываем текущую тактовую частоту
 
nCount=(RCC_Clocks.HCLK_Frequency/10000)*ms; //пересчитываем мс в циклы
for (; nCount!=0; nCount--); //гоняем пустые циклы
}
 
int main(void)
{
	int x = 1023;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //включить тактирование 
 
	GPIO_InitTypeDef PORT_SETUP; //структура настройки ножки
 	PORT_SETUP.GPIO_Mode = GPIO_Mode_AF; //альтернативная функция ножки
	PORT_SETUP.GPIO_OType = GPIO_OType_PP; //ножка пуш-пул
	PORT_SETUP.GPIO_Pin = GPIO_Pin_12; //12 ножка
	PORT_SETUP.GPIO_Speed = GPIO_Speed_2MHz; 
	GPIO_Init(GPIOD, &PORT_SETUP);
 
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4); //использовать таймер4 для 12 ножки
 
	TIM_TimeBaseInitTypeDef TIM_SETUP; //структура настройки таймера
	TIM_SETUP.TIM_CounterMode = TIM_CounterMode_Up;  //считаем вверх  
	TIM_SETUP.TIM_Period = 1023;     //период таймера 1023 отсчета
	TIM_SETUP.TIM_Prescaler = 0;    //предделитель откл
 	TIM_TimeBaseInit(TIM4, &TIM_SETUP);
 
	TIM_OCInitTypeDef PWM_SETUP;  //структура настройки ШИМ
	PWM_SETUP.TIM_Pulse = 254; //начальное заполнение
	PWM_SETUP.TIM_OCMode = TIM_OCMode_PWM1; //режим1 center align
	PWM_SETUP.TIM_OutputState =TIM_OutputState_Enable; //подключаем к выходу
	PWM_SETUP.TIM_OCPolarity = TIM_OCPolarity_High; //положительная полярность
	TIM_OC1Init(TIM4, &PWM_SETUP);
	TIM_Cmd(TIM4, ENABLE);
 
    while(1)
    {
    	while(x>0) //тушим светодиод
    	{
    		TIM4->CCR1=x;
    		x--;
    		delay_ms(1);
    	}
    	while(x<1023) //зажигаем светодиод
    	{
    		TIM4->CCR1=x;
    		x++;
    		delay_ms(1);
    	}
    }
}

Выглядит несколько сложнее чем на AVR, но если вдуматься то все тоже самое. Результат

Проект кокоса

3 комментария: ШИМ в STM32F4

  • Можно пример как ШИМ подключить к ножек №13, если это возможно.

  • Вопрос снят.

  • Вот что мне у вас всегда нравиться так это то, что в коде всегда все подписано! это так упрощает нам ленивцам жизнь) вместо того чтобы открывать ref_manual читать переводить, подглядел у вас в коде, тяп-ляп переписал под свои задачи и готово) спасибо огромное!

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

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

Свежие записи
Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика