[Из песочницы] Управление яркостью подсветки 7-ми дюймового TFT LCD
Введение В настоящее время я занимаюсь проектом на Arduino с использованием TFT дисплея. Недавно мне захотелось добавить в него, казалось бы, простую функцию — функцию регулировки яркости. Нашёл в документации к библиотеке для работы с TFT дисплеем (UTFT Library) нужный метод: setBrightness (br); Написал весь код, сделал все, как надо. Решил проверить, но, к моему удивлению, ничего не происходило. Начал разбираться. Спустя два дня, заметил небольшое примечание к методу: «This function is currently only supported on CPLD-based displays.» То есть, данная библиотека, не поддерживает мой дисплей. Но я узнал, что сам дисплей регулировку яркости поддерживает. Очень долго искал в интернете способы настройки, но так и не нашёл, поэтому решил добиться своей цели сам, несмотря ни на что, и у меня это получилось. И вот решил поделиться с теми, кому это может пригодиться.
Что нам понадобится? Разберёмся с железом Открыв схему дисплея, можно увидеть, что на конвертер mp3032 идет три входа: LED-A, PWM, 5V. Изначально, PWM неактивен. Этот вход не используется совсем. Подсветка управляется LED-A. Если взглянуть на обратную сторону дисплея, можно найти область, подписанную как «Backlight control». Здесь то мы и найдём эти самые входы. Для управления подсветкой методом ШИМ, необходимо сделать так, чтобы все было наоборот: LED-A — неактивен, PWM — активен. Для этого придётся перепаять перемычку. Вот фото того, что должно получиться: Программная часть Так как наша библиотека не может дать то, что нам надо, мы сами напишем нужную функцию. Для этого откроем документацию к контроллеру, управляющему дисплеем (SSD1963). Управление SSD1963 осуществляется с помощью специальных команд, которые передаются с Arduino через специальные выходы, которые описаны в документации: Управление осуществляется следующим образом: Arduino выводит через RS (D/C в таблице) 0, если мы собираемся передавать команду, 1 — если данные. После передачи команды, RS переключается на 1, и далее передаются необходимые параметры. Все команды и параметры передаются через выходы D0-D7. Если у вас ATmega2560, то все эти восемь выходов объединены в порт C.
Итак, для начала, напишем функцию передачи данных по шине. Для удобства использования, я буду писать прямо в UTFT.h:
void Lcd_Writ_Bus (uint8_t bla) { digitalWrite (WR, LOW); //Настраиваем SSD1963 на чтение digitalWrite (CS, LOW); PORTC = bla; //Передаем на шину данные в виде одного байта digitalWrite (CS, HIGH); digitalWrite (WR, HIGH); } Также стоит обратить внимание на названия методов, так как в библиотеке уже могут встретиться функции с такими же именами.Добавим две функции для вывода команд и данных:
void Lcd_Write_Com (uint8_t data) { digitalWrite (RS, LOW); //Переключаем RS в режим чтения команды, то есть 0 Lcd_Writ_Bus (data); }
void Lcd_Write_Data (uint8_t data) { digitalWrite (38, HIGH); //Переключаем RS в режим чтения данных, то есть 1 Lcd_Writ_Bus (data); } Теперь сама настройка подсветки. Чтобы узнать, как осуществить все это, открываем документацию и ищем команду для настройки PWM.
Примечание: PWM может управляться, с помощью DBC — система динамической регулировки яркости, но я, для простоты, не стал её использовать. Вы же, если хотите, можете найти необходимую информацию в той же документации.Итак, вот, что нам надо:
То есть, сначала мы должны передать команду »0xBE», а потом, в качестве 3-х параметров передать частоту сигнала, длительность рабочего цикла, а также третий параметр, который определяет, включен DBC или нет (0×01 — выключен, 0×09 — включен).
Для регулировки самой яркости, необходимо изменять лишь частоту рабочего цикла. Так как мы передаём данные в виде одного байта, то значения цикла могут быть от 0 до 255. Я решил определить 9 уровней яркости (от 0 до 8). Следовательно, все 256 значений нужно разбить на 9 ступеней. Но также стоит обратить внимание на то, что если ступени будут равными, то яркость будет изменяться не так плавно, как хотелось бы. То есть уже, к примеру, на 4-ой ступени, яркость будет почти максимальной, а с 4-ой по 8-ую ступень будет изменять почти незаметно. Учитывая это, я решил использовать геометрическую прогрессию со знаменателем 2. То есть яркость будет вычисляться по следующей формуле: (2 ^ lvl) — 1, где lvl — уровень яркости от 0 до 8. Обратите внимание, что так как значения начинаются с нуля, то необходимо вычесть единицу. Конечно, вы можете выбрать ступени и их значения сами, но я привёл вот такой, довольно просто пример. Теперь сам код:
void setBright (byte lvl) { byte brightness (1); for (byte i (1); i <= lvl; i++) //Возведение в степень brightness *= 2; Lcd_Write_Com(0xBE); //Вывод команды Lcd_Write_Data(0x01); //Ставим частоту 760Гц Lcd_Write_Data(brightness-1); //Выводим длину рабочего цикла Lcd_Write_Data(0x01); //Отключаем DBC } Теперь можно использовать UTFT.setBright(byte lvl);