Встроенный «умный» символ ЖК-драйвера.Это хорошая идея? - PullRequest
0 голосов
/ 23 мая 2010

У меня есть встроенный проект, над которым я работаю, и в настоящее время я кодирую драйвер ЖК-дисплея персонажа.

На данный момент драйвер ЖК-дисплея поддерживает только "тупую" запись. Например, предположим, что в строке 1 есть текст, и я вызываю функцию, которая пишет в строку. Функция просто ищет начало строки и записывает текст (плюс достаточно пробелов, чтобы стереть все, что было написано в последний раз).

Это хорошо, но иногда я чувствую, что это ужасно неэффективно, поскольку некоторые строки просто: "Чтение-чтением-какое-то значение"

Вместо "грубой силы", заменяющей всю строку, я хотел разработать некоторый код, который бы нашел лучший способ обновить информацию на ЖК-дисплее.

(как фон, для поиска любой позиции символа требуется 2 байта. Затем я могу начать писать строку)

Моя идея состояла в том, чтобы сначала создать цикл. Этот цикл будет сравнивать ввод с последней записью, и при этом он будет охватывать две вещи:

A: Соберите все различия между последней записью и вводом. Для каждого смежного сегмента (будь то один или другой) добавьте два байта к числу байтов. На это ссылаются в B, чтобы определить, расходуем ли мы последовательную полосу пропускания.

Б: Цикл определит, действительно ли это разумно. Если в итоге мы будем использовать больше байтов для обновления строки, чем для "грубой силы" строки, то мы должны просто вернуться и позволить методу грубой силы вступить во владение. Мы должны выйти из функции интеллектуальной записи, как только это условие будет выполнено, чтобы не терять время.

Следующая часть функции будет учитывать все различия, искать требуемый символ на ЖК-дисплее и записывать их.

Таким образом, если у нас есть такая строка на ЖК-дисплее: «Текущая температура: 80F» и мы хотим обновить его до «Текущая температура: 79F»

Функция пройдёт и увидит, что потребуется меньше пропускной способности, чтобы просто искать «8» и писать «79». «7» покроет «8», а «9» покроет «0». Таким образом, мы не тратим время на запись всей строки.

Это похоже на практическую идею?

Ответы [ 6 ]

2 голосов
/ 23 мая 2010

Нет смысла оптимизировать это. Передача 20 байтов на скорости 9600 бод занимает аппаратные 21 миллисекунды. И занимает программное обеспечение несколько микросекунд. Достаточно быстро, чтобы иметь возможность обновлять дисплей быстрее, чем человеческий глаз мог когда-либо воспринимать в 2 раза. И это не значит, что вам нужна «пропускная способность», нет никаких дополнительных данных, о которых я могу подумать, что вы хочу мультиплексировать на последовательном канале.

2 голосов
/ 23 мая 2010

Предполагая, что смещение на дисплее автоматически увеличивается, и это одна запись для вывода каждого последующего символа, я был бы склонен просто писать всю строку дисплея каждый раз, если нет конкретной проблемы с производительностью, которую вы пытаетесь исправить , То есть: ненужные оптимизации - это потенциальные проблемы с обслуживанием в будущем, и ваше время «оптимизации» было бы лучше потратить на то, что действительно влияет на производительность всего приложения.

Примечание. Если обновление дисплея на самом деле является приложением, влияющим на проблему производительности, у вас, вероятно, есть представление о том, насколько быстрее оно должно быть ... тогда вы (а не мы) можете сами руководить оценкой оптимизации. достаточно.

0 голосов
/ 19 августа 2011

Текстовый режим LCD

Я согласен с другими, если вы пишете в текстовом режиме, нет никакого смысла делать это на уровне персонажа. Время обработки, необходимое для выполнения вычислений, вероятно, займет столько же времени, сколько и время для написания материала.

Более того, уровень на персонажа будет проходить через часть памяти, поскольку вам нужно будет буферизовать то, что отображается в данный момент (то есть, что было написано в последний раз).

Вы можете упростить процесс, разделив экран на секции (линии, как правило, наиболее удобны), а затем отметив их при изменении этой линии. Это особенно полезно, если вы хотите записать в буфер памяти вашего экрана и синхронизировать его позже (например, с временным прерыванием).

Сокращение по проекту

Вместо того, чтобы оставить это на усмотрение водителя, вы можете уменьшить время записи на уровне приложения, гарантируя, что вы будете писать только то, что изменяется. Этого можно достичь, назначив конкретные ячейки значений, по сути, выполнив следующее:

char text[50];
int val;
...
lcd_print("The count is ", 0, 0); // Print static text at the coords (0,0)
sprintf(text, "%d", val);
lcd_print(text, 0, 13); // Print changing text at (0,13)
...
sprintf(text, "%d", val);
lcd_print(text, 0, 13); // Print changing text at (0,13)

А не:

char text[50];
int val;
...
sprintf(text, "The count is %d", val);
lcd_print(text, 0, 0); // Print all text at the coords (0,0)
...
sprintf(text, "The count is %d", val);
lcd_print(text, 0, 0); // Print all text at the coords (0,0)

Графический режим LCD

С другой стороны, если ваш процесс записи довольно дорогой, как у меня (~ 20 байт, рисование символа в графическом режиме), тогда было бы полезно сэкономить время на символьной основе. Есть две схемы, которые вы можете использовать. Первый, как вы описываете, но вы также можете рассмотреть (при использовании графического режима) концепцию буферизации горизонтальной линии пикселей через строку текста.

Запись каждого символа для каждого символа требует ручного перемещения курсора записи на линию пикселей, предполагая, что вы рисуете горизонтально, а затем сверху вниз. Этот шаг можно удалить, написав все верхние строки всех символов в текстовой строке или, что еще лучше, изменив подмножество (т. Е. «ABC», а затем отдельно «I» в «XXXDEFGHX» -> «ABCDEFGHI»).

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

0 голосов
/ 17 сентября 2010

Для отображения символов этот вид оптимизации обновлений - это то, чем занималась библиотека curses.Раньше, когда мы разговаривали с большими компьютерами с немыми терминалами и телефонными линиями со скоростью 1200 бод или меньше, часто было сложно обновить экран достаточно быстро, чтобы программы чувствовали себя интерактивными по медленной модемной линии.Библиотека curses сделала это практичным, сохранив кэш того, что должно быть на экране пользователя, и отправив близко к оптимальному количеству команд перемещения и стирания с вкраплениями обычных символов для отображения.Требовалось, чтобы терминал поддерживал некоторую форму позиционирования курсора.

Библиотека curses живет в нескольких формах, а ncurses , например, хорошо известен, с открытым исходным кодом, иЛицензия под лицензией GPL.

В принципе, вы можете адаптировать ncurses к вашему контроллеру дисплея и позволить ему выполнять всю тяжелую работу.

Открытый вопрос - стоит ли это усилий.На скорости 9600 бод вы можете отправлять 960 символов в секунду.Это достаточно быстро, чтобы полностью перекрасить ЖК-дисплей с 4 строками и 20 колонками 12 раз в секунду.Так что, если вы не работаете в PIC или ATtiny, где вам, возможно, придется внедрить этот UART в программное обеспечение и вам нужны циклы, чтобы действительно сделать что-то полезное, то, вероятно, будет мало преимуществ в том, что вы слишком умны.обычно все же имеет смысл один раз закрасить фиксированный текст и просто обновлять отображаемые значения при их изменении.

0 голосов
/ 23 мая 2010

Таким образом, мы не тратим время на написание из всей строки.

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

Какая связь с ЖК-дисплеем? SPI / I2C / Parellel?

Что бы это ни было, если DMA поддерживается SoC на интерфейсе, используйте его.

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

Используйте либо подпрограмму прерывания для обработки отправки каждого байта, либо используйте «гибридный» подход, если вы можете контролировать маршрутизацию прерываний (делают это для экономии энергии). Вот интересная запись здесь

0 голосов
/ 23 мая 2010

Реализация, которую вы планируете, кажется слишком сложной для решения проблемы.Все необходимое сравнение может фактически замедлить работу, если процессор не быстрый.

Если вам нужно только обновить, например, значение температуры, вам следует просто обновить значение температуры и игнорировать фиксированные тексты.Вам нужно иметь координаты в памяти для каждого поля, которое необходимо обновить.Затем просто переместите позицию записи в это место и запишите значение.Вот как я обычно это делаю.

Если обновление экрана все еще слишком медленное, вы можете рассмотреть использование языка ассемблера.Например, несколько лет назад я сделал программное обеспечение для устройства типа наручных часов с точечно-матричным ЖК-дисплеем.Обновление дисплея было слишком медленным (почти секунда, чтобы обновить весь дисплей, например, при прокрутке), поэтому я написал только процедуру самого низкого уровня в Assembly (заменяя около 20 строк C на 30 строк Assembly).Полученная функция была вдвое меньше и в 3 раза быстрее оптимизированной функции C, и теперь скорость обновления дисплея была достаточной.

...