Сетевые технологии

Лабораторная работа №14. Работа с LED PWM контроллером

Показывать лекцию целиком

14.1 Цель и задачи

Цель работы: изучить порядок настройки и использования встроенного контроллера LED PWM. Задачи:

  • Получить навыки управления светодиодами с использованием широтно-импульсно модулированных (ШИМ) сигналов.
  • Разработать программу для управления и индикации через светодиоды платы.
  • Презентация к блоку "Микроконтроллеры RISC-V"

    14.2 Краткие теоретические сведения

    Контроллер LED PWM - это периферийное устройство, предназначенное для генерации ШИМ сигналов для управления светодиодами, однако выходные ШИМ сигналы контроллера могут использоваться и для других целей.

    Контроллер LED PWM включает в себя четыре независимых таймера (Time0 - Timer3) с поддержкой деления на доли, мультиплексор и шесть независимых ШИМ-генераторов (PWM0 - PWM5) с разрешением 14 бит (рис. 14.1).

    (рис 14.1) Архитектура LED PWM контроллера

    Контроллер может реализовывать затухание рабочего цикла (т.е. постепенное увеличение/уменьшение рабочего цикла ШИМ без вмешательства процессора) с генерацией прерывания по завершении затухания, позволяет регулировать фазу выходного ШИМ-сигнала, допускает перевод вывода ШИМ-сигнала в режим пониженного энергопотребления.

    На рисунке 14.2 показаны настраиваемые элементы контроллера.

    Каждый таймер в контроллере LED PWM реализует счет времени на основе тактового сигнала ref_pulseX. Все таймеры используют один и тот же источник тактового сигнала LEDC_CLKX, который затем пропускается через делитель тактового сигнала, чтобы сформировать ref_pulseX для счетчика.

    (рис 14.2) Настройка элементов PWM контроллера

    Настройка канала для генерации ШИМ-сигнала проводится в три последовательных этапа:

  • Инициализация таймера;
  • Инициализация канала (подключение к нему таймера и GPIO);
  • Задание значения на выходе GPIO.
  • Для выполнения этих действий можно использовать следующие API функции и структуры.

    Для настройки таймера в функцию ledc_timer_config нужно передать заполненную структуру ledc_timer_config_t, которая состоит из следующих элементов:

    struct ledc_timer_config_t {
    ledc_timer_bit_t duty_resolution,
    uint32_t freq_hz,
    ledc_mode_t speed_mode,
    ledc_timer_t timer_num,
    ledc_clk_cfg_t clk_cfg
    }
    
  • timer_num - номер таймера, число от 0 до 3.
  • clk_cfg. Для автоматического выбора параметра можно установить его в значение LEDC_AUTO_CLK.
  • speed_mode. Для ESP32-C3 этот параметр может быть установлен только в значение LEDC_LOW_SPEED_MODE.
  • duty_resolution - разрешение канала, количество бит. Например, при значении duty_resolution 10, можно устанавливать интенсивность сигнала (duty) в значения от 0 до (2**10-1).
  • freq_hz - частота таймера. Значения частоты таймера и разрешения канала (duty_resolution) зависят друг от друга: при увеличении частоты необходимо понизить разрешение. Например, при частоте 40 мегагерц допустимое разрешение составляет только 1 бит, а при 5 килогерц - 13 бит.
  • Далее нужно настроить канал.

    ledc_channel_config_t {
    ledc_channel_t channel,
    uint32_t duty,
    int gpio_num,
    ledc_mode_t speed_mode,
    int hpoint,
    ledc_timer_t timer_sel
    }
    
  • channel - номер канала от 0 до 5.
  • duty - интенсивность сигнала, от 0 до (2**duty_resolution-1).
  • gpio_num - номер пина.
  • timer_sel - номер выбранного таймера, аналогичный номеру timer_num в структуре ledc_timer_config_t.
  • speed_mode - режим, аналогичный выбранному в структуре ledc_timer_config_t.
  • Чтобы эти изменения установились, как и в случае с таймером структура передается в специальную функцию ledc_timer_config. Сразу после этого на выбранном пине начинает генерироваться заданный сигнал.

    Для изменения параметра duty последовательно используются функции ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty) и ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel) .

    14.3 Задание к лабораторной работе

    Подготовить программу, обеспечивающую управление светодиодами с использованием LED PWM контроллера, в соответствии с заданным вариантом. С использованием беспаечной макетной платы собрать схему, подключив светодиоды к настроенным на связь с выходами LED PWM внешним контактам.

  • Реализовать плавное уменьшение яркости светодиода до полного его выключения в течение 10 секунд после запуска программы.
  • Реализовать плавное увеличение яркости светодиода до его максимальной яркости в течение 10 секунд после запуска программы.
  • Реализовать циклическое плавное уменьшение с последующим увеличением яркости. Длительность цикла - 10 секунд.
  • 14.3.1 Описание последовательности выполнения работы

    Для выполнения работы необходимо иметь беспаечную макетную плату для многократного макетирования; одножильные провода-перемычки с контактами, допускающими коммутацию с установленными на макетной плате элементами; светодиоды.

  • Открыть шаблон проекта командой Open Folder. В качестве шаблона для первого проекта можно использовать проект Sample_project, находящийся в каталоге esp\ esp-idf\examples\get-started\
  • Подготовить текст основной программы в соответствии с заданием, используя шаблон, реализующий формирование ШИМ сигнала с использованием контроллера и приведенный в п. 14.3.2.
  • 14.3.2 Пример выполнения задания на защиту

    #include <stdio.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "driver/ledc.h"
    #include "esp_err.h"
    //Для подключения таймера
    #define LEDC_LS_TIMER        LEDC_TIMER_1
    #define LEDC_LS_MODE         LEDC_LOW_SPEED_MODE
    //Для подключения первого светодиода
    #define LEDC_LS_CH0_GPIO     (8)
    #define LEDC_LS_CH0_CHANNEL  LEDC_CHANNEL_0
    //Для подключения второго светодиода
    #define LEDC_LS_CH1_GPIO     (5)
    #define LEDC_LS_CH1_CHANNEL  LEDC_CHANNEL_3
    #define LEDC_TEST_CH_NUM     (2) //число светодиодов
    #define LEDC_TEST_DUTY       (8191)//максимальная интенсивность
    void app_main(void)
    {
        int ch;
    /*Конфигурация таймера*/
        ledc_timer_config_t ledc_timer = {
            .duty_resolution = LEDC_TIMER_13_BIT, 
            .freq_hz = 5000,                      
            .speed_mode = LEDC_LS_MODE,           
            .timer_num = LEDC_LS_TIMER,           
            .clk_cfg = LEDC_AUTO_CLK,              
        };
        
        ledc_timer_config(ledc_timer);
    /*Конфигурация двух ШИМ-каналов*/
        ledc_channel_config_t ledc_channel[LEDC_TEST_CH_NUM] = {
            {
                .channel    = LEDC_LS_CH0_CHANNEL,
                .duty       = 0,
                .gpio_num   = LEDC_LS_CH0_GPIO,
                .speed_mode = LEDC_LS_MODE,
                .hpoint     = 0,
                .timer_sel  = LEDC_LS_TIMER,
                .flags.output_invert = 0
            },
            {
                .channel    = LEDC_LS_CH1_CHANNEL,
                .duty       = 0,
                .gpio_num   = LEDC_LS_CH1_GPIO,
                .speed_mode = LEDC_LS_MODE,
                .hpoint     = 0,
                .timer_sel  = LEDC_LS_TIMER,
                .flags.output_invert = 1 /*1 - сигнал на выходе инвертируется*/
            },
        };
        for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
            ledc_channel_config(ledc_channel[ch]);
        }
        while (1) {
    /*Установка и обновление интенсивности для каждого канала*/
            printf(" LEDC set duty from %d to 0 without autofade\n", LEDC_TEST_DUTY);
            for(int i = 0; i<LEDC_TEST_DUTY; i+= 40){
                for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
                  ledc_set_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, LEDC_TEST_DUTY-i);
                  ledc_update_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel);
                
                }
                vTaskDelay(10 / portTICK_PERIOD_MS);
            }
    vTaskDelay(100 / portTICK_PERIOD_MS);
    }
    }
    

    14.4 Вопросы для контроля

  • Поясните правила управления яркостью светодиода с использованием ШИМ сигнала.
  • Какие действия необходимо выполнить для настройки LED PWM контроллера?
  • Как осуществляется настройка таймера? Какую функцию выполняет предварительный делитель?
  • Вернуться к учебному плану