Jump to content

    
Sign in to follow this  
hasuman_

ЖКИ на основе SED1520

Recommended Posts

Никак не соображу как лучше рисовать символы.

Сейчас работаю следующим образом:

1. Есть массив, в котором лежат все символы в виде {0x00, 0xFF, 0xFF, 0xAA, 0x84, 0xFF и т.д.}. Символ размером 8x6(высота, ширина). То есть для 10 символов получается массив из 60 байт.

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

При вызове функции вывода символа на экран (например printf('A')), ищу в массиве структур нужный мне символ, беру из этой структуры индекс, с которого начинается символ в массиве и последовательно вывожу 6 байт символа.

Может кто-нибудь знает способ проще и быстрее? :)

Share this post


Link to post
Share on other sites
Может кто-нибудь знает способ проще и быстрее? :)
Раз размер символов фиксирован - достаточно умножить код символа на размер и прибавить к адресу начала массива. Если массивов несколько - то под каждый может быть структура с размером символа и указателем на начало массива.

Share this post


Link to post
Share on other sites
Раз размер символов фиксирован - достаточно умножить код символа на размер и прибавить к адресу начала массива.

"код символа" - имеется ввиду ascii-код? Если да, то для массива в котором хранятся цифры 0-9 и буквы А-Я(в порядке возрастания кодов) нужно будет сделать одну промежуточную операцию: если рисуем цифру, то из кода символа нужно вычесть код '0', а если букву, то вычесть код 'А'. Затем уже умножаем получившееся число на размер символа - это и есть индекс начала символа в массиве. Или я не прав?

Share this post


Link to post
Share on other sites
"код символа" - имеется ввиду ascii-код? Если да, то для массива в котором хранятся цифры 0-9 и буквы А-Я(в порядке возрастания кодов) нужно будет сделать одну промежуточную операцию: если рисуем цифру, то из кода символа нужно вычесть код '0', а если букву, то вычесть код 'А'. Затем уже умножаем получившееся число на размер символа - это и есть индекс начала символа в массиве. Или я не прав?

Заполните всю кодовую таблицу для 256 символов, цифры и буквы уравняются в правах :)

Тогда не нужно ничего анализировать.

Чуть больше места в памяти, но будет быстрее работать.

А если сделать матрицу 8*8 (все равно нужны промежутки между символами), расположить таблицу по адресу с 11 младшими нулевыми разрядами и заменить перемножение на сдвиг и логическое сложение, все будет просто летать, как на Пентиуме :biggrin:

Share this post


Link to post
Share on other sites
А если сделать матрицу 8*8 (все равно нужны промежутки между символами), расположить таблицу по адресу с 11 младшими нулевыми разрядами и заменить перемножение на сдвиг и логическое сложение, все будет просто летать, как на Пентиуме :biggrin:

Сам хотел сделать 8*8, но экрана не хватит для всей информации :(

Размер экрана 120*32, разница в 5 символов получается.

А что значит "расположить таблицу по адресу с 11 младшими нулевыми разрядами"? То есть положить в память, например по адресу 0x800?

PS. пишу на Си под msp430

Share this post


Link to post
Share on other sites
А что значит "расположить таблицу по адресу с 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, и будет максимальное быстродействие.

Share this post


Link to post
Share on other sites
Никак не соображу как лучше рисовать символы.

Может кто-нибудь знает способ проще и быстрее? :)

Я использую для рисования библиотеку uc-GUI или отдельные её части (на небольших платформах типа AVR).

В частности для шрифтов есть специальные утилитки, позволяющие создавать по-пиксельные изображения любых шрифтов (в т.ч. разных размеров, bold, italic)... Я использую все структуры, которые используются в uc-GUI, тем самым достигается легкость в использовании шрифтов различных размеров и типов (пропорциональные и моноширинные).. Для пропорциональных шрифтов в структуры специально закладывается отступ для каждого символа..

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

Если вас заинтересуют подробности, утилиты, некоторые исходники... пишите в PM :)

Share this post


Link to post
Share on other sites

Вот, что у меня получилось. Дельные комментарии приветствуются :)

#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 */

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this