+7 (495) 662-44-14

Главная / Форум
  • РУС / ENG
(495) 662-44-14 Многоканальный телефон Не дозвонились?
Форумы >>ЖК индикаторы >>RE: Символы, программируемые пользователем МТ–16S1A
RE: Символы, программируемые пользователем МТ–16S1A

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

подскажите пожалуйста какие команды надо подать в CVAvr, чтобы запрограммировать свои символы? какая должна быть последовательность команд? 4-х битный режим, стандартная библиотека

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Не очень уверен какую именно библиотеку Вы считаете стандартной и для какой версии CVAvr, но вот один из вариантов решения для LCD.lib версий до 2.0: сделать специальную функцию для изменения изображения символа и пользоваться этими символами как обычными:

Код:
void SetNewSymbol(byte a, byte * p) {//Код символа и указатель на массив его изображения
byte i;
_lcd_ready(); _lcd_write_data(0x40 + ((a & 0x07) << 3));//Переключение на память изображений символов
for (i = 0; i < 8; i++) {
_lcd_ready();
#asm("sbi __lcd_port,__lcd_rs ;RS=1");
_lcd_write_data(*p++);//Изменение изображения символа
};
lcd_gotoxy(_lcd_x, _lcd_y);//Переключение обратно на память текста (DDRAM) без перемещения курсора
}
Вызов функции меняет изображение указанного символа, без разницы есть или нет он на экране. Если есть - изображение меняется во всех позициях где он есть, одновременно и мгновенно.

PS. Заодно уж, чтоб два раза не вставать, код для переключения страницы знакогенератора:
Код:
{ _lcd_ready(); _lcd_write_data(0x28); }//Включить 0-ю страницу знакогенератора
{ _lcd_ready(); _lcd_write_data(0x2A); }//Включить 1-ю страницу знакогенератора

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Судя по Вашему старому сообщению (середина 2014 года) библиотека у Вас более новой версии и не в исходном коде, а в двоичном. Тогда если код выше не заработает, то не знаю что делать, нужно детальное описание функций именно Вашей библиотеки.
Общая идея банальна: выдать команду 0x40+<код_символа>*8, потом 8 байтов данных нового изображения символа, потом вернуть курсор туда где был (командой 0x80+x или 0xC0+x). Но как это сделать именно с Вашей библиотекой - без понятия.

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

приятно, когда вспоминают твои сообщения
версия CVAvr 2.05.3, библиотека alcd.lib

я понял саму идею записи своего символа, но не понимаю последовательность команд
может рассмотрим на примере?

например я хочу записать на страницу 0 в адрес 0х00 символ "+", ясно что значения в знакогенераторе будут
00000
00100
00100
11111
00100
00100
00000

я даю команду _lcd_write_data(0x40) для первой строки, значения которой должно быть 00000
а дальше? как должна выглядеть последовательность команд для записи этой строки и других строк? правильно ли я все понимаю?

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Сначала даёте команду 0x40 (вызовом процедур _lcd_ready() и _lcd_write_data(0x040)), она переключает память на CGRAM (знакогенератор) и выбирает символ для обновления. Потом нужно индикатору передать 8 байтов как данные (символы) (т.е. вывести символы с кодами 0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00 для вашего плюсика, которые для моей процедурки выше должны лежать в массиве), по идее это должна делать lcd_putchar, но она одновременно перемещает курсор (что несложно обойти) и обрабатывает код 0x0A как переход на новую строку и не записывает его в индикатор вообще - а вот это засада! Как её корректно обойти я не придумал. Если же не совсем корректно, то можно сделать так (т.к. старшие три бита в каждом байте изображения никак не используются):

Код:
void SetNewSymbol(byte a, byte * p) {//Код символа и указатель на массив его изображения
byte x, i;
x = _lcd_x; _lcd_x = 0; _lcd_maxx += 10;//Нужно для putchar
_lcd_ready(); _lcd_write_data(0x40 + ((a & 0x07) << 3));//Переключение на память изображений символов
for (i = 0; i < 8; i++) lcd_putchar((*p++) | 0x40);//Изменение изображения символа, 0x40 добавлено для исключения обработки кода 0x0A
_lcd_maxx -= 10; lcd_gotoxy(x, _lcd_y);//Переключение обратно на память текста (DDRAM) без перемещения курсора
}

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

то есть в данном случае переменная a - это адрес символа с 0х00 по 0х07, а p - это массив (в этом конкретном случае с плюсиком) со значениями [0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00]?

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Да. Только вместо "адрес символа" понятнее использовать "код символа". Например код символа "7" - 0x37. А "адрес символа" в CGRAM (точнее его верхней строки) - его код, умноженный на 8. Т.е. "код символа" - принадлежность самого символа (если забыть о разных кодировках), а вот "адрес символа" - свойство зависящее от контекста (например символам с кодами 0x08-0xFF никаких адресов не сопоставлено).

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

испробовал. проблема в том что компилятор не принимает ни _lcd_x, ни _lcd_maxx, ни _lcd_y
а lcd_putchar, да, не записывает.
уж не знаю, то ли библиотека такая, то ли я чего не понимаю. я не программист, а технарь, поэтому не все сразу доступно для понимания

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Вполне возможно, я говорил по своей библиотеке для более старого компилятора, 1.25, там она в исходном коде доступна. Что поменяли в 2.0 версиях мне неизвестно, может и ничего, просто убрали доступ к внутренним переменным.
Хм, а на _lcd_ready() и _lcd_write_data() не ругается? Ну тогда можно попробовать плюнуть на сохранение позиции курсора и сделать так:

Код:
void SetNewSymbol(byte a, byte * p) {//Код символа и указатель на массив его изображения
a = 0x40 + ((a & 0x07) << 3);
do {
_lcd_ready(); _lcd_write_data(a);//Переключение на память изображений символов
lcd_putchar((*p++) | 0x40);//Изменение изображения символа, 0x40 добавлено для исключения обработки кода 0x0A
} while (++a & 0x07);
lcd_gotoxy(0, 0);//Переключение обратно на память текста (DDRAM), курсор в левый верхний угол
}
Последнюю команду исключать нельзя!

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

как говориться, то ли лыжи не едут, то ли я...
максимально упростил для моего понимания и изменил немного алгоритм и записал следующее (все переменные и массивы были обьявлены как глобальные, из них массив symbol_s - массив с кодом символа)

Код:
void new_symbol()
{
code_symb=0x40+((code_symb&0x07)<<3);
do
{
_lcd_write_data(code_symb); // Переключение на память изображений символов
lcd_putchar((symbol_s[line])|0x40); // Изменение изображения символа, 0x40 добавлено для исключения обработки кода 0x0A
line++;
code_symb++;
} while (line<8);
lcd_gotoxy(0,0);
line=0;
}

вывожу на экран витиеватой командой, потому что остальные более сложные надписи этим выводятся
Код:
sprintf(lcd_buffer,"\x00");
lcd_gotoxy(0,0);
lcd_puts(lcd_buffer);

знакоместо пустое, т..е. ничего не выводится. какую ошибку я мог допустить?

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

чую я что придется заказать у вас еще индикаторов с сразу вшитыми символами, нужных мне

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Вы забыли _lcd_ready() перед _lcd_write_data() - а значит последние вообще не отработали, кроме возможно самой первой.
line надо инициализировать в 0 перед циклом do, а не после.
Символ с кодом 0x00 не может выводиться командами строкового вывода - это же код конца строки! Вот lcd_putchar на ноль не проверяет и ею такой символ вывести можно. Но для удобства, когда хватает 7-ми своих символов, символ с кодом 0x00 лучше не использовать.
Излишнее использование глобальных переменных - плохо! Если так уж хочется через глобальный массив сделать, то лучше так:

Код:
void SetNewSymbol(byte a) {//Код символа
byte line;
a = 0x40 + ((a & 0x07) << 3);
for (line = 0; line < 8; line++) {//Стандартный вариант организации цикла на 8 повторений
_lcd_ready(); _lcd_write_data(a + line);//Переключение на память изображений символов
lcd_putchar(symbol_s[line] | 0x40);//Изменение изображения символа, 0x40 добавлено для исключения обработки кода 0x0A
};
lcd_gotoxy(0, 0);//Переключение обратно на память текста (DDRAM), курсор в левый верхний угол
}

Вызов:
Код:
SetNewSymbol(0x03);//Изменить изображение символа с кодом 0x03 по глобальному массиву
sprintf(lcd_buffer, "Symbol: {\x03}"); lcd_gotoxy(0, 0); lcd_puts(lcd_buffer);

А вот как выглядит вызов с произвольным массивом в параметре, для того варианта что раньше был:
Код:
SetNewSymbol(0x03, symbol_s);//Изменить изображение символа с кодом 0x03 по произвольному массиву
Согласитесь вполне понятно же.

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

итак, лед тронулся
но....как же без но)

мой массив {0x0E,0x11,0x17,0x11,0x1D,0x11,0x0E,0x00};

Код:
void new_symbol(char a)
{
char line;
a=0x40+((a&0x07)<<3);
for (line=0; line<8; line++)
{
_lcd_write_data(a+line); // Переключение на память изображений символов
lcd_putchar((symbol_s[line])|0x40); // Изменение изображения символа, 0x40 добавлено для исключения обработки кода 0x0A
}
lcd_gotoxy(0,0);
}


вывод символа
Код:
new_symbol(1);
sprintf(lcd_buffer, "\x01");
lcd_gotoxy(0,0);
lcd_puts(lcd_buffer);


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

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Вы снова забыли _lcd_ready(). Это уже не смешно.

И пользуйтесь пожалуйста тегом [code], он есть по кнопочке # справа от кнопки Quote выше основного текста, с ним код выглядит хоть немного лучше, пусть и без отступов, зато нет лишних смайлов.

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

_lcd_ready() команда не принимается компилятором. я ее не забыл. _lcd_write_data() работает без _lcd_ready()
я просто не могу понять, почему именно третий элемент в массиве 0x17 отображается не как 10111, а как 11111. именно третий, третья строка в символе, а все остальные нормально

насчет оформления понял, постараюсь делать правильно

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Без _lcd_ready() надо тогда вместо неё поставить задержку на 40мкс минимум. Перед _lcd_write_data.

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

устанавливал паузы по 50 и 100мкс, была попытка вывести разные символы. результат тот же, третья строка выводится как 11111 при значении 0x17 или любом другом. память CGRAM ведь перезаписываемая?
возможны ли аппаратные баги? очень смущает некорректный вывод именно третий строки символа. у меня есть еще один такой же индикатор. стоит ли пробовать?

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

CGRAM обычная статическая память, как и вся память в индикаторе.
А другие коды в третью строку выводятся правильно? Попробуйте хотя бы 0х00,0х07,0х10,0х11.
Выводится ли код 0x17 в какую-нибудь другую строку или это свойство кода такое, не выводиться никуда?
Попробуйте заменить 0x40 на 0x80 в lcd_putchar.
Заменить код символа с 0x03 на другой (кроме нулевого) пробовали?
Аппаратная неисправность индикатора - последнее о чём надо думать.
Попробуйте не заработает ли такой код:

Код:
void new_symbol(char a) { //Код изменяемого символа
char line;
a = 0x40 + ((a & 0x07) << 3); //Формирование адреса символа в CGRAM
for (line=0; line<8; line++) _lcd_write_byte(a + line, symbol_s[line]); //Изменение изображения символа
lcd_gotoxy(0, 0);//Переключение обратно на память текста (DDRAM), курсор в левый верхний угол
}

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

rukhafi
Пользователи

Сообщений: 24
Регистрация: 24.04.2014

ну наконец то заработало как надо

спасла ситуацию именно команда lcd_write_byte(a + line, symbol_s[line] | 0x40);

спасибо Вам за помощь и терпение!

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение

Петухов_Дмитрий
Пользователи

Сообщений: 1238
Регистрация: 25.11.2009

Ну наконец добили.
Да, кстати, 0x40 к байтам изображения уже добавлять не надо, можно писать прямо байты из массива, код я поправил.

Имя Для добавления сообщений Вы должны зарегистрироваться или авторизоваться Цитировать Получить ссылку на сообщение
Сейчас на форуме (гостей: 8, пользователей: 0 , из них : 0 )