Приветствую Вас, Гость! Регистрация RSS

Пятница, 19.04.2024
Главная » Статьи » Cтатьи

CodeVisionAVR. Подключение графического индикатора WG12864B-YGH-VN к микроконтроллеру ATMEGA8535. часть 3

Введение

Продолжаем третью часть статьи по графическому индикатору WG12864B-YGH-VN, в которой научимся выводит отдельно символы и целые строки.

Напишем программу по выводу символа на экран.



Результатом выполнения программы будет слово test:



Первый результат. Выводим символ



Функция принимает 4 параметра:

character – код символа по кодировке ASCII. Например U – 0x55 (85), 7 – 0x73 (55). Эти коды можно посмотреть, открыв таблицу символов Windows



(нужно выбрать из списка набор символов строчку Windows: кириллица и в строке состояния посмотреть hex код символа).

x, y – координаты вывода одного символа. Это означает, в каком месте экрана будет выведен один символ.
Inv – инвертирование вывода символа.
          • Если inv = 0, то темный символ на светлом фоне.
          • Если inv = 255, то светлый символ на темном фоне.

Полный код функции:



Мы знаем что дисплей WG12864B-YGH-VN имеет два контроллера и соответственно два полуэкрана. В область полуэкрана 64*64 можно вывести 10 символов. Однако есть нюанс: последний символ приходится на границу полуэкрана. Чтобы исключить данный нюанс, нужно сделать так, чтобы символ выводился от левого края с небольшим отступом, например, 4 точки. Этот вариант организован в функции goto_xy:



x, y – Указываем координаты вывода символа.

Как видно, функция принимает 2 аргумента и возвращает результат: в каком полуэкране выводить символы.

Полный код функции:



В операторе if(){}else{} проверяем, если х<10, то переменной cs присваивается значение 0, переменной textcs присваивается 0, в противном случае переменной cs присваивается значение 1, переменной textcs присваивается 64. Вся основная расчетная математика является аргументом функции glcd_xy, которую рассматривали ранее.



Это часть кода позволяет автоматически переходить на новую строку по мере заполнения. Я думаю объяснения не нужны...

Основным элементом функции является оператор цикла с постусловием do{}while();, в котором происходит взаимодействие функции write_data_glcd с двухмерным массивов символов charsets[160][6]:



Он эквивалентен такой записи:



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

Немного вспомним или освоим, что же такое многомерный массив. Это массив массивов, т.е. массив, элементами которого являются массивы. Размерность массива – это количество индексов, используемых для ссылки на конкретный элемент массива. Двухмерный массив charsets, который содержится в заголовочном файле GenerateCode.h содержит 160 индексов, указывающих на массивы из 6-ти элементов по 1 байту:




Размер символов данного массива я выбрал 7х6 – 6-ой байт имеет 0х00. В процессе работы с массивом символов 7х5, возникла проблема вывода символов с инверсией: между белыми символами с черным заполнением вокруг, получались белые полоски, и текст выглядел так:


Пробовал множество манипуляций с функциями вывода символа и строки, но так истинна и не открылась, поэтому остановился с размерами 7х6. С массивом 7х6 все получалось отлично (да и какая разница, текст выводится в полнее исправно):


Первым индексом массива является символ пробела, потом восклицательный знак и т.д. Как оговаривалось выше, все символы Windows имеют кодировку ASCII. Для того, чтобы связать массив символов с кодировкой Win-символов используются два оператора if с проверкой диапазона кода символа:



Если код Win-символа меньше 0х7F, то от переменной character вычитаем число 0х20 и получаем индекс массива charsets. В следующем операторе проверяем если код Win-символа больше 0хBF, то от переменной character вычитаем число 0х60 и получаем индекс массива charsets:

- Charsets = 0x48 (72),   значит будем вычитать 0х20 (32), и в итоге получим число 40   – индекс массива символа H (англ.)
- Charsets = 0xE5 (229), значит будем вычитать 0х60 (96), и в итоге получим число 133 – индекс массива символа е (русс.)


по коду:



Как видно, совершенно не сложно, простое вычисление чисел.

Второй результат. Выводим строки

Поскольку мы разобрались как выводить символ, разберемся как выводить строку.
Основная программа по выводу строковой информации на экран:





Ну а теперь собственно функции по выводу строки:



Названия putsf, puts, putchar взял из стандартной библиотеки LCD.H CodeVisionAVR, т.к. они более привычны глазу.

Функция вывода строки, аргументом которой является непосредственно текст записанный в ковычках:



str[] – массив, который будет проинициализирован текстом. Тип flash указывает, что символы массива будут помещены компилятором во flash память микроконтроллера.
x, y – координаты вывода строки. Это означает, в какого места экрана будет выведена строка.
Inv – инвертирование вывода строки.

Полный код функции:



Немного Си теории

В Си/С++, в отличие от многих других языков, отсутствует специальный строковый тип. Вместо этого строки представляются как массив типа char, в конце которого помещен символ "\0" или нуль-терминатор. В этом случае массив называется строкой в формате ASCII (ASCII строка). При объявлении массива, под строку необходимо предусмотреть место для нуль-терминатора, которым заканчивается любая строка. Пример объявления строкового массива:



при такой инициализации массива, нуль-терминатор указывается символом конца строки.



При такой инициализации массива, текст, помещенный в кавычки, будет рассматриваться как строка, и поэтому компилятор автоматически добавит нуль-терминатор. Исходя из данного определения строкового массива, воспользуемся нуль-терминатором для определения конца строки. Например функция glcd_putsf с текстом:



В этом случае массив в flash char str[] будет проинициализирован 12-ю символами букв + 13-й символ нуль - терминатор:



Раз массив определяется в формате ASCII, то по сути каждый символ букв, будет представлен кодом:



по элементу массива:



Рассмотрим смысл работы функции glcd_putsf. Основным элементом функции является оператор цикла с постусловием:



Весь процесс работы цикла состоит в том, что переменной k присваивается значение элементов массива str, которые выбираются по инкременту переменной j. Оператор if проверяет, не содержит ли переменная k нуль-терминатор (0х00). Если содержит, то прерывается цикл do{}while(); оператором break. Все коды символов кроме \0, которые содержала переменная k, передаются в функцию glcd_putchar, пока выполняется цикл.

Функция вывода строки, аргументом которой является переменная:



*str – переменная типа указатель на объект символьного типа char, которая хранит адрес элемента памяти.

Компилятор выделит память как для строки, так и для размещения значения указателя. например, записать можно так:



или так



x, y – координаты вывода строки.
Inv – инвертирование вывода строки.

Полный код функции:



Пример вывода строк, которые заполняют весь экран графического индикатора. Конечно получается некрасиво, но это только для наглядности:

 


Можно создавать, что-то типа Справки или помощь по описанию и использованию устройства.

Ну в общем-то, все что хотел предоставить по графическому дисплею WG12864B-YGH-VN, то и предоставил, настолько насколько хватило знаний, терпения, и не желания это держать в себе. Кто дошел до конца третьей части статьи (соответственно с прочтенными двумя) огромное спасибо, что не оставили без внимания!

Файлы

library_wg12864_cvavr.rar

Категория: Cтатьи | Добавил: Автор (11.06.2010)
Просмотров: 20046 | Комментарии: 14 | Теги: вывод строки на lcd, многомерный массив, функция putchar, функция puts, вывод текста на дисплей, нуль-терминатор, функция putsf | Рейтинг: 5.0/3
Всего комментариев: 141 2 »
1 us4ilq  
1
Ну ОЧЕНЬ здорово!
Вот если бы еше подробненько описать рисование точек, линий, вывод
заготовленных (например в программе KS0108 v 4.0 For PIC) изображений.
Чтоб можно было писать проги типа анализаторов спектра, осциллографы и т.д. и т.п.
Похоже чето я слишком разошелся.

2 Автор  
0
если бы еше подробненько описать рисование точек, линий, вывод заготовленных изображений.

Я как раз собираюсь этим заняться по истечению некоторого времени. Это даже очень нужная тема. Спасибо что поднял эту тему... smile


3 Den  
0
Хочу сделать часы, но не получается вывести на экран переменную с типом int, что посоветуете, как с этим бороться?

4 Den  
0
Ещё хочу исправить большую букву Д, но не как не могу её найти, если знаешь подскажи пожалуйста.

Да ещё забыл выразить благодарность за хорошие статьи! Молодец!


5 Denis  
0
Хелп плиз очень надо!!!

6 Denis  
0
Букву Д нашёл она под индексом 100 в масиве.

7 Павел  
0
Den, есть такая классная функция - sprintf называется.

пишешь
int i = 5678;
char buf[10];

sprintf (buf, "%d", i);

получишь в buf строку "5678". И выводи ее куда хочешь.
Это стандарт языка C. От всяких там LCD никак не зависит.


8 Oleg  
1
Молодец! Круто! Перевел все на STM8L - работает!
Спасибо!

9 SergBagin  
0
Прикольно а подойдет к FDCG12864B-FLYYBW-51XN

10 Автор  
0
Да!

11 liftoman  
0
Доброго времени суток! Отличная статья! Спасибо!
Сломал себе всю голову - не получается вывести большой символ на пол экрана (cs1): Рисует сверху вниз до половины после чего продолжает рисовать с координаты (0,0)

12 Strelok  
0
liftoman, тоже появилась такая проблема, я ее решил дописыванием новых функций. Вот даю функции, которые я дописал в lcd_wg.c, тебе нужна последняя. Первая -- выводит построчно переключаясь между половинками перекодированный в одномерный массив *.bmp, вторая -- выводит сначала левую часть экрана, затем вторую (все тот же одномерный массив *.bmp), в параметрах передается размер массива, его имя, стартовая позиция и номер экрана, а вот последняя выводит массив по пол экрана, но массив двумерный, тоесть, если изображение или твой большой символ записан построчно в двумерный массив charcode[x][y], пользуйся...
Code

// вывод одномерного массива на два параллельных экрана
void display_line_bitmap(unsigned int count, flash unsigned char temp[count])
{
unsigned char cs;
unsigned char k=0;
unsigned int symb=0;

unsigned char row=0;

display_xy( 0,0,cs1 );
cs=cs1;

for(symb=0;symb<count;symb++)
{
if ((k>=0)&(k<64))
{
write_data_display( dat,temp[symb],cs1 );
};
if ((k>=64)&(k<128))
{
write_data_display( dat,temp[symb],cs2 );
};

k++;

if (k==128) {row++;display_xy( 0,row,cs1 );k=0;};
if (k==64) {display_xy( 0,row,cs2 );};

};// for symb

}

// вывод одномерного массива на два последовательных экрана
void display_2scr_bitmap(unsigned int count, flash unsigned char temp[count], unsigned char xpos, unsigned char ypos, unsigned char cs)
{
unsigned char k=0;
unsigned int symb=0;

unsigned char row=0;

//display_xy( 0,0,cs1 );

display_xy( xpos+1, ypos, cs );
row=ypos;
for(symb=0;symb<count;symb++)
{
// if (symb==256){display_xy( 0,4,cs1 );row=0;};
if (symb==512){display_xy( 0,0,cs2 );cs=cs2;};
//if (symb==768){display_xy( 0,4, cs2 );};

if (k<63)
{
write_data_display( dat,temp[symb],cs );
k++;
}
else
{
row++;
k=0;
display_xy( 0,row,cs );
write_data_display( dat,temp[symb],cs );
};
};// for symb
}

// вывод двухмерного массива символов поэкранно
void display_char_bitmap(unsigned char count)
{
unsigned char cs;
unsigned char k=0;
unsigned char symb=0;

display_xy( 0,0,cs1 );
cs=cs1;

for(symb=0;symb<count;symb++)
{
if (symb==32){display_xy( 0,4,cs1 );};
if (symb==64){display_xy( 0,0,cs2 );cs=cs2;};
if (symb==96){display_xy( 0,4, cs2 );};

for(k=0;k<8;k++)
{
write_data_display( dat,charcode[symb][k],cs );
};
};// for symb

}

1-10 11-12
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]