Перейти к содержимому

#28. PWM Output

В этом разделе мы рассмотрим пример использования PWM выхода. Для этого нам необходимо будет использовать таймеры. Таймеры общего назначения состоят из 16-разрядного счетчика с автоперезагрузкой, управляемого программируемым прескалером. Они могут использоваться для различных целей, включая измерение длительности импульсов входных сигналов (захват входного сигнала) или генерацию выходных сигналов (сравнение выходных сигналов и ШИМ — что нам и нужно). Длины импульсов и периоды колебаний могут быть модулированы от нескольких микросекунд до нескольких миллисекунд с использованием прескалера таймера и прескалера регулятора тактового сигнала RCC. Таймеры полностью независимы и не делятся никакими ресурсами. Они могут быть синхронизированы вместе.

Основные функции TIMx:
Функции таймера общего назначения TIMx включают в себя:
• 16-битный счетчик автоматической перезагрузки вверх, вниз, вверх / вниз.
• 16-разрядный программируемый прескалер, используемый для деления (также «на лету») тактовой частоты счетчика на любой коэффициент от 1 до 65536.
• До 4 независимых каналов

Основным блоком программируемого таймера является 16-разрядный счетчик с соответствующим регистром автоперезагрузки. Счетчик может считать вверх, вниз или одновременно вверх и вниз. Счетчик часов можно разделить на прескалер.
Счетчик, регистр автоматической перезагрузки и регистр предварительного масштабирования могут быть записаны или считаны программным обеспечением. Это верно, даже когда счетчик работает.
Единица времени включает в себя:
• Счетчик регистров (TIMx_CNT)
• Предварительный регистр (TIMx_PSC):
• Автозагрузка регистра (TIMx_ARR)

Для более глубокого и детального изучения можно открыть Reference manual раздел PWM Mode.

Мы же для примера возьмем пин PA6. Для наглядного примера можем открыть CubeMX, но выгружать оттуда ничего не будем:

PA6

Видим, что на пину PA6 сидит таймер TIM3. Теперь необходимо посмотреть на какой шине сидит наш таймер — для определения максимальной частоты работы. Смотрим все тот же Reference Manual:

Максимальная частота TIM3 не выше 36 МГц, значит и делители необходимо настраивать не выше данной частоты).

Напишем код:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h" 


void InitPWM(void)	//Функция инициализации и настройки ШИМ на порту А
	
{
		// Включаем тактирование таймера и порта A
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // Конфигурируем порт А6
    GPIO_InitTypeDef GPIO_Config;
    GPIO_Config.GPIO_Pin = GPIO_Pin_6;
    // Альтернативная функция (в нашем случае - выход таймера), Push-Pull
    GPIO_Config.GPIO_Mode = GPIO_Mode_AF_PP;
    // Частота - 50 MHz
    GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;

    // Инициализируем порт A
    GPIO_Init(GPIOA, &GPIO_Config);
    // Конфигурация таймера
    TIM_TimeBaseInitTypeDef TIM_BaseConfig;
    // Конфигурация выхода таймера
    TIM_OCInitTypeDef TIM_OCConfig;
	
		// Конфигурируем таймер
		// PWM frequency = 100 Гц		

    // Запускаем таймер на тактовой частоте в 100 Hz
    TIM_BaseConfig.TIM_Prescaler = SystemCoreClock/100000 - 1; // 0..239;
		// Период - 1000 тактов => 100000/1000 = 100 Hz	//0...36 MHz
    TIM_BaseConfig.TIM_Period = 1000 - 1; // 0..999	
    TIM_BaseConfig.TIM_ClockDivision = 0;
    // Отсчет от нуля до TIM_Period
    TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up;

    // Инициализируем таймер 3
    TIM_TimeBaseInit(TIM3, &TIM_BaseConfig);

    // Конфигурируем выход таймера, режим - PWM1
    TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1;
    // Выход включен
    TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
    // Пульс длинной 100 тактов => 100/1000 = 90%
    TIM_OCConfig.TIM_Pulse = 100 - 1;	//0...999
    // Полярность => пульс - это единица (+3.3V)
    TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High;

    // Инициализируем первый выход таймера 3
    TIM_OC1Init(TIM3, &TIM_OCConfig);

    // Включаем таймер
    TIM_Cmd(TIM3, ENABLE);

}

int main(void)
{
    InitPWM();
 
    while(1)
    {
    }
    return 0;
}

В коде показаны этапы, необходимые для настройки таймера 3 для работы с периодом 100 Гц и 1000 шагов тактового генератора. Это позволяет нам определять ширину импульса на выходе от 0 до 100% с точностью до 0,1%. Основными параметрами конфигурации являются Prescaler, период и count mode (режим подсчета (up!)). Выходной канал сконфигурирован в режиме PWM (на самом деле есть две вариации — выровненные по краям и выровненные по центру — здесь мы выбираем выровненные по краям. Импульсная ширина pw (0..999) также может быть установлена с помощью следующей команды — TIM_SetCompare2

TIM_SetCompare2(TIM2, pw); //(0..999)

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