Хотел бы представить Вашему вниманию свою собственную библиотеку для работы с широко распространёнными символьными дисплеями на базе контроллера HD44780.
Рис.1 Внешний вид дисплея на базе контроллера HD44780 ( 2 строки Х 16 символов).
Библиотека написана на С#, в Atmel Studio 6.2. Библиотека состоит из 2-х файлов: HD44780_Config.h и HD44780.c. Первый файл является заголовочным, он, собственно, и подключается в Ваш разрабатываемый проект директивой #include «HD44780_Config.h». Также, в этом файле мы прописываем все необходимые нам начальные настройки. Вот, собственно, исходный код этого заголовочно — настроечного файла:
#ifndef HD44780_Config
#define HD44780_Config
#define uchar unsigned char
#define Sbit(reg,bit) (reg|=(1< #define Cbit(reg,bit) (reg&=~(1< #define CheckBit(reg,bit) (reg&(1< #define FirstStr_StartPosition_DDRAM_Addr 0x80
#define SecondStr_StartPosition_DDRAM_Addr 0xC0
/*
*указываем разрядность шины данных дисплея (1-8 бит, 0-4 бита)
*/
#define Data_Length 0
/*
*указываем количество строк дисплея (1-2 строки, 0-1 строка)
*/
#define NumberOfLines 1
/*
*указываем размер шрифта дисплея (1–шрифт 5×10 точек, 0–шрифт 5×7 точек)
*/
#define Font 1
/*
*указываем порт МК, к которому подключена линия E
*указываем номер бита порта МК, к которому подключена линия E
*/
#define PORT_Strob_Signal_E PORTC
#define PIN_Strob_Signal_E 1
/*
*указываем порт МК, к которому подключена линия RS
*указываем номер бита порта МК, к которому подключена линия RS
*/
#define PORT_Strob_Signal_RS PORTC
#define PIN_Strob_Signal_RS 0
/*
*порты ввода-вывода шины данных дисплея D4-D7
*номер бита порта ввода-вывода шины данных дисплея D4-D7
*/
#if Data_Length==0 //4-х проводная шина данных
#define PORT_bus_4 PORTD
#define PIN_bus_4 4
#define PORT_bus_5 PORTD
#define PIN_bus_5 5
#define PORT_bus_6 PORTD
#define PIN_bus_6 6
#define PORT_bus_7 PORTD
#define PIN_bus_7 7
/*
*указываем порты ввода-вывода шины данных дисплея D0-D7
*указываем номер бита порта ввода-вывода шины данных дисплея D0-D7
*/
#elif Data_Length==1 //8-ми проводная шина данных
#define PORT_bus_0 PORTD
#define PIN_bus_0 0
#define PORT_bus_1 PORTD
#define PIN_bus_1 1
#define PORT_bus_2 PORTD
#define PIN_bus_2 2
#define PORT_bus_3 PORTD
#define PIN_bus_3 3
#define PORT_bus_4 PORTD
#define PIN_bus_4 4
#define PORT_bus_5 PORTD
#define PIN_bus_5 5
#define PORT_bus_6 PORTD
#define PIN_bus_6 6
#define PORT_bus_7 PORTD
#define PIN_bus_7 7
#endif
/*
*функция инициализации дисплея. Должна вызываться первой.
*/
void LCD_Init(void);
/*
*функция команды полной очистки DDRAM-памяти дисплея и установка курсора в
*нулевую позицию
*/
void LCD_Full_Clean(void);
/*
*функция команды установки курсора и положения дисплея в нулевую позицию
*/
void LCD_CursorPosition_ToStart(void);
/*
*функция команды направления сдвига курсора после записи и разрешения сдви-
*га дисплея вместе с курсором:
*I_D(Increment/Decrement)-направление сдвига курсора после записи (I_D=1-сдвиг вправо, I_D=0–сдвиг влево);
*S(Shift)–разрешение сдвига дисплея вместе с курсором (S=1-сдвиг разрешен, S=0-сдвиг запрещен);
*/
void LCD_AutoMovCurDispDirect(uchar I_D, uchar S);
/*
*функция команды включения-выключения дисплея, включение-выключение курсора
*и его мигания:
*D(Display)–включение дисплея (D=1-дисплей включен, D=0-дисплей отключен)
*C(Cursor)-видимость курсора (C=1–видимый курсор, C=0–погашенный курсор);
*B(Blink)-мигание курсора (B=1–курсор мигает, B=0–курсор не мигает);
*/
void LCD_DisplEnable_CursOnOffBlink(uchar D, uchar C, uchar B);
/*
*функция команды перемешения дисплея/курсора, направления перемешения:
*S_C(Screen/Cursor)–перемещение дисплея/курсора (S_C=1–перемещается дисплей, S_C=0–перемещается курсор)
*R_L(Right/Left)-направление перемещения дисплея/курсора (R_L=1–перемещение вправо, R_L=0–перемещение влево).
*/
void LCD_MovingCurDispDirection(uchar S_C, uchar R_L);
/*
*функция вывода символов на дисплей. Параметры:
*Addr-код символа (адрес в памяти знакогенератора)
*Str-номер строки, в которой нужно вывести символ
*Cursor-позиция символа в строке
*/
void LCD_Show(uchar Addr, uchar Str, uchar Cursor);
/*
*функция записи пользовательских символов в память знакогенератора CGRAM
*дисплея. Диапазон адресов параметра Addr: 0х00-0x07 (8 пользовательских симво-
*лов). 1 символ занимает 8 байт данных
*/
void LCD_UserSymbolsWrite(uchar Addr, uchar *data);
/*
*функция управляющих сигналов RS, E и шины данных. Вызывается для передачи дан-
*ных дисплею. В качестве параметра RS передаётся 0 или 1. Если 0-команда, 1-данные.
*/
void BusLinesState(uchar *data, uchar RS);
#endif
Здесь, в общем и целом, каждая функция и каждый заданный макрос описаны между знаками комментария /* */. Большее внимание хотелось бы уделить макросам, определяющим инициализационные настройки:
#define Data_Length 0
Данный макрос определяет, по какой схеме Вы хотите подключить свой дисплей к микроконтроллеру — 4-х проводная (Data_Length 0) или 8-ми проводная (Data_Length 1).
Рис.2 Схемы подключения дисплея к МК
а) 8-ми проводная б) 4-х проводная
Если вы выбираете 4-х проводную схему, то побитно записываете порты МК, к которым подключены линии дисплея, в этот макрос:
#if Data_Length==0 //4-х проводная шина данных
#define PORT_bus_4 PORTD
#define PIN_bus_4 4
#define PORT_bus_5 PORTD
#define PIN_bus_5 5
#define PORT_bus_6 PORTD
#define PIN_bus_6 6
#define PORT_bus_7 PORTD
#define PIN_bus_7 7
К примеру, где PORT_bus_4 — это имя порта МК, к которому подключена линия дисплея DB4. Аналогично и с записью бита порта: PIN_bus — номер бита порта, к которому подключена линия дисплея DB4.
Если вы выбираете 8-ми проводную схему, то побитно записываете порты МК, к которым подключены линии дисплея, в этот макрос:
#elif Data_Length==1 //8-ми проводная шина данных
#define PORT_bus_0 PORTD
#define PIN_bus_0 0
#define PORT_bus_1 PORTD
#define PIN_bus_1 1
#define PORT_bus_2 PORTD
#define PIN_bus_2 2
#define PORT_bus_3 PORTD
#define PIN_bus_3 3
#define PORT_bus_4 PORTD
#define PIN_bus_4 4
#define PORT_bus_5 PORTD
#define PIN_bus_5 5
#define PORT_bus_6 PORTD
#define PIN_bus_6 6
#define PORT_bus_7 PORTD
#define PIN_bus_7 7
#endif
Здесь все так же, лишь проводов больше. Зачем же такие сложности, спросите вы? Ответ прост-благодаря этому, Вы можете подключать линии дисплея абсолютно в разброс по всем портам МК, к которым захотите и ножки которых будут свободны. Просто зачастую получается так, что при проектировании какого-либо устройства не удаётся сохранить абсолютно свободным целый порт. Я часто сталкивался с этой проблемой, и решил её таким вот образом. Здесь Вы не привязаны к конкретным ножкам МК, какие цифры напишете и названия портов в вышеприведённых макросах настройки, по таким линиям микроконтроллера и будет работать ваш дисплей.
Остальные макросы и функции, я думаю, не вызовут затруднений в использовании, поскольку их описание приводится непосредственно в исходном коде заголовочного файла. Единственная функция, которой я хотел бы уделить дополнительное внимание-функция записи в память CGRAM пользовательских символов, которых нет в таблице ASCI:
LCD_UserSymbolsWrite(uchar Addr, uchar *data);
Данная функция позволяет нам записать в энергозависимую память знакогенератора 8 собственных символов, которые Вы сами и придумаете. Для большей ясности, дабы мне не повторять автора, можете почитать интересную статью: /me/mc/book52.php. Там расписана вся работа дисплея на аппаратном уровне. Моя статья и библиотека призваны упростить применение дисплея=)
Так, я немножко отвлёкся от темы….. Запись в дисплей пользовательских символов!!! — Для упрощения этой задачи, в дополнение к библиотеке, я написал простую программу:
Рис.3 Внешний вид программы для рисования пользовательских символов
Синие квадратики соответствуют не активированным пикселям сегмента дисплея. Кликом мыши можно переключать эти пиксели между видимым состоянием и не видимым. Программа рассчитывает значения байтов данных и автоматически создаёт готовый массив одного символа Symbol[8], состоящего из восьми байт. После того, как вы закончили рисование своего символа, копируете весь массив в Ваш проект и запихиваете его в память дисплея функцией LCD_UserSymbolsWrite вот так:
LCD_UserSymbolsWrite(i,&Symbol[0]);
где i — адрес памяти CGRAM, предназначенный для пользовательских символов. Диапазон адресов: 0х00-0х07;
&Symbol[0] — указатель на нулевой (начало) элемент массива с данными для сегмента.
К статье приложен пример использования, там можно будет конкретно посмотреть тело программы + имеется проект в Протеусе.
Рис.4 Внешний вид программы для рисования пользовательских символов с готовым результатом
Рис.5 и 6 Иллюстрация работы
В общем и целом, вроде бы всё. Если что-то будет непонятно, почитать можно тут: /me/mc/book52.php.
Если даже после этого останутся вопросы — задавайте в комментариях. Спасибо за внимание!
Прикрепленные файлы:
- HD44780.rar (431 Кб)