Введение
В настоящее время я занимаюсь проектом на Arduino с использованием TFT дисплея. Недавно мне захотелось добавить в него, казалось бы, простую функцию — функцию регулировки яркости. Нашёл в документации к библиотеке для работы с TFT дисплеем (UTFT Library) нужный метод: setBrightness(br);
Написал весь код, сделал все, как надо. Решил проверить, но, к моему удивлению, ничего не происходило. Начал разбираться. Спустя два дня, заметил небольшое примечание к методу: "This function is currently only supported on CPLD-based displays."
То есть, данная библиотека, не поддерживает мой дисплей. Но я узнал, что сам дисплей регулировку яркости поддерживает. Очень долго искал в интернете способы настройки, но так и не нашёл, поэтому решил добиться своей цели сам, несмотря ни на что, и у меня это получилось. И вот решил поделиться с теми, кому это может пригодиться.
Что нам понадобится?
- В качестве основы, я использовал Frearduino ADK v.2.2 на базе процессора ATmega2560
- TFT LCD Mega Shield v.2.2
- Сам дисплей — 7" TFT LCD SSD1963 (Тут вы найдёте его описание, а так же необходимую документацию)
- UTFT Library — универсальная библиотека для работы с TFT дисплеями (Найти саму библиотеку, а так же документацию можно тут)
- Паяльник
Разберёмся с железом
Открыв схему дисплея, можно увидеть, что на конвертер 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 или нет (0x01 — выключен, 0x09 — включен).
Для регулировки самой яркости, необходимо изменять лишь частоту рабочего цикла. Так как мы передаём данные в виде одного байта, то значения цикла могут быть от 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);
Автор: FuryaevStanislav