NeoPixel LED и PIC18

Views: 1651


Play

 

Еще раз об управлении светодиодами на драйвере WS2812 и ему подобных. Как известно эти светики управляются по однопроводной шине. Основная особенность, что программно можно описать передачу данных, но это будет поглощать значительную часть времени работы микроконтроллера, но в новых микроконтроллерах появилась возможность организовать этот интерфейс с применением периферии.

И так с самого начала как выглядит протокол передачи данных по шине, например, для 4 светодиодов соединенных последовательно?

Каждый светодиод представляет собой внутри сдвиговый регистр, в который необходимо загрузить 24 бита данных (8 бит на каждый свет) для формирования яркости его свечения. Для управления 4 светодиодами нам необходимо сформировать последовательность из 96 бит или из 12 байт. Эту последовательность необходимо подать на вход первого светодиода. Рассмотрим как будет выглядеть передача данных по шине:

Т.е. если нам необходимо управлять 4 светодиодами. то нам необходимо сформировать буфер данных и передать их через порт, предварительно сформировав в начале длительность низкого уровня не короче 50 мкСек. Этот длительность очень зависит от количество светодиодов на шине и при значительном количестве его надо увеличивать. Почему? Каждая микросхема светодиода имеет небольшую задержку в передачи сигнала и сформированный на входи импульс синхронизации обязан пройти через все светики, чтобы все они переключились в исходное состояние по приёму данных. Эту задержку надо учитывать чтобы перед последним светодиодом импульс синхронизации был не менее 50 мкСек. Т.е. реально чтобы выбрать между скоростью передачи и надёжностью, надо искать компромисс. В длинных цепочках этот импульс может достигать миллисекунд.

Что собой представляет структура данных, как формируется бит передачи логической единицы и нуля. Из описания на эти драйверы мы видим для формирования передачи логического нуля надо сформировать:

С технической документации нам рекомендуют, чтобы длительность передачи tH + tL = 1.25μs±600ns.

Параметр Описание Длительность
Допуск
tH0 Длительность высокого уровня при передачи 0 0.4us ±150ns
tL0 Длительность низкого уровня при передачи 0 0.8us ±150ns
tH1 Длительность высокого уровня при передачи 1 0.85us ±150ns
tL1 Длительность низкого уровня при передачи 1 0.45us ±150ns
bus sync pulse Длительность импульса синхронизации более 50μs

Я уже описывал как программно формировать протокол передачи для WS2812, но в новых микроконтроллерах с использование аппаратных средств это можно сделать намного эффективней. Основные преимущества нам даст наличие модуля CLC. Разберем последовательно как с применением аппаратных модулей можно сформировать передачу данных. Для тестирования я использовал PIC18F25K42, т.е для повторения подойдут все МК 18 серии которые заканчиваются на 42. Для передачи данных нам необходимо использовать SPI модуль микроконтроллера. Как выглядят данные при передачи например, двух байт 0x55 и 0xAA.

Данные на выходе SPI реально не подходят для передачи данных для WS2812, но сформировать корректные длительности нам поможет CLC модуль. Нам необходимо взять данные на выходе SPI модуля и в зависимости от уровня формировать 0 или 1 для формирования данных. Нам необходимо две длительности импульса высокого уровня 0.8us и 0.45us. Для большой длительности можно использовать длительность импульса из синхронизации его длительность 0,625us (для скорости передачи данных 800 кГц) это близко к минимальной длительности по техническому описанию. А для формирования малой длительности импульса будем использовать PWM модуль настроив его на формирования импульса требуемой длительности.

Как это будут выглядеть при создании проекта, новый проект:

 Выбираем стандартный проект:

Выберем микроконтроллер:

Выберем инструмент для программирования:

Выберем версию компилятора:

Зададим имя и каталог для хранения проекта, а также не забудем о кодировке:

Нажмем финиш и начальная подготовка проекта закончена. Пока у нас просто пустой каталог. Запустим MCC:

Конфигуратор попросит указать имя конфигурации и место его хранения, если у вас предполагает единственная конфигурация (например, только для одного типа контроллера) все можно оставить как есть и нажать ok!

После этого нам отрется окно конфигуратора, настройку начнем с тактового генератора.

Установим работу от внутреннего генератора (1), выберем скорость 64 МГц (хотя тут можно выбрать частоту в зависимости от вашего необходимого энергопотребления, но я люблю по быстрее), делитель установим на 1. Включим сторожевой таймер на постоянно. Зачем нам сторожевой таймер в демопроекте? Да можно без сторожевого таймера, но в реальном проекте без него никак не обойтись, по этому учимся и его использовать и включаем. Нам сразу предлагается период 2 секунды, что это значит? Это значит, что программа в при своей нормальной работе, должна как минимум не позднее чем через две секунды сбрасывать сторожевой таймер. Если эта процедура не будут выполнена, то считается, что контроллер  “завис” и сторожевой таймер апаратно перезапустит систему.

Дополнительно обратите внимание на выводы микроконтроллера это даст в последующем возможность оценить графические возможности MCC.

Следующий этап нам надо задать тактовую частоту для SPI, PWM модулей, для этого будут использовать таймер Т2. В окне ресурсы проекта выберем таймер 2.

Первое, что сделаем этот выберем от какого источника синхронизировать таймер, выберем FOSC/4 – это необходимо, чтобы можно было от него управлять модулем PWM. Какой период таймера? По тех описанию тактовая частота передачи данных для WS2812 должна быть 800 кГц. Длительность периода составляет 0.00000125 секунды. Но это период для WS2812, для таймера необходимо работать в два раза быстрее, чтобы сформировать период 800 кГц. это 0.000 000 625 или 625 нСек. Настроим таймер:

Обновление от 03/2021
Таймер настроили. следующее подключим SPI модуль.

Настроим модуль указав, что он работает в режиме главного (ведущего, мастера) и тактируется от таймера 2, проверим, правильная частота получилась 800 кГц….

Обновление 03/2021

Настроим еще два параметра для SPI. Нам необходимо настроить, следующим образом:

Обновлено 03/2021

BMODE:  выбора режима длины. если 1 = настройка SPIxTWIDTH применяется к каждому байту: общее количество отправленных битов равно SPIxTWIDTH * SPIxTCNT, конец пакета происходит, когда SPIxTCNT = 0.

RXR: – 0 = полученные данные не сохраняются в FIFO.

Посмотрим распиновку:

Настраивать периферию в MCC песня!!!

Ok!!! Следующее настроим PWM модуль.

В настройке ничего в принципе делать не надо, у нас период ШИМ 625 нСек, 50% 312 нСек, это в допуске для импульса формирования 0.

Теперь мы имеем модуль для передачи данных SPI  с которого можно взять управление и импульсы длительностью для формирования логической “1”, модуль PWM  с которого можно взять импульс для формирования логического “0”, надо их чем то объединить, для этого и используем модуль CLC!!!

Добавим модуль. Выберем CLC3, почему 3!? В принципе можно выбрать любой модуль, разница заключается только в том, что выходы модуля могут быть сконфигурируемы, только для определённого порта, например CLC1 на порт A, CLC3 на порт B, а мне надо на порт RB1, я хочу подключить (ну уже припаял соединитель, ну кому легко).

для нас откроется окно

Что с этим делать? Мы имеет три источника данных выход PWM, выход синхронизации и выход данных SPI. Подключим их!

Дальше пойдём логическим путём, нам нужен переключатель, между SCK и PWM для выбора данных которые находятся на SDO. Т.е. данные SDO должны управлять? Для этого мы будем использовать И и ИЛИ элементы. Выход PWM подключим инверсно на элемент ИЛИ 1 и естественно про инвертируем выход, чтобы не потерять логику сигнала. Выход SCK модуля SPI подключим на прямую на вход модуля ИЛИ 3. Теперь сделаем переключатель, чтобы при нуле на SDO выбирались сигнал с PWM, а при логической “1” на шине SDO с SCK. Еще необходимо учесть, что формирование логического нуля было возможно только в одном полупериоде SLK для этого надо сделать сборку по ИЛИ на модуле 1 сигналов PWM и SLK. Реально нам надо выполнить следующую логическую функцию

(SCK & nSDO & PWM) || ( SCK & SDO)

Мышкой кликаем на точках подключения и настраиваем модуль, выглядеть должно быть так:

Для наглядности нарисую стрелками где у нас формируются логический нуль и логическая единица для передачи данных.

Обновлено 03/2021

От состояния SDO логика переключается на формирование логического нуля или единице, с элемента 1 формируется логический ноль, а с элемента 4 логическая единица.

Теперь настроим выход модуля CLC для подключения ко входу светодиодов.

Запустим конфигуратор на выполнение:

После выполнения в проект будут добавлены файлы:

Откроем файл main и добавим следующий код для тестирования интерфейса, не забудем, что мы включили сторожевой таймер!

void main(void)
{
    // Initialize the device
    SYSTEM_Initialize();

    // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
    // Use the following macros to:

    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();
    
    CLRWDT();   //сброс сторожевого таймера +++++++++++++++++++++- 

    while (1)
    {
        // Add your application code
        
        CLRWDT();   //сброс сторожевого таймера +++++++++++++++++++++- 
        
        SPI1TXB = 0x55;                 // загрузка буфера кодом
        while(!SPI1STATUSbits.TXBE);    // ожидать передачи данных
        SPI1TXB = 0xAA;                 // загрузка буфера кодом
        while(!SPI1STATUSbits.TXBE);    // ожидать передачи данных
        __delay_us(10);                 // сделать паузу
        
        
    }
}

Суть этого примера простая сбрасывать сторожевой таймер говоря микроконтроллеру, что программа выполняется правильно, загружать в буфер SPI данные и проверить, что мы имеем на выходе CLC3 модуля….

Я использую анализатор для просмотра сигналов (при этом предварительно вывел и PWM и SDO на порты микроконтроллера.

Мы видим как работает SPI, как на выходе его формируются наши передаваемые данные, в третей строке видим наш сигнал PWM, а на четвертой данные формируемые для управление светодиодами.

А теперь по подробнее:

Как формируется логический ноль:

 

как формируется логическая единица:

Все длительности в допуске, правда хочу сказать из практики, светики будут работать и при еще большем разбросе.

Для управления, например, 4 светодиодами напишем небольшою функцию.

/*
 * где входные данные величина яркости для
 * red -
 * green -
 * blue -
 */

void transfer_WS2812(uint8_t red, uint8_t green, uint8_t blue)
{
    SPI1TXB = green;
    while(!SPI1STATUSbits.TXBE);
    SPI1TXB = red;
    while(!SPI1STATUSbits.TXBE);
    SPI1TXB = blue;
    while(!SPI1STATUSbits.TXBE);
}

и напишем небольшую программу для передачи данных на наши 4 светика, так будут выглядеть программа в главном цикле для постоянной передачи данных в шину.

    while (1)
    {
        // Add your application code
        
        CLRWDT();   //сброс сторожевого таймера +++++++++++++++++++++- 
        

        __delay_us(100);                 // синхронизация
        transfer_WS2812(255,0,0);   // Красный
        transfer_WS2812(0,255,0);   // Зеленый
        transfer_WS2812(0,0,255);   // Синий
        transfer_WS2812(255,255,0); // Желтый
        
    }

На выходе мы увидим:

Проект и сканы данных в формате салае логик можно скачать. На этом все. В следующей статье расскажу как сделать полноценную библиотеку для работы со светодиодными лентами и как создавать световые эффекты!

Значок

Neopixel LED и PIC18 - демо проект 491.83 KB 80 downloads

Еще раз об управлении светодиодами на драйвере...
Значок

Neopixel LED и PIC18 - сканы интерфейса 1.31 MB 69 downloads

Все длительности в допуске, правда хочу сказать...

Это может быть интересно


  • NeoPixel LED and PIC24NeoPixel LED and PIC24
    Views: 612 Популярность однопроводной шины для управления светодиода типа WS2812 не ослабевает, а новые типы светодиодов в корпусах 3,5*3,5мм, 2,0*2,0мм становяться все больше привлекательными. Построение дисплеев для анимации требуют все …
  • Проект с использованием MCC часть 12-2Проект с использованием MCC часть 12-2
    Views: 1006 Настало время для изучения шины I2C. Изучать будем на примере работы с индикатором RET012864E. Что изменили со старой схемы: В прошлой теме я затупил и не добавил подтягивающие резисторы …
  • Дисплей KD035C-3A подключение и управлениеДисплей KD035C-3A подключение и управление
    Views: 691 Дисплей KD035C-3A производиться компанией SHENZHEN STARTEK ELECTRONIC TECHNOLOGY CO.,LTD Характеристики Параметр Спецификация Единицы измерения Размер дисплея 70.08(H)*52.56(V) (3.5inch) mm Тип дисплея TFT active matrix Цветовая гамма 65K/262K colors Разрешение …
  • HVLD модуль на примере PIC24FJ128GA204HVLD модуль на примере PIC24FJ128GA204
    Views: 618 HVLD модуль представляет собой простое устройство, для контроля напряжения питания микроконтроллера или внешнего напряжения (через делитель). Его задача при “выходе” напряжения за заданные пределы сформировать сообщение микроконтроллеру, что …
  • LED модуль P10C4V12LED модуль P10C4V12
    Views: 3070 LED панели на обычных регистрах типа 74HC595. Они выпускаются как монохромные так двух и полно цветные, особенность, что они предназначены для текстовой информации и имеют один уровень яркости. Общую яркость …
  • Защита датчиков температуры DS18B20 от статического электричестваЗащита датчиков температуры DS18B20 от статического электричества
    Views: 1812 Статья перепечатана с сайта http://svetomuzyka.narod.ru При удалении датчика на большие расстояния возникает опасность наведения импульсов высокого напряжения на кабель, который соединяет датчик с контролером. Если не принимать меры защиты, …
  • DS18B20 – удаленный контроль температурыDS18B20 – удаленный контроль температуры
    Views: 3021 Контроль температуры с использованием датчиков температуры DS18B20 и платы ILLISSI-4B-09-primum Проект позволяет подключать к плате ILLISSI-4B-09-primum до 16 датчиков температуры DS18B20, удаленных более 300 метров,  и выводить информацию …
  • AD9833 – Programmable Waveform Generator – part twoAD9833 – Programmable Waveform Generator – part two
    Views: 1672 Прошло время и появилась тема, что-бы закончить проект AD9833 – Programmable Waveform Generator. Приехали печатные платы. В этот раз я печатные платы заказывал в https://jlcpcb.com/ делал это в …
  • Ultrasonic Level Meters – ULM –53LUltrasonic Level Meters – ULM –53L
    Views: 707 Измерение расстояния при помощи ультра звукового датчика ULM–53L–10. Диапазон измерения от 0,5 м до 10 м, полностью пластмассовый излучатель PVDF, механическое соединение фланцем из полиэтилена HDPE (исполнение “N”) Характеристики …
  • MCC – K42 – настройка модуля DMAMCC – K42 – настройка модуля DMA
    Views: 738 MCC – в версии v.3.95.0 и начиная ядра 4.85.0 конфигуратор предоставляет графический интерфейс для настройки модуля DMA. Для начала: Посмотреть какая версия МСС можно в закладке версии, если …



 

Поделись этим!

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

Продолжайте читать

НазадДалее

Комментарии

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

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