|
ЖКИ на основе SED1520, как рисовать правильно? |
|
|
|
Apr 24 2009, 07:49
|
Группа: Участник
Сообщений: 11
Регистрация: 9-02-09
Пользователь №: 44 597

|
Никак не соображу как лучше рисовать символы. Сейчас работаю следующим образом: 1. Есть массив, в котором лежат все символы в виде {0x00, 0xFF, 0xFF, 0xAA, 0x84, 0xFF и т.д.}. Символ размером 8x6(высота, ширина). То есть для 10 символов получается массив из 60 байт. 2. Есть массив структур. В структуре лежит сам символ и индекс, с которого этот символ начинается в массиве описанном выше. При вызове функции вывода символа на экран (например printf('A')), ищу в массиве структур нужный мне символ, беру из этой структуры индекс, с которого начинается символ в массиве и последовательно вывожу 6 байт символа. Может кто-нибудь знает способ проще и быстрее?
|
|
|
|
|
 |
Ответов
(1 - 8)
|
Apr 24 2009, 10:58
|
Группа: Участник
Сообщений: 11
Регистрация: 9-02-09
Пользователь №: 44 597

|
Цитата(Сергей Борщ @ Apr 24 2009, 14:07)  Раз размер символов фиксирован - достаточно умножить код символа на размер и прибавить к адресу начала массива. "код символа" - имеется ввиду ascii-код? Если да, то для массива в котором хранятся цифры 0-9 и буквы А-Я(в порядке возрастания кодов) нужно будет сделать одну промежуточную операцию: если рисуем цифру, то из кода символа нужно вычесть код '0', а если букву, то вычесть код 'А'. Затем уже умножаем получившееся число на размер символа - это и есть индекс начала символа в массиве. Или я не прав?
|
|
|
|
|
Apr 24 2009, 11:17
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(HasuMan @ Apr 24 2009, 13:58)  "код символа" - имеется ввиду ascii-код? Если да, то для массива в котором хранятся цифры 0-9 и буквы А-Я(в порядке возрастания кодов) нужно будет сделать одну промежуточную операцию: если рисуем цифру, то из кода символа нужно вычесть код '0', а если букву, то вычесть код 'А'. Затем уже умножаем получившееся число на размер символа - это и есть индекс начала символа в массиве. Или я не прав? Заполните всю кодовую таблицу для 256 символов, цифры и буквы уравняются в правах  Тогда не нужно ничего анализировать. Чуть больше места в памяти, но будет быстрее работать. А если сделать матрицу 8*8 (все равно нужны промежутки между символами), расположить таблицу по адресу с 11 младшими нулевыми разрядами и заменить перемножение на сдвиг и логическое сложение, все будет просто летать, как на Пентиуме
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Apr 24 2009, 11:41
|
Группа: Участник
Сообщений: 11
Регистрация: 9-02-09
Пользователь №: 44 597

|
Цитата(Dog Pawlowa @ Apr 24 2009, 15:17)  А если сделать матрицу 8*8 (все равно нужны промежутки между символами), расположить таблицу по адресу с 11 младшими нулевыми разрядами и заменить перемножение на сдвиг и логическое сложение, все будет просто летать, как на Пентиуме  Сам хотел сделать 8*8, но экрана не хватит для всей информации  Размер экрана 120*32, разница в 5 символов получается. А что значит "расположить таблицу по адресу с 11 младшими нулевыми разрядами"? То есть положить в память, например по адресу 0x800? PS. пишу на Си под msp430
|
|
|
|
|
Apr 24 2009, 12:59
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(HasuMan @ Apr 24 2009, 14:41)  А что значит "расположить таблицу по адресу с 11 младшими нулевыми разрядами"? То есть положить в память, например по адресу 0x800? PS. пишу на Си под msp430 Если 8 байтов не получается, то тогда нет смысла, остается умножение: Код unsigned char * a = table_pointer+ ((unsigned int) my_char)*6; SendToLcd(*a); a++; SendToLcd(*a); a++; SendToLcd(*a); a++; SendToLcd(*a); a++; SendToLcd(*a); a++; SendToLcd(*a); a++; Сделайте SendToLcd() pragma inline forced, и будет максимальное быстродействие.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Apr 24 2009, 13:21
|

инопланетянин
  
Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832

|
Цитата(HasuMan @ Apr 24 2009, 11:49)  Никак не соображу как лучше рисовать символы. Может кто-нибудь знает способ проще и быстрее?  Я использую для рисования библиотеку uc-GUI или отдельные её части (на небольших платформах типа AVR). В частности для шрифтов есть специальные утилитки, позволяющие создавать по-пиксельные изображения любых шрифтов (в т.ч. разных размеров, bold, italic)... Я использую все структуры, которые используются в uc-GUI, тем самым достигается легкость в использовании шрифтов различных размеров и типов (пропорциональные и моноширинные).. Для пропорциональных шрифтов в структуры специально закладывается отступ для каждого символа.. Такой подход не претендует на повышение быстродействия, однако этим очень удобно пользоваться.. Если вас заинтересуют подробности, утилиты, некоторые исходники... пишите в PM
|
|
|
|
|
Apr 27 2009, 04:52
|
Группа: Участник
Сообщений: 11
Регистрация: 9-02-09
Пользователь №: 44 597

|
Цитата(Dog Pawlowa @ Apr 24 2009, 16:59)  Сделайте SendToLcd() pragma inline forced, и будет максимальное быстродействие. Спасибо за помощь, так и сделаю.
|
|
|
|
|
Apr 29 2009, 05:44
|
Группа: Участник
Сообщений: 11
Регистрация: 9-02-09
Пользователь №: 44 597

|
Вот, что у меня получилось. Дельные комментарии приветствуются  CODE #ifndef lcd_header #define lcd_header
#include <msp430x16x.h> #include "symbols.h" #include "mytypes.h"
uChar lcd_CurrColumn; // текущий столбец LCD-дисплея uChar lcd_CurrPage; // текущая страница LCD-дисплея
//P4 #define lcd_Data P4OUT #define lcd_ImageOff 0xAE // выключить изображение #define lcd_ImageOn 0xAF // включить изображение #define lcd_StaticControlOn 0xA4 // включить статическое управление #define lcd_StaticControlOff 0xA5 // выключить ---//--- #define lcd_Reset 0xE2 // сброс #define lcd_SetStartString 0xC0 // установить начальную строку #define lcd_SetPage 0xB8 // установить страницу #define lcd_SetColumn 0x00 // установить столбец //P6 #define lcd_Control P6OUT #define lcd_A0 BIT4 #define lcd_RW BIT5 #define lcd_E1 BIT6 #define lcd_E2 BIT7 #define lcd_E12 0xC0
/// Функция посылки комманды на LCD-дисплей. /// cmd - комманда, посылаемая дисплею. /// param нужен только для установки начальной строки, страницы и столбца; /// в остальных случаях он не используется. /// Значения начальной строки могут быть 0-31, /// страницы 0-3, столбца 0-119. /// void LcdSendCommand(uChar cmd, uChar param) { lcd_Control &= ~(lcd_A0 + lcd_RW); // подаем на входы A0 и RW низкий уровень switch(cmd) // записываем комманду в ОЗУ дисплея { case lcd_SetStartString:/* начальная строка */ lcd_Data = (cmd | param); lcd_Control |= lcd_E12; // разрешаем выполнение lcd_Control &= ~lcd_E12; // для обоих частей экрана break;
case lcd_SetPage:/* страница */ lcd_Data = (cmd | param); lcd_CurrPage = param; // устанавливаем новую текущую страницу lcd_Control |= lcd_E12; // разрешаем выполнение lcd_Control &= ~lcd_E12; // для обоих частей экрана break; case lcd_SetColumn:/* столбец */ if(param <= 59) // если столбец < 60, { lcd_Data = (cmd | param); lcd_Control |= lcd_E1; // то выполняем для левой части lcd_Control &= ~lcd_E1; } else // иначе { lcd_Data = (cmd | (param - 60)); lcd_Control |= lcd_E2; // выполняем для правой части lcd_Control &= ~lcd_E2; } lcd_CurrColumn = param; // устанавливаем новый текущий столбец break; default:/* остальные комманды */ lcd_Data = cmd; lcd_Control |= lcd_E12; // разрешаем выполнение lcd_Control &= ~lcd_E12; // для обоих частей экрана break; } }; /* LcdSendCommand() */
/// Функция посылки данных на LCD-дисплей. /// data - 8 бит данных. /// #pragma inline=forced void LcdSendData(uChar *data) { lcd_Control |= lcd_A0; // высокий уровень на A0 lcd_Control &= ~lcd_RW;// низкий уровень на RW lcd_Data = *data; // записываем данные в ОЗУ дисплея /* рисуем на нужной половине экрана */ if(lcd_CurrColumn <= 59) { lcd_Control |= lcd_E1; lcd_Control &= ~lcd_E1; } else { lcd_Control |= lcd_E2; lcd_Control &= ~lcd_E2; } }; /* LcdSendData() */
/// Функция рисования символа на дисплее. /// symb - символ, который нужно нарисовать. /// void LcdPutChar(uChar symb) { for(uChar i = 0; i < 6; i++) { LcdSendData(&symb_array[(symb * 6) + i]); lcd_CurrColumn++; // увеличиваем счетчик столбца
if(lcd_CurrColumn == 60) // если кончилась левая половина экрана LcdSendCommand(lcd_SetColumn, lcd_CurrColumn);
if(lcd_CurrColumn == 120) // если столбец выехал за правую половину экрана { lcd_CurrColumn = 0; // обнуляем столбец lcd_CurrPage++; // и переходим на след страницу if(lcd_CurrPage > 3) // если страница >3, то переходим на верхнюю lcd_CurrPage = 0; LcdSendCommand(lcd_SetPage, lcd_CurrPage); // устанавливаем новую LcdSendCommand(lcd_SetColumn, lcd_CurrColumn);// страницу и столбец } }
}; /* LcdPutChar() */
/// Функция вывода строки текста на экран. /// str - указатель на строку, которую нужно вывести. /// #pragma inline=forced void LcdPutText(uChar *str) { while(*str) LcdPutChar(*str++);
}; /* LcdPutText() */
/// Функция очистки LCD-дисплея. /// #pragma inline=forced void LcdClearScreen() { LcdSendCommand(lcd_SetColumn, 0); // устанавливаем столбец LcdSendCommand(lcd_SetPage, 0); // и страницу в 0 uChar tmp[] = " "; // 20 пробелов, чтобы for(uChar i = 0; i < 4; i++) // зарисвать 4 строки LcdPutText(tmp); // зарисовываем весь экран пробелами }; /* LcdClearScreen() */
/// Функция инициализации LCD-дисплея /// #pragma inline=forced void InitLcd() { LcdSendCommand(lcd_SetStartString, 0); LcdClearScreen(); LcdSendCommand(lcd_ImageOn, 0);
}; /* InitLcd() */
#endif /* lcd_header */
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|