SPL: программный ШИМ

     Краткое описание: ШИМ широтно импульсная модуляция процесс управления мощностью, подводимой к нагрузке, путем изменения скважности импульсов, при постоянной частоте.

     Задача:Требуется написать с использованием библиотеки StdPeriph код. Программа должна изменять яркость свечения светодиода при нажатии на пользовательскую кнопку.

#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_exti.h"
#include "stm32f30x_syscfg.h"
#include "stm32f30x_misc.h"
#include "stm32f30x_tim.h"

#define TIMER_PRESCALER 800 //Пределитель
#define TIMER_PERIOD 10 //Период

GPIO_InitTypeDef gpio; //Объявляем переменную gpio типа GPIO_InitTypeDef
TIM_TimeBaseInitTypeDef timer; //Объявляем переменную timer типа TIM_TimeBaseInitTypeDef

int PWM_PERIOD_COUNT; //Период ШИМ
int PWM_DUTY_CYCLE_COUNT; //Коэффициент заполнения ШИМ

void initAll()
{
    RCC_HSICmd(ENABLE); //Включаем тактирование от внутреннего источника
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); //Подаем тактовый сигнал на системную шину
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); //Включаем тактирование порта С
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //Включаем тактирование таймера

    gpio.GPIO_Mode = GPIO_Mode_OUT; //Выбираем режим работы пина: ВЫХОД
    gpio.GPIO_Pin = GPIO_Pin_7; //Выбираем нужный пин
    GPIO_Init(GPIOC, &gpio); //Инициализируем структуру с настройками

    gpio.GPIO_Mode = GPIO_Mode_IN; //Выбираем режим работы пинов
    gpio.GPIO_Pin = GPIO_Pin_0; //Выбираем нужны пин
    GPIO_Init(GPIOC, &gpio); //Инициализируем структуру с настройками

    timer.TIM_Prescaler = TIMER_PRESCALER; //Устанавливаем пределитель
    timer.TIM_Period = TIMER_PERIOD; //Устанавливаем период
    TIM_TimeBaseInit(TIM4, &timer); //Инициализируем структуру с настройками
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //Настраиваем таймер для генерации прерывания по обновлению (переполнению)
    TIM_Cmd(TIM4, ENABLE); //Запускаем таймер
}

int main()
{
    ok_enable_irq(); //Разрешаем прерывания
    initAll(); //Вызываем функцию инициализации периферии
    NVIC_EnableIRQ(TIM4_IRQn); //Разрешаем прерывание по таймеру

    while (1) {
    }
}

void TIM4_IRQHandler() //Функция обработчика прерываний таймера
{
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //Очищаем бит прерывания

    PWM_PERIOD_COUNT++; //Увеличиваем значение счетчика периода ШИМ на 1
    PWM_DUTY_CYCLE_COUNT++; //Увеличиваем значение счетчика коэффициента заполнения ШИМ на 1

    if (PWM_PERIOD_COUNT == 12) {
        PWM_PERIOD_COUNT = 0; //Обнуляем счетчик периода ШИМ когда он досчитает до 12 миллисекунд
        PWM_DUTY_CYCLE_COUNT = 0; //Обнуляем счетчик коэффициента заполнения
        GPIO_ResetBits(GPIOC, GPIO_Pin_7); //Выключаем диод
    }
    if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0) == 1) //Узнаем состояние входа PIN0, кнопка нажата или нет
    {
        if (PWM_DUTY_CYCLE_COUNT == 11) //Если кнопка нажата увеличиваем коэффициент заполнения ШИМ и зажигаем светодиод
        {
            GPIO_SetBits(GPIOC, GPIO_Pin_7);
        }
    }
    else {
        if (PWM_DUTY_CYCLE_COUNT == 1) //Если кнопка не нажата уменьшаем коэффициент заполнения ШИМ и зажигаем светодиод
        {
            GPIO_SetBits(GPIOC, GPIO_Pin_7);
        }
    }
}

     Скомпилируйте программу нажав кнопку Build, прошейте микроконтроллер, нажмите RESET. Зеленый светодиод должен светится в полную силу, при нажатии на кнопку светодиод начнет светится тусклее. 

     ВНИМАНИЕ: Приведенный листинг кода не является единственной и оптимальной реализацией поставленной задачи. Пример опубликован с демонстрационной целью. Также автор во избежание переписывания чужих статей, пропускает теоретические основы необходимые для понимания примера, связывая это с тем что всю необходимую информацию можно найти в интернете.

Комментариев (0)

Написать комментарий

Имя *
E-mail
Введите комментарий *
Капча
36 + ? = 44