Главная » Микроконтроллеры
Призовой фонд
на июль 2017 г.
1. Осциллограф DSO138
Паяльник
2. Регулируемый паяльник 60 Вт
Паяльник
3. 200 руб.
От пользователей

Зажигаем на TLC5940

В данной статье будет детально описана работа с ШИМ контроллером на основе TLC5940 под управлением микроконтроллера, например, STM32F100. Рассмотрим детально строение контроллера и принципы работы с ним (аппаратный и программный аспект). Сам когда-то зубы съел на его запуске TLC`шки, думаю данная статья поможет легко и быстро запустить устройство на TLC5940.

Содержание

  1. Обзор TLC5940.
  2. Принцип работы.
  3. Подключение.
  4. Запуск.

1. Обзор TLC5940.

Кратко по характеристикам TLC5940:

  • Напряжение питания: 3-5,5 В.
  • 16 ШИМ каналов с ограничением по току и глубиной в 12 бит или 4096 уровней.
  • Каждый канал имеет свой 6-битный ограничитель по току (64 уровня регулировки тока канала).
  • Ток 60-120 мА на канал для напряжения питания <3,6 В и 5,5 В соответственно.
  • Последовательный интерфейс обмена с микроконтроллером (до 30МГц)
  • Различает уровни CMOS.
  • Так же микросхема умеет определять отсутствие нагрузки (например, отключенный светодиод) и сообщать о своем перегреве.
  • Стоимость около 1$ на AliExpress

Рассмотрим распиновку на примере TLC5940NT. И пройдемся по выводах микросхемы.

Название вывода

Назначение вывода

OUT0-OUT15

выводы ШИМ-сигнала

VCC и GND

питание микросхемы

SIN

Вход даных

SCLK

Тактовый сигнал данных

SOUT

Выход данных

XLAT

Сигнал защелкивания данных из сдвиговых регистров

BLANK

Обнуление счетчика ШИМ и выключение каналов OUT0-OUT15

GSCLK

Тактовый сигнал ШИМ

IREF

Ограничение по току для всех каналов

XERR

Выход для сигналов ошибок

VPRG

Задает режим работы (0 – режим ШИМ

 1 – режим коррекции тока каналов)

DCPRG

Задает режим работы с данными коррекции тока каналов

(0 – EEPROM

 1 – DC Register)

Теперь глянем на внутренности микросхемы:

Как видно из рисунка, у нас на борту есть блок контроля за выходным током, вход для счетчика ШИМа, блок слежения за ошибками. Теперь самое вкусное: данные последовательно пропихиваются в сдвиговый регистр Input Shift Register. В зависимости от предназначения этих данных (значения ШИМ (GrayScale) или коррекция тока каналов (Dot Correction)) они по приходу сигнала XLAT и состояния VPRG записываются в регистры ШИМ (GS Register) или коррекции тока каналов (DC Register). Далее ШИМ-контроллер заземляет  или отключает от земли свой вывод OUTn.

Если честно, TLC5940 не такая уж и умная – всего-то умеет считать от 0 до 4095 и следить за выводами ШИМ.

2. Принцип работы

Для простоты понимания принципа работы микросхемы рассмотрим живой пример.

Задача: засветить 12-битным ШИМом 16 светодиодов.

16 каналов по 12 бит дадут нам 192 бит данных, которые как уже говорилось, нужно передать последовательно по линии SIN. Самое простое, что напрашивается для реализации этой задачи – SPI. Поехали!

Заранее оговоримся: если работаем только с ШИМом – выставляем на управляющих выводах следующие значения:
VPRG    лог. 0
BLANK   лог. 1
XLAT   лог. 0

Вместе с нарастанием тактового сигнала на SCLK бит за битом данные поступают в сдвиговый регистр (192 штуки). Пропускная способность канала ограничена в 30Мбит (максимальная частота тактовых импульсов на SCLK – 30 МГц). Данные должны поступать старшим битом 15-го канала (MSB) вперед. Передача начинается с данных 15-го ШИМ-канала и заканчивается данными 0-го канала. Формат пакета имеет следующий вид:

Тут все просто. После этого направляем данные в свои каналы (защелкиваем их импульсом на XLAT). Стоит отметить, что данные сразу защелкиваются в регистры ШИМа (и перезаписывают значения там лежащие), поэтому защелкивание данных нужно проводить ПОСЛЕ окончания цикла ШИМ.

Теперь о том, как получить на выходе OUTn сигнал ШИМа. Все данные загружены в регистры ШИМ. Нужно разрешить работу вывода установкой
BLANK   лог. 0

и запустить 4096 импульсов на вход GSCLK. Микросхема начнет считать эти импульсы и сравнивать значения своих счетчиков со значениями в регистрах ШИМ-канала. Пока она это делает, можно отправить следующую порцию данных (следующие 192 бита). Далее текущий цикл ШИМа завершается. Отключаем выводы ШИМа установкой
BLANK   лог. 1

Защелкиваем новые данные в регистры ШИМ-каналов импульсом на XLAT. Включаем каналы (BLANK  лог. 1) и запускаем 4096 импульсов на GSCLK. То есть цикл повторяется.

Ниже приведена временная диаграмма отправки трех пакетов.

Как видно из диаграммы, начиная со второго пакета разработчики рекомендуют перед отправкой пакета вставлять дополнительный импульс тактового сигнала SCLK (193). Хотя даже без него все работает отлично.

Несколько слов про тонкую настройку максимального тока каждого вывода OUTn. TLC5940 позволяет ограничить максимальный выходной ток ШИМ-каналов с помощью резистора, который тянет вывод IREF к земле. Но, когда мы работаем с RGB светодиодами для разных цветов номинальный ток не одинаковый. Если мы будем ограничивать ток диодов одним значением, передача цвета исказится. Для устранения проблемы можно использовать 64-ступенчастую коррекцию тока канала (Dot Correction) – на каждый канал приходится по 6 бит (96 бит на все каналы). Предел коррекции тока – от 0% до 100%.

В режим коррекции тока канала можно войти подняв вывод VPRG к напряжению питания (лог. 1). Отправка данных имеет тот же вид: начинаем отправку со старшего бита 15-го канала и заканчиваем младшим битом 0-го канала запись осуществляется по нарастанию тактового импульса SCLK. Когда все 96 бит прошли, защелкиваем их в регистры DC Register импульсом на XLAT. Опускаем VPRG в лог. 0. Формат пакета коррекции тока имеет следующий вид:

Временная диаграмма приведена на рисунке ниже.

В этом режиме можно не переживать за состояние BLANK т.к. данные записываются в регистры коррекции каналов. Так же можно записывать данные коррекции тока в память EEPROM, но про это как-нибуть в другой раз. Переходим к схемам подключения.

Стоит еще упомянуть про возможность каскадного подключения микросхем. Различие в передаче данных – только в их количестве (например, для двух микросхем нужно будет отправить не 192 бита, а 384 и в конце передачи защелкнуть их в регистры ШИМ).

3. Схемы подключения

Данная микросхема требует минимальной обвязки, поэтому схема до безобразия проста:

а каскадное включение трех микросхем выглядит так:

Схема в Eagle прилагается.

4. Запуск

Принцип работы схема подключения к микроконтроллеру нам понятны. Пришло время зажечь что-то на TLC5940. Для понимания накатаем алгоритм, а потом и программу.

Программа, для простоты и практичности, работает с 8-битной кодировкой цвета, поэтому ее нужно перекодировать в 12-битный формат и упаковать в 16-битные слова (SPI отправляет по 16 бит за раз), а уже потом отправлять по SPI. Получается что то типа  RRRG,GGBB,BRRR…

В основном цикле программы мы проверяем не готовы ли новые данные для отправки (если да – конвертируем в 12-битный формат) и можно ли отправлять новый пакет данных (отправляем).

А теперь – подпрограмма прерывания таймера:

Период ШИМа отслеживается таймером, который считает 4096 импульса и в прерывании отключает ШИМ-выводы, защелкивает пришедшие данные в регистры ШИМ и, включая снова выводы, запускает новый период ШИМа с обновленными значениями яркости. Главное – успеть отправить данные за период ШИМа (если не успеть, нужно увеличивать скорость передачи или период ШИМа)

Если на GSCLK подать 12МГц получим около 3кГц ШИМ. Таймер работает на той же частоте и отсчитывает нужные 4096 импульсов. Импульсы на GSCLK присутствуют постоянно, т.к. счетчик ШИМ сбрасывается при импульсе BLANK после срабатывания таймера. SPI работает тоже на 12МГц.

Процедура перевода из 8-битной в 12-битную систему замороченная (в свое время ничего лучшего не придумал), но сводится к сдвигу на 4 знака влево (0xFF превращается в 0x0FF0). Потом эти числа упаковываются сдвигами и суммированием в 16-бытные слова, из которых состоит конечный пакет для отправки в TLC5940.

Теперь основные моменты программы.

Основной цикл:

while(1){

//если готовы новые данные -конвертируем 8bit to 12bit-in-16bit

   if(newData==1){ 

convertData(DataIn); //convert array

newData = 0;

}

//отправка в TLC если разрешает таймер (начался цикл ШИМ)

//вначале делаем 193-й импульс


   if(nextData==1){

   if(fstCycleFlag ==1){

SPI1->CR1    &=   ~SPI_CR1_SPE;   //disable SPI
   GPIOA->CRL    &=   ~GPIO_CRL_CNF5;
   GPIOA->BSRR =    GPIO_BSRR_BS5;   //"SCLK" HI
   GPIOA->BSRR =    GPIO_BSRR_BR5;   //"SCLK" LO
GPIOA->CRL    |= GPIO_CRL_CNF5_1;   
   SPI1->CR1    |=    SPI_CR1_SPE;   //enable SPI

}


   //теперь отправляем

   while (!(SPI1->SR & SPI_SR_TXE));

for(i=0;i< GSdata_N;i++){

   SPI1->DR = GSdataOut[i];

while (!(SPI1->SR & SPI_SR_TXE));

   }

fstCycleFlag = 1;

//теперь можно защелкивать (puls of XLAT when BLANK pulse is present)

latchData = 1;

nextData = 0; //чтоб не возвращаться больше сюда

   }

}

Прерывание таймера после 4096 импульсов GSCLK.

void TIM3_IRQHandler(void){

if (TIM3->SR & TIM_SR_UIF){

TIM3->SR &= ~TIM_SR_UIF;
BLANK_1; //BLANK HI

//если можно защелкивать, то делай

   if(latchData){

XLAT_1;   //XLAT HI
XLAT_0;   //XLAT LO
latchData = 0;

}

//теперь опускаем BLANK, тем самым запускаем новый цикл ШИМ с новыми данными

BLANK_0; //BLANK LO

//разрешаем отправку новых данных, пока ШИМ работает

   nextData=1;

}

Конвертация данных замудрёная (можно конечно и через таблицу да еще и с гамма-коррекцией), но работает как надо.

void convertData(u8 *Din){

u16 j = 0;
u16 s = 1;
u16 k = 0;
u16 tmp1=0, tmp2=0;

   for(j=0;j

   tmp1 =  Din[s];
   tmp1 <<= 4+(k*4);
   tmp2 =   Din[s+1];
   tmp2 >>= 8-(k*4);

   GSdataOut[j] = tmp1+tmp2;


   s++; k++;

   if(k==3){

   k=0;
   s++;

   }
   }
}

Исходник программы в файле под статьей.

Прикрепленные файлы:

Теги:

Опубликована: 0 0
Я собрал 0 1
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 1 чел.

Комментарии (13) | Я собрал (0) | Подписаться

0
Andrey #
Доброго времени суток. А в какой среде написан код?
SPI1->CR1 &= ~SPI_CR1_SPE; //disable
Это родные библиотеки?
Ответить
0

[Автор]
kharakternyk #
coocox CMSIS родные
Отредактирован 31.08.2015 21:22
Ответить
0
skylol #
Спасибо за подробное описание.
Ответить
0

[Автор]
kharakternyk #
И вам благодарю... продолжение следует
Ответить
0
Tavrel_max #
Подскажите по этой микросхеме, а то уже 2-ой день не могу толком ее завести.
atmega8+ tcl5940+codevisionavr.
1) Во-первых: почему-то не меняется яркость светодиодов, посылаю по SPI 24 байта (192 бита), и не зависимо что посылаю (0х11 или 0хFF) яркость одна и та же, разве что если посылаю 0х00 то светодиоды не светят.
2) Зачем вообще нужен цикл ШИМ, т.е. зачем посылать эти 4096 импульса? что после них должно/не должно происходить?
Заранее спасибо.
Прикрепленный файл: led.c
Ответить
0

[Автор]
kharakternyk #
1)Во-первых там значения яркости должны быть 12-битными числами 100% = 0xFFF, 50% = 0x7FF - вот у вас в яркость каналов всякая ерунда записывается (кроме случая с ff и 00)
2) На пальцах: ШИМ это когда есть таймер, который тикает допустим 4096 импульсов и есть компаратор, который сравнивает сколько натикало и сколько надо, т.е. какое значение скважности-яркости (допустим 50% т.е. надо держать выход канала открытым, пока не протикает 2048 импульсов). Так-вот tlc тикать 4096 раз не умеет (умеет только считать до 4096) за него это делаем мы… мы и перезагружаем счетчик (когда насчитает 4096). Смысл вот в чем:
1) отправили значение яркости,
2) запустили импульсы (4096 штук) и счетчик TLC,
3) подождали пока все 4096 пойдут,
4) сбросили счетчик TLC и снова запустили импульсы (4096 штук) - и так по кругу
Ответить
0
Tavrel_max #
Спасибо, с вашей помощью понял свою ошибку: я эти 4096 импульсов подавал слишком медленно, цикл ШИМ у меня получался например 4 секунды, яркость подавал среднюю, вот у меня светодиоды и горели 2 секунды, а на следующие 2 секунды выключались... ну и этот цикл ШИМ делал только один раз. Не такая уже и веселая микруха, как ожидал, с этими импульсами надо много ей времени уделять. Думал данные по яркости передал, а она все остальное сама делает
Ответить
0

[Автор]
kharakternyk #
Можно 4096 кидать до 30 МГц, лишь бы успевать готовить и отправлять новые даные
Ответить
0
Илья #
Travel_max - можете пожалуйста дать пример кода на СИ, а то пока не очень все понимаю (что куда и в каком порядке...)
Ответить
0
med #
Хочу на каждый выход посадить отдельную светодиодную ленту длиной в 80 см. (12 штук)
А затем заставить каждую из них загораться если подаст сигнал имеющийся УЗ датчик.
Залил пример скетча-- ленты длиной в 10 см. светятся в чуть чуть накала даже не смотря на то что минусы все я посадил на выходы платы а плюс подаю от отдельного БП (есстесно если напрямую этот бп подсоединить к какой нибудь из лент то она светится офигенно ярко)
Ответить
0
Евгений #
TLC 5940 120мА на канал. А у вас посчитайте сколько
Ответить
0
Никита #
Здравствуйте! Спасибо за описание, пытаюсь это переписать для Atmega8 в AtmelStudio7.
Наткнулся на не очевидный момент - для переменной newData есть условие на равенство 1 и присвоение ей 0 в случае успеха, но! она нигде не объявляется и нигде ей не присваивается 1.
Ответить
0
Nikolaj #
Это сигнал что получен новый пакет данных. Он виставляется в 1 при срабатывании прерывания от, например, усарта или через что у вас идет загрузка картинки …а точнее - после получения всего пакета. А потом мы в основном цикле сбрасываем его и обрабатываем эти данные
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Мини гравер 125 Ватт Raspberry Pi 2
вверх