Хотел бы представить Вашему вниманию свою собственную библиотеку для работы с широко распространёнными символьными дисплеями на базе контроллера HD44780.
Рис.1 Внешний вид дисплея на базе контроллера HD44780 ( 2 строки Х 16 символов).
Библиотека написана на С#, в Atmel Studio 6.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–шрифт 5x10 точек, 0–шрифт 5x7 точек) */ #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 собственных символов, которые Вы сами и придумаете. Для большей ясности, дабы мне не повторять автора, можете почитать интересную статью: //cxem.net/mc/book52.php. Там расписана вся работа дисплея на аппаратном уровне. Моя статья и библиотека призваны упростить применение дисплея=)
Так, я немножко отвлёкся от темы..... Запись в дисплей пользовательских символов!!! - Для упрощения этой задачи, в дополнение к библиотеке, я написал простую программу:
Рис.3 Внешний вид программы для рисования пользовательских символов
Синие квадратики соответствуют не активированным пикселям сегмента дисплея. Кликом мыши можно переключать эти пиксели между видимым состоянием и не видимым. Программа рассчитывает значения байтов данных и автоматически создаёт готовый массив одного символа Symbol[8], состоящего из восьми байт. После того, как вы закончили рисование своего символа, копируете весь массив в Ваш проект и запихиваете его в память дисплея функцией LCD_UserSymbolsWrite вот так:
LCD_UserSymbolsWrite(i,&Symbol[0]);
где i - адрес памяти CGRAM, предназначенный для пользовательских символов. Диапазон адресов: 0х00-0х07;
&Symbol[0] - указатель на нулевой (начало) элемент массива с данными для сегмента.
К статье приложен пример использования, там можно будет конкретно посмотреть тело программы + имеется проект в Протеусе.
Рис.4 Внешний вид программы для рисования пользовательских символов с готовым результатом
Рис.5 и 6 Иллюстрация работы
В общем и целом, вроде бы всё. Если что-то будет непонятно, почитать можно тут: //cxem.net/mc/book52.php.
Если даже после этого останутся вопросы - задавайте в комментариях. Спасибо за внимание!
Прикрепленные файлы:
- HD44780.rar (431 Кб)
Комментарии (19) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация
[Автор]
[Автор]
[Автор]
[Автор]
[Автор]
void main(){
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,txt4);
}
[Автор]
#define Data_Length 0
*указываем количество строк дисплея (1-2 строки, 0-1 строка)
#define NumberOfLines 1
#define Data_Length 8
*указываем количество строк дисплея (1 или 2 строки)
#define NumberOfLines 1
[Автор]
[Автор]
int8_t humidity = 0;
humidity = dht11_gethumidity();
Как теперь мне вывести переменную humidity на экран?
[Автор]